Using RMT to sample Continuous PWM Duty Cycle

andrewressa
Posts: 1
Joined: Thu Apr 28, 2022 8:24 pm

Using RMT to sample Continuous PWM Duty Cycle

Postby andrewressa » Thu Apr 28, 2022 8:45 pm

Hey folks -

I've been trying to use the RMT peripheral to measure the duty cycle of a continuous PWM square wave. The signal is 2kHz with Duty Cycles between 10% and 90%. Trying to be as specific as possible, the signal is continuous with no breaks between any "symbols".

I've successfully set up an RX Channel:

Code: Select all

Initialize(uint8_t rmt_channel, uint8_t gpio)
{
    esp_err_t res;

    RMT_Channel = (rmt_channel_t)rmt_channel;
    RMT_GPIO = (gpio_num_t)gpio;

    rmt_config_t rmt_rx_config = RMT_DEFAULT_CONFIG_RX( RMT_GPIO, RMT_Channel );

    res = rmt_config(&rmt_rx_config);
    res = rmt_driver_install(RMT_Channel, 0, 0);

    rmt_get_counter_clock(RMT_Channel, &rmt_clock_hz_);

    res = rmt_rx_start(RMT_Channel, true);   

}
This works fine, and is successful, but when I run the code I get a continuous stream of:

Code: Select all

E (3369290) rmt: ---RX buffer too small: 4
E (3369300) rmt: ---RX buffer too small: 4
E (3369310) rmt: ---RX buffer too small: 4
E (3369320) rmt: ---RX buffer too small: 4
E (3369340) rmt: ---RX buffer too small: 4
E (3369350) rmt: ---RX buffer too small: 4
E (3369360) rmt: ---RX buffer too small: 4
I can successfully sample by peeking at the memory directly:

Code: Select all

Read(void)
{
    esp_err_t res;
    volatile rmt_item32_t* item;

    item = RMTMEM.chan[RMT_Channel].data32;

    std::cout << "item d0: " << item->duration0 << " l0: " << item->level0  << " d1: " << item->duration1  << " l1: " << item->level1  << std::endl;

}
However, I still get the "RX buffer too small" errors continuously.

Regarding the Ring Buffer - it does not really make sense to keep many many readings, I just need one "symbol" (or a small handful at a maximum) to measure the duty cycle, and it does not seem to make much sense to worry about the buffer (especially since the RMTMEM direct read is just as good. If you notice, I actually have the Ring Buffer disabled in the line

Code: Select all

res = rmt_driver_install(RMT_Channel, 0, 0);
Regarding an Interrupt, it does not make sense to fire off an interrupt ~2k times a second, every time I get a single period of my wave into the device.


Could anyone suggest any options for sampling the duty cycle of this signal? I only expect to measure the duty cycle of the PWM signal every 20ms or so at most (which is how I have the above code set up - the Read() function gets called by another task).

Thanks in advance.

Who is online

Users browsing this forum: Bing [Bot] and 121 guests