-
Notifications
You must be signed in to change notification settings - Fork 7.7k
How to make RMT RX done with count of signals? #11769
-
Board
ESP32 C3
Device Description
ESP32 C3
Hardware Configuration
default
Version
v3.0.3
Type
Question
IDE Name
Arduino IDE
Operating System
Windows10
Flash frequency
80MHz
PSRAM enabled
no
Upload speed
921600
Description
I use two types of RMT RX setup. One is for legacy driver, the other is new driver.
In legacy driver, I used ringbuffer to collect RMT RX data. The handling data part is
rmt_item32_t* items = (rmt_item32_t*)xRingbufferReceive(signal_rb, &size, 0);
if (items)
process data
In new driver, I used interrupt and task notify to enter handling part.
uint32_t got = ulTaskNotifyTake(pdTRUE, pdMS_TO_TICKS(1));
if (got > 0)
process data
The signals that I'd like to collect has a pattern like
15μs 30μs 45μs 22.5μs 15μs 15μs 22.5μs ... 22.5μs 200μs(end).
However, in the two drivers, I can only process data whenever a long end occur or when a block is full. But I need to process first 8 signals as soon as possible so it should process data whenever 8 signals are received. How to achieve this goal? (No matter in legacy driver or new driver is well.)
Sketch
// The legacy driver setup rmt_config_t config = {}; config.rmt_mode = RMT_MODE_RX; config.channel = RMT_CHANNEL_4; config.gpio_num = (gpio_num_t)m_input_pin; config.clk_div = 8; // 0.1 μs per tick config.mem_block_num = 2; config.rx_config.filter_en = false; // filter noise config.rx_config.idle_threshold = 350; // div 8, 35 micro rmt_config(&config); rmt_driver_install(config.channel, 32768, 0); // the smallest number is 256 but also too large // New driver setup rmt_channel_handle_t rx_chan = nullptr; rmt_symbol_word_t rx_buf[8] = {0}; static TaskHandle_t s_consumer_task = nullptr; s_consumer_task = xTaskGetCurrentTaskHandle(); rmt_rx_channel_config_t cfg = {}; cfg.gpio_num = (gpio_num_t)m_input_pin; cfg.clk_src = RMT_CLK_SRC_DEFAULT; cfg.resolution_hz = 10000000; // 100 ns tick cfg.mem_block_symbols = 64; // or 48 but still fail cfg.flags.invert_in = false; cfg.flags.with_dma = false; cfg.intr_priority = 0; ESP_ERROR_CHECK(rmt_new_rx_channel(&cfg, &rx_chan)); rmt_rx_event_callbacks_t cbs = {}; cbs.on_recv_done = on_rmt_rx_done; // callback ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rx_chan, &cbs, nullptr)); ESP_ERROR_CHECK(rmt_enable(rx_chan)); ESP_ERROR_CHECK(rmt_receive(rx_chan, rx_buf, sizeof(rx_buf), &rcfg)); // Callback function of new driver static bool IRAM_ATTR on_rmt_rx_done(rmt_channel_handle_t, const rmt_rx_done_event_data_t* edata, void* user) { // signal task; do NOT process here s_last_count = edata->num_symbols; BaseType_t hpw = pdFALSE; // xSemaphoreGiveFromISR(s_consumer_task, &hpw); vTaskNotifyGiveFromISR(s_consumer_task, &hpw); return hpw == pdTRUE; }
Debug Message
any
Other Steps to Reproduce
No response
I have checked existing issues, online documentation and the Troubleshooting Guide
- I confirm I have checked existing issues, online documentation and Troubleshooting guide.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 1 comment
-
@DavidHan1998 - This seems to be a question about IDF and not about Arduino API.
You may try to check the IDF 5.4.1 (compatible with Arduino Core 3.0.3) examples:
https://github.com/espressif/esp-idf/tree/release/v5.1/examples/peripherals/rmt
It is also possible to ask about it directly in the ESP-IDF issue area:
https://github.com/espressif/esp-idf/issues
Another option would be to try to implement it using the Arduino Core API created to deal with RMT.
Please check these examples:
https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/RMT
The API implementation can be found in:
Core 3.0.3 esp32-hal-rmt.h
Core 3.0.3 esp32-hal-rmt.c
I'll move this issue to discussions because it is not related to ESP32 Arduino Core code.
Beta Was this translation helpful? Give feedback.