Skip to content

How to make RMT RX done with count of signals? #11767

@DavidHan1998

Description

@DavidHan1998

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.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions