Sending this using RMT is straightforward and works very well.
Receiving though seems to be more complicated. Note that I do my decoding decoupled from the rx callback
and have the callback marked w/ IRAM_ATTR.
Here's portions from my code so you can see how I'm initializing RMT:
Code: Select all
void init() {
// Configure RMT RX channel
rmt_rx_channel_config_t rx_channel_config = {
.gpio_num = gpio_num_,
.clk_src = RMT_CLK_SRC_DEFAULT,
.resolution_hz = 1'000'000, // 1 MHz, 1 tick = 1 µs
.mem_block_symbols = MemBlockBuffer,
};
ESP_ERROR_CHECK(rmt_new_rx_channel(&rx_channel_config, &rmt_channel_));
// Install RX done callback
rmt_rx_event_callbacks_t cbs = {
.on_recv_done = rxDoneCallback,
};
ESP_ERROR_CHECK(rmt_rx_register_event_callbacks(rmt_channel_, &cbs, this));
// Enable RMT RX channel
ESP_ERROR_CHECK(rmt_enable(rmt_channel_));
startReceive();
}
void startReceive() {
// Allocate buffer for received symbols
static rmt_symbol_word_t symbols[MemBlockBuffer]; // Maximum supported by hardware
// Configure RX parameters - adjust for our tick period
auto config = rmt_receive_config_t {
.signal_range_min_ns = 1 * 1000, // 1µs resolution
.signal_range_max_ns = 100 * 1000, // Max sync high pulse
};
ESP_ERROR_CHECK(rmt_receive(rmt_channel_, symbols, sizeof(symbols), &config));
}
Here's the log output trying to receive 5 frames:
Code: Select all
D (4692) rmt: new group(0) at 0x3fcb15a4, occupy=ffffff00
D (4694) intr_alloc: Connected src 40 to int 12 (cpu 0)
D (4694) rmt: group (0) clock resolution:80000000Hz
D (4694) rmt: new rx channel(0,0) at 0x3fcb14c0, gpio=1, res=1000000Hz, hw_mem_base=0x60016b00, ping_pong_size=72
Waiting for 5 SENT frames on GPIO 1 (tick period 3 µs)...
D (4696) TASK: SENTReceiver created.
D (4697) TASK: SENTReceiver resumed.
D (4697) TASK: SENTReceiver entering code.
D (4697) SENTReceiver: SENTReceiver task started
D (4698) SENTReceiver: [RAW] LOW 14 us -> HIGH 21 us
D (4698) SENTReceiver: [STAT] 0x0
D (4699) SENTReceiver: [RAW] LOW 15 us -> HIGH 24 us
D (4699) SENTReceiver: [DATA] 0x1
D (4699) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4700) SENTReceiver: [DATA] 0x2
D (4700) SENTReceiver: [RAW] LOW 15 us -> HIGH 30 us
D (4700) SENTReceiver: [DATA] 0x3
D (4701) SENTReceiver: [RAW] LOW 15 us -> HIGH 33 us
D (4701) SENTReceiver: [DATA] 0x4
D (4701) SENTReceiver: [RAW] LOW 15 us -> HIGH 36 us
D (4702) SENTReceiver: [DATA] 0x5
D (4702) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4703) SENTReceiver: [DATA] 0x6
D (4703) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4703) SENTReceiver: [CRC ] 0x2 (valid)
D (4704) SENTReceiver: [FRAME] Status:0x0 Data:[0x1,0x2,0x3,0x4,0x5,0x6] CRC:0x2 (valid)
Frame 1/5 received: [0x0] 0x1 0x2 0x3 0x4 0x5 0x6 [0x2 (valid)
D (4705) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
D (4705) SENTReceiver: Incomplete frame (0/8 nibbles) terminated by zero-duration pulse
D (4707) SENTReceiver: [RAW] LOW 14 us -> HIGH 21 us
D (4707) SENTReceiver: [STAT] 0x0
D (4708) SENTReceiver: [RAW] LOW 15 us -> HIGH 24 us
D (4708) SENTReceiver: [DATA] 0x1
D (4709) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4709) SENTReceiver: [DATA] 0x2
D (4709) SENTReceiver: [RAW] LOW 15 us -> HIGH 30 us
D (4710) SENTReceiver: [DATA] 0x3
D (4710) SENTReceiver: [RAW] LOW 15 us -> HIGH 33 us
D (4711) SENTReceiver: [DATA] 0x4
D (4711) SENTReceiver: [RAW] LOW 15 us -> HIGH 36 us
D (4712) SENTReceiver: [DATA] 0x5
D (4712) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4713) SENTReceiver: [DATA] 0x6
D (4713) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4713) SENTReceiver: [CRC ] 0x2 (valid)
D (4714) SENTReceiver: [FRAME] Status:0x0 Data:[0x1,0x2,0x3,0x4,0x5,0x6] CRC:0x2 (valid)
Frame 2/5 received: [0x0] 0x1 0x2 0x3 0x4 0x5 0x6 [0x2 (valid)
D (4715) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
D (4716) SENTReceiver: Incomplete frame (0/8 nibbles) terminated by zero-duration pulse
D (4717) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4717) SENTReceiver: [STAT] 0x6
D (4718) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4718) SENTReceiver: [DATA] 0x2
D (4719) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
D (4719) SENTReceiver: Incomplete frame (2/8 nibbles) terminated by zero-duration pulse
D (4720) SENTReceiver: [RAW] LOW 15 us -> HIGH 21 us
D (4721) SENTReceiver: [STAT] 0x0
D (4721) SENTReceiver: [RAW] LOW 14 us -> HIGH 25 us
D (4722) SENTReceiver: [DATA] 0x1
D (4722) SENTReceiver: [RAW] LOW 14 us -> HIGH 27 us
D (4723) SENTReceiver: [DATA] 0x2
D (4723) SENTReceiver: [RAW] LOW 15 us -> HIGH 30 us
D (4724) SENTReceiver: [DATA] 0x3
D (4724) SENTReceiver: [RAW] LOW 15 us -> HIGH 33 us
D (4724) SENTReceiver: [DATA] 0x4
D (4725) SENTReceiver: [RAW] LOW 15 us -> HIGH 36 us
D (4725) SENTReceiver: [DATA] 0x5
D (4726) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4726) SENTReceiver: [DATA] 0x6
D (4727) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4727) SENTReceiver: [CRC ] 0x2 (valid)
D (4728) SENTReceiver: [FRAME] Status:0x0 Data:[0x1,0x2,0x3,0x4,0x5,0x6] CRC:0x2 (valid)
Frame 3/5 received: [0x0] 0x1 0x2 0x3 0x4 0x5 0x6 [0x2 (valid)
D (4729) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
D (4729) SENTReceiver: Incomplete frame (0/8 nibbles) terminated by zero-duration pulse
D (4730) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4731) SENTReceiver: [STAT] 0x6
D (4731) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4732) SENTReceiver: [DATA] 0x2
D (4732) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
D (4733) SENTReceiver: Incomplete frame (2/8 nibbles) terminated by zero-duration pulse
D (4734) SENTReceiver: [RAW] LOW 14 us -> HIGH 21 us
D (4735) SENTReceiver: [STAT] 0x0
D (4735) SENTReceiver: [RAW] LOW 15 us -> HIGH 24 us
D (4735) SENTReceiver: [DATA] 0x1
D (4736) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4736) SENTReceiver: [DATA] 0x2
D (4737) SENTReceiver: [RAW] LOW 15 us -> HIGH 30 us
D (4737) SENTReceiver: [DATA] 0x3
D (4738) SENTReceiver: [RAW] LOW 15 us -> HIGH 33 us
D (4738) SENTReceiver: [DATA] 0x4
D (4738) SENTReceiver: [RAW] LOW 15 us -> HIGH 36 us
D (4739) SENTReceiver: [DATA] 0x5
D (4739) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4740) SENTReceiver: [DATA] 0x6
D (4740) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4741) SENTReceiver: [CRC ] 0x2 (valid)
D (4741) SENTReceiver: [FRAME] Status:0x0 Data:[0x1,0x2,0x3,0x4,0x5,0x6] CRC:0x2 (valid)
Frame 4/5 received: [0x0] 0x1 0x2 0x3 0x4 0x5 0x6 [0x2 (valid)
D (4742) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
D (4743) SENTReceiver: Incomplete frame (0/8 nibbles) terminated by zero-duration pulse
D (4745) SENTReceiver: [RAW] LOW 14 us -> HIGH 21 us
D (4745) SENTReceiver: [STAT] 0x0
D (4745) SENTReceiver: [RAW] LOW 15 us -> HIGH 24 us
D (4746) SENTReceiver: [DATA] 0x1
D (4746) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4747) SENTReceiver: [DATA] 0x2
D (4747) SENTReceiver: [RAW] LOW 15 us -> HIGH 30 us
D (4748) SENTReceiver: [DATA] 0x3
D (4748) SENTReceiver: [RAW] LOW 15 us -> HIGH 33 us
D (4749) SENTReceiver: [DATA] 0x4
D (4749) SENTReceiver: [RAW] LOW 15 us -> HIGH 36 us
D (4749) SENTReceiver: [DATA] 0x5
D (4750) SENTReceiver: [RAW] LOW 15 us -> HIGH 39 us
D (4750) SENTReceiver: [DATA] 0x6
D (4751) SENTReceiver: [RAW] LOW 15 us -> HIGH 27 us
D (4751) SENTReceiver: [CRC ] 0x2 (valid)
D (4752) SENTReceiver: [FRAME] Status:0x0 Data:[0x1,0x2,0x3,0x4,0x5,0x6] CRC:0x2 (valid)
Frame 5/5 received: [0x0] 0x1 0x2 0x3 0x4 0x5 0x6 [0x2 (valid)
D (4753) SENTReceiver: [RAW] LOW 15 us -> HIGH 0 us
Received 5 frames, dropped 0 symbols, 6 short frames
D (4754) TASK: SENTReceiver will cancel...
D (4754) SENTReceiver: Incomplete frame (0/8 nibbles) terminated by zero-duration pulse
D (4755) SENTReceiver: SENTReceiver task stopped
D (4755) TASK: SENTReceiver exited code regularly (cancel).
D (4756) TASK: SENTReceiver cancelled.
D (4756) rmt: del rx channel(0,0)
D (4757) rmt: del group(0)
D (4757) TASK: SENTReceiver ~Task
ESP32>
Code: Select all
auto config = rmt_receive_config_t {
.signal_range_min_ns = 1 * 1000, // 1µs resolution
.signal_range_max_ns = 175 * 1000, // Max sync high pulse
};
Code: Select all
E rmt: user buffer too small, received symbols truncated
What is happening here? Why is the signal_range_max_ns not allowing 175 and why am I getting 0 lengths (followed by symbols where the polarity is switched, e.g. level0 is HIGH and level1 is LOW whereas they're typically vice versa).