Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RMT: RMTLoopback example hangs and gives core error #11200

Closed
1 task done
fanfanlatulipe26 opened this issue Mar 28, 2025 · 19 comments · Fixed by #11203
Closed
1 task done

RMT: RMTLoopback example hangs and gives core error #11200

fanfanlatulipe26 opened this issue Mar 28, 2025 · 19 comments · Fixed by #11203
Assignees
Labels
Status: In Progress ⚠️ Issue is in progress
Milestone

Comments

@fanfanlatulipe26
Copy link

Board

ESP32 Dev Kit v1

Device Description

ESP32 Dev Kit v1

Hardware Configuration

Jumper between pin 18 and 21

Version

v3.1.2

IDE Name

Arduino IDE 1.8.19

Operating System

Windows 10

Flash frequency

80Mhz

PSRAM enabled

no

Upload speed

921600

Description

In fact I use the very last version of ESP32: 3.2.0 (release not yet available in the dropdown list here above)

The standard RMTLoopback example fails with an error and hangs
E (1190) rmt: rmt_receive(386): partial receive not supported
If the example is compiled with debug level None we just get:
real tick set to: 100ns Please connect GPIO 18 to GPIO 21, now. E (11) rmt: rmt_receive(386): partial receive not supported
If we compile with debug level Error, we get more output from the testcase as can be seen in the "Debug Message" section

As can be seen in the output of the test, the results are not exactly the one expexted, but not really garbage. Some shift ??

More: the frequency used in the example is 10 000 000
#define RMT_FREQ 10000000 // tick time is 100ns
In fact the generated waveform shows that it is not 100ns, and the wave form is not exactly the one given by the data array.
I found little documentation and the tick time is not at all always as described in the comment in esp32-hal-rmt.h for rmtInit

New Parameters in Arduino Core 3: RMT tick is set in the rmtInit() function by the frequency of the RMT channel. Example: 100ns tick => 10MHz, thus frequency will be 10,000,000 Hz
Seems OK for 1Mhz, 2Mhz,8Mhz, but bad for 5Mhz, 10Mhz.

Sketch

The example given in for ESP32 RMT: RMTLoopback
No change.

Debug Message

ets Jun  8 2016 00:22:57

rst:0x1 (POWERON_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:4888
load:0x40078000,len:16516
load:0x40080400,len:4
load:0x40080404,len:3476
entry 0x400805b4
[     1][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x400d489c
[    12][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x400d4880
[    26][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x400d4864
[    39][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x400d4848
[    53][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x400d489c
[    66][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x400d4880
[    80][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x400d4864
[    93][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x400d4848
[   107][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RX (2) successfully set to 0x400d489c
[   120][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_TX (3) successfully set to 0x400d4880
[   133][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_CTS (4) successfully set to 0x400d4864
[   147][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type UART_RTS (5) successfully set to 0x400d4848
[   177][D][esp32-hal-cpu.c:263] setCpuFrequencyMhz(): PLL: 480 / 2 = 240 Mhz, APB: 80000000 Hz
[   193][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 3 successfully set to type UART_RX (2) with bus 0x3ffbdb60
[   204][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 1 successfully set to type UART_TX (3) with bus 0x3ffbdb60
=========== Before Setup Start ===========
Chip Info:
------------------------------------------
  Model             : ESP32
  Package           : D0WD-Q6
  Revision          : 1.00
  Cores             : 2
  CPU Frequency     : 240 MHz
  XTAL Frequency    : 40 MHz
  Features Bitfield : 0x00000032
  Embedded Flash    : No
  Embedded PSRAM    : No
  2.4GHz WiFi       : Yes
  Classic BT        : Yes
  BT Low Energy     : Yes
  IEEE 802.15.4     : No
------------------------------------------
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   372984 B ( 364.2 KB)
  Free Bytes        :   332084 B ( 324.3 KB)
  Allocated Bytes   :    33748 B (  33.0 KB)
  Minimum Free Bytes:   326388 B ( 318.7 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
Flash Info:
------------------------------------------
  Chip Size         :  4194304 B (4 MB)
  Block Size        :    65536 B (  64.0 KB)
  Sector Size       :     4096 B (   4.0 KB)
  Page Size         :      256 B (   0.2 KB)
  Bus Speed         : 80 MHz
  Bus Mode          : QIO
------------------------------------------
Partitions Info:
------------------------------------------
                nvs : addr: 0x00009000, size:    20.0 KB, type: DATA, subtype: NVS
            otadata : addr: 0x0000E000, size:     8.0 KB, type: DATA, subtype: OTA
               app0 : addr: 0x00010000, size:  1280.0 KB, type:  APP, subtype: OTA_0
               app1 : addr: 0x00150000, size:  1280.0 KB, type:  APP, subtype: OTA_1
             spiffs : addr: 0x00290000, size:  1408.0 KB, type: DATA, subtype: SPIFFS
           coredump : addr: 0x003F0000, size:    64.0 KB, type: DATA, subtype: COREDUMP
------------------------------------------
Software Info:
------------------------------------------
  Compile Date/Time : Mar 28 2025 17:01:13
  Compile Host OS   : windows
  ESP-IDF Version   : v5.4.1-1-g2f7dcd862a-dirty
  Arduino Version   : 3.2.0
------------------------------------------
Board Info:
------------------------------------------
  Arduino Board     : ESP32_DEV
  Arduino Variant   : esp32
  Arduino FQBN      : esp32:esp32:esp32:JTAGAdapter=default,PSRAM=disabled,PartitionScheme=default,CPUFreq=240,FlashMode=qio,FlashFreq=80,FlashSize=4M,UploadSpeed=921600,LoopCore=1,EventsCore=1,DebugLevel=verbose,EraseFlash=none,ZigbeeMode=default
============ Before Setup End ============
[   714][V][esp32-hal-uart.c:552] uartBegin(): UART0 baud(115200) Mode(800001c) rxPin(3) txPin(1)
[   723][V][esp32-hal-uart.c:650] uartBegin(): UART0 not installed. Starting installation
[   733][V][esp32-hal-uart.c:660] uartBegin(): UART0 RX FIFO full threshold set to 120 (value requested: 120 || FIFO Max = 128)
[   746][V][esp32-hal-uart.c:681] uartBegin(): Setting UART0 to use REF_TICK clock
[   756][V][esp32-hal-uart.c:732] uartBegin(): UART0 initialization done.
[   771][V][esp32-hal-uart.c:783] uartSetRxFIFOFull(): UART0 RX FIFO Full value set to 120 from a requested value of 120
[   782][V][esp32-hal-rmt.c:454] rmtInit(): GPIO 18 - TX MODE - MemSize[64] - Freq=10000000Hz
[   790][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type RMT_TX (13) successfully set to 0x400d1ef8
[   801][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type RMT_RX (14) successfully set to 0x400d1ef8
[   813][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 18 successfully set to type RMT_TX (13) with bus 0x3ffb8e60
[   824][V][esp32-hal-rmt.c:454] rmtInit(): GPIO 21 - RX MODE - MemSize[192] - Freq=10000000Hz
[   832][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type RMT_TX (13) successfully set to 0x400d1ef8
[   844][V][esp32-hal-periman.c:235] perimanSetBusDeinit(): Deinit function for type RMT_RX (14) successfully set to 0x400d1ef8
[   855][V][esp32-hal-periman.c:160] perimanSetPinBus(): Pin 21 successfully set to type RMT_RX (14) with bus 0x3ffb944c
real tick set to: 100ns

Please connect GPIO 18 to GPIO 21, now.
=========== After Setup Start ============
INTERNAL Memory Info:
------------------------------------------
  Total Size        :   372984 B ( 364.2 KB)
  Free Bytes        :   327464 B ( 319.8 KB)
  Allocated Bytes   :    37680 B (  36.8 KB)
  Minimum Free Bytes:   321620 B ( 314.1 KB)
  Largest Free Block:   110580 B ( 108.0 KB)
------------------------------------------
GPIO Info:
------------------------------------------
  GPIO : BUS_TYPE[bus/unit][chan]
  --------------------------------------  
     1 : UART_TX[0]
     3 : UART_RX[0]
    18 : RMT_TX
    21 : RMT_RX
============ After Setup End =============
[   947][V][esp32-hal-rmt.c:377] _rmtRead(): GPIO: 21 - Request: 30 RMT Symbols - Non-Blocking - Timeout: 0
[   957][V][esp32-hal-rmt.c:305] _rmtWrite(): GPIO: 18 - Request: 30 RMT Symbols - Blocking - Timeout: -1
[   966][V][esp32-hal-rmt.c:306] _rmtWrite(): GPIO: 18 - Currently in Loop Mode: [NO] | Asked to Loop: NO, LoopCancel: NO
Got 30 RMT symbols
000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 000a8004=8004000b 
00098005=8005000a 00088006=80060009 00078007=80070008 00068008=80080007 
00058009=80090006 0004800a=800a0005 0003800b=800b0004 0002800c=800c0003 
000e800d=800d0002 000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 
000a8004=8004000b 00098005=8005000a 00088006=80060009 00078007=80070008 
00068008=80080007 00058009=80090006 0004800a=800a0005 0003800b=800b0004 
0002800c=800c0003 000e800d=800d0002 000d8001=8001000e 000c8002=8002000d 
000b8003=8003000c 00008004=8004000b 00000000=8005000a 00000000=80060009 
00000000=80070008 00000000=80080007 00000000=80090006 00000000=800a0005 
00000000=800b0004 00000000=800c0003 00000000=800d0002 00000000=8001000e 
00000000=8002000d 00000000=8003000c 00000000=8004000b 00000000=8005000a 
00000000=80060009 00000000=80070008 00000000=80080007 00000000=80090006 
00000000=800a0005 00000000=800b0004 00000000=800c0003 00000000=800d0002 
00000000=8001000e 00000000=8002000d 00000000=8003000c 00000000=8004000b 
00000000=8005000a 00000000=80060009 00000000=80070008 00000000=80080007 


[  1570][V][esp32-hal-rmt.c:377] _rmtRead(): GPIO: 21 - Request: 30 RMT Symbols - Non-Blocking - Timeout: 0
E (1403) rmt: rmt_receive(386): partial receive not supported
[  1580][V][esp32-hal-rmt.c:305] _rmtWrite(): GPIO: 18 - Request: 30 RMT Symbols - Blocking - Timeout: -1
[  1594][V][esp32-hal-rmt.c:306] _rmtWrite(): GPIO: 18 - Currently in Loop Mode: [NO] | Asked to Loop: NO, LoopCancel: NO

Other Steps to Reproduce

I tried with other GPIOs. Same results

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
@fanfanlatulipe26 fanfanlatulipe26 added the Status: Awaiting triage Issue is waiting for triage label Mar 28, 2025
@SuGlider SuGlider self-assigned this Mar 30, 2025
@SuGlider SuGlider added the Status: Needs investigation We need to do some research before taking next steps on this issue label Mar 30, 2025
@SuGlider
Copy link
Collaborator

IDF 5.4 has introduced a new flag into Receive Config Struct, causing it to fail when set to 1 when using ESP32.

To make sure that such kind of failure won't happen in any other place, a PR (#11203) to clear all RMT config structs before using them has been posted. This shall fix this issue.

@fanfanlatulipe26 - If possible, please test the PR. Thanks!

@SuGlider SuGlider moved this from Todo to In Progress in Arduino ESP32 Core Project Roadmap Mar 30, 2025
@SuGlider SuGlider added this to the 3.2.0 milestone Mar 30, 2025
@SuGlider SuGlider added Status: In Progress ⚠️ Issue is in progress and removed Status: Awaiting triage Issue is waiting for triage Status: Needs investigation We need to do some research before taking next steps on this issue labels Mar 30, 2025
@SuGlider SuGlider modified the milestones: 3.2.0, 3.2.1 Mar 31, 2025
@fanfanlatulipe26
Copy link
Author

I ran the example with the new esp32-hal-rmt.c.
No more error messages, but I got the same strange results as the ones I posted above.
I would expect send and receive data to be identical.

real tick set to: 100ns

Please connect GPIO 18 to GPIO 21, now.
Got 30 RMT symbols
000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 000a8004=8004000b 
00098005=8005000a 00088006=80060009 00078007=80070008 00068008=80080007 
00058009=80090006 0004800a=800a0005 0003800b=800b0004 0002800c=800c0003 
000e800d=800d0002 000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 
000a8004=8004000b 00098005=8005000a 00088006=80060009 00078007=80070008 
00068008=80080007 00058009=80090006 0004800a=800a0005 0003800b=800b0004 
0002800c=800c0003 000e800d=800d0002 000d8001=8001000e 000c8002=8002000d 
000b8003=8003000c 00008004=8004000b 00000000=8005000a 00000000=80060009 
00000000=80070008 00000000=80080007 00000000=80090006 00000000=800a0005 
00000000=800b0004 00000000=800c0003 00000000=800d0002 00000000=8001000e 
00000000=8002000d 00000000=8003000c 00000000=8004000b 00000000=8005000a 
00000000=80060009 00000000=80070008 00000000=80080007 00000000=80090006 
00000000=800a0005 00000000=800b0004 00000000=800c0003 00000000=800d0002 
00000000=8001000e 00000000=8002000d 00000000=8003000c 00000000=8004000b 
00000000=8005000a 00000000=80060009 00000000=80070008 00000000=80080007 


Got 30 RMT symbols
000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 000a8004=8004000b 
00098005=8005000a 00088006=80060009 00078007=80070008 00068008=80080007 
00058009=80090006 0004800a=800a0005 0003800b=800b0004 0002800c=800c0003 
000e800d=800d0002 000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 
000a8004=8004000b 00098005=8005000a 00088006=80060009 00078007=80070008 
00068008=80080007 00058009=80090006 0004800a=800a0005 0003800b=800b0004 
0002800c=800c0003 000e800d=800d0002 000d8001=8001000e 000c8002=8002000d 
000b8003=8003000c 00008004=8004000b 00000000=8005000a 00000000=80060009 
00000000=80070008 00000000=80080007 00000000=80090006 00000000=800a0005 
00000000=800b0004 00000000=800c0003 00000000=800d0002 00000000=8001000e 
00000000=8002000d 00000000=8003000c 00000000=8004000b 00000000=8005000a 
00000000=80060009 00000000=80070008 00000000=80080007 00000000=80090006 
00000000=800a0005 00000000=800b0004 00000000=800c0003 00000000=800d0002 
00000000=8001000e 00000000=8002000d 00000000=8003000c 00000000=8004000b 
00000000=8005000a 00000000=80060009 00000000=80070008 00000000=80080007 


Got 30 RMT symbols
000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 000a8004=8004000b 
00098005=8005000a 00088006=80060009 00078007=80070008 00068008=80080007 

@SuGlider
Copy link
Collaborator

SuGlider commented Mar 31, 2025

I would expect send and receive data to be identical.

Let me check it. It sends 30 samples and prints 60 samples.

@fanfanlatulipe26
Copy link
Author

Word on the left of "=" is the received RMT symbol, and on the left the sent one.
The received symbol seems to have the 2 16bit words swapped ???
I have a look with a logic analyzer to the generated waveform and discover that the low part of the pulse correspond in fact to the low part of the next symbol .
I used a low frequency because 10Mhz is too much and the tick is not 100ns, and also bigger pulses.
Here are the changes I made:

//#define RMT_FREQ               10000000  // tick time is 100ns
#define RMT_FREQ               1000000  // tick time is 1us

and

// rmtSetRxMaxThreshold(RMT_RX_PIN, 20);
    rmtSetRxMaxThreshold(RMT_RX_PIN, 30000);

and

 for (i = 0; i < 255; i++) {
 //  data[i].val = 0x80010001 + ((i % 13) << 16) + 13 - (i % 13);
   data[i].val = 0x80010001 + (((i*4) % 16) << 16) + 16 - ((i*4) % 16);
    my_data[i].val = 0;
  }

And the result

Got 30 RMT symbols
000d8001=80010011 00098005=8005000d 00058009=80090009 0011800d=800d0005 
000d8001=80010011 00098005=8005000d 00058009=80090009 0011800d=800d0005 
...

First pulse in the burst should be 1us H / 17usL,  second 5usH / 13usL, third 9usH / 9usL

![Image](https://github.com/user-attachments/assets/53e30bad-b556-486f-8ec0-9095274a1a2e)

@fanfanlatulipe26
Copy link
Author

Sorry, I didn't manage to past the waveform ...
We can see:
first pulse 1usH/13L in fact 13usL is the low part of next RMT symbol for low part
second 5usH/9usL
third 9usH/5usL
forth 13H/17L

@fanfanlatulipe26
Copy link
Author

Image

@SuGlider
Copy link
Collaborator

SuGlider commented Mar 31, 2025

Got 30 RMT symbols
000d8001=80010011 00098005=8005000d 00058009=80090009 0011800d=800d0005
000d8001=80010011 00098005=8005000d 00058009=80090009 0011800d=800d0005
...

First pulse in the burst should be 1us H / 17usL, second 5usH / 13usL, third 9usH / 9usL

Sent pulses:
8001 + 0011 ==> both are High, first for 0x4000 ticks (15bits = 16384 ticks) and the second for 1 tick high
8005 + 000d ==> both are High, first for 0x4002 ticks and the second for 6 ticks high
8009 + 0009 ==> both are High, first for 0x4003 ticks and the second for 4 ticks high
800d + 0005 ==> both are high
all are High. I don't see any RMT Symbol even (last bit 0), which would be low level.

Not correct... check #11200 (comment)

@fanfanlatulipe26
Copy link
Author

80010011 8001 0011 1 tick high, 17 ticks low
8005000d 5 ticks high, 13 low and it is what we see (more or less for the low part ...) on the waveform
The bit and byte numbering and order is very confusing in the documentation ...

@SuGlider
Copy link
Collaborator

SuGlider commented Mar 31, 2025

80010011 8001 0011 1 tick high, 17 ticks low 8005000d 5 ticks high, 13 low and it is what we see (more or less for the low part ...) on the waveform The bit and byte numbering and order is very confusing in the documentation ...

Image

TRM shows the bits in the reverse order, from LSB to MSB, but the bits are not reversed inside each field.

a 32 bits has 2 RMT information. For example:

0x8001 = Level 1 | 0x1 = High level for 1 tick
0x0011 = Level 0 | 0x11 = Low level for 3 ticks.

Level Bit 15 during Bits 0..14 number of Ticks is sent first.
Then, signal in the signal described in bits 16 to 31 is sent after that one.

Therefore myData = 0x8001000e => First sends LOW for 14 ticks and then sends HIGH for 1 tick.

In order to avoid problems, it would be better to set the transmission using this structure:

typedef union {
  struct {
    uint32_t duration0 : 15;    // bit 0 to 14
    uint32_t level0    : 1;     // bit 15
    uint32_t duration1 : 15;    // bit 16 to 30
    uint32_t level1    : 1;     // bit 31
  };
  uint32_t val;
} rmt_data_t;

The equivalent code would be:

void loop() {
  // Init data
  int i;
  for (i = 0; i < 255; i++) {
    //data[i].val = 0x80010001 + ((i % 13) << 16) + 13 - (i % 13);
    data[i].level0 = 0; // LOW
    data[i].duration0 = 1 + 13 - (i % 13); // number of Tick on Low
    data[i].level1 = 1; // HIGH
    data[i].duration1 = 1 + (i % 13); // number of Ticks on HIGH
    // set the received data to zero
    my_data[i].val = 0;
  }
  data[255].val = 0;
  Serial.println("=======\r\nSent Data:\r\n=======");
  // Printout the received data plus the original values
  for (i = 0; i < 60; i++) {
    Serial.printf("%08lx[%c0x%03x|%c0x%03x] ", data[i].val,
                  data[i].level0 ? 'H' : 'L', data[i].duration0,
                  data[i].level1 ? 'H' : 'L', data[i].duration1);

    if (!((i + 1) % 4)) {
      Serial.println("");
    }
  }
  Serial.println("\n");

  // Start an async data read
  size_t rx_num_symbols = RMT_NUM_EXCHANGED_DATA;
  rmtReadAsync(RMT_RX_PIN, my_data, &rx_num_symbols);

  // Write blocking the data to the loopback
  rmtWrite(RMT_TX_PIN, data, RMT_NUM_EXCHANGED_DATA, RMT_WAIT_FOR_EVER);

  // Wait until data is read
  while (!rmtReceiveCompleted(RMT_RX_PIN));

  // Once data is available, the number of RMT Symbols is stored in rx_num_symbols
  // and the received data is copied to my_data
  Serial.printf("Got %d RMT symbols\n", rx_num_symbols);

  // Printout the received data plus the original values
  for (i = 0; i < 60; i++) {
    Serial.printf("%08lx=%08lx ", my_data[i].val, data[i].val);

    if (!((i + 1) % 4)) {
      Serial.println("");
    }
  }
  Serial.println("\n");

  delay(500);
}

@SuGlider
Copy link
Collaborator

real tick set to: 100ns

Please connect GPIO 18 to GPIO 21, now.
Got 30 RMT symbols
000d8001=8001000e 000c8002=8002000d 000b8003=8003000c 000a8004=8004000b
00098005=8005000a 00088006=80060009 00078007=80070008 00068008=80080007

Indeed, received data has the 16bits swapped. When applying the rmt_data_t to the received data, [level0][duration0] should be [level1][duration1] instead.

@SuGlider
Copy link
Collaborator

This code ilustrates waveforms and how to encode it using RTM (transmission only):
https://github.com/espressif/arduino-esp32/blob/master/libraries/ESP32/examples/RMT/RMTWrite_RGB_LED/RMTWrite_RGB_LED.ino

@fanfanlatulipe26
Copy link
Author

I fully agree with you that the best is to use the various field of the data structure of rmt_data_t., mainly in a teaching example.
Your example is realy better for a beginner.
In fact the deference between the words we received in my_data[] and the reference in data[] comes from the fact that the GPIO TX pin is set to 0 by default a startup and also after each rmtWrite.
The first symbol start with a Low pulse (8001000e[L0x00e|H0x001] ) and so there is no transition on the GPIO and nothing detected by the rmtReadAsync.
If we force the idle state of GPIO to HIGH we receive exactly the same words.
I added at the end of startup

  if (!rmtSetEOT(RMT_TX_PIN, HIGH)) {
     Serial.println("rmtSetEOT failed\n");
  }

Now, as expected only the first burst is bad but the following are perfect:
( a strange error appears : E rmt: user buffer too small, received symbols truncated ???????????????????????????????????????????)

=======
Sent Data:
=======
8001000e[L0x00e|H0x001] 8002000d[L0x00d|H0x002] 8003000c[L0x00c|H0x003] 8004000b[L0x00b|H0x004] 
8005000a[L0x00a|H0x005] 80060009[L0x009|H0x006] 80070008[L0x008|H0x007] 80080007[L0x007|H0x008] 
80090006[L0x006|H0x009] 800a0005[L0x005|H0x00a] 800b0004[L0x004|H0x00b] 800c0003[L0x003|H0x00c] 
......

E rmt: user buffer too small, received symbols truncated               ???????????????????????????????????????????
Got 30 RMT symbols
000e8003=8001000e 000d8001=8002000d 000c8002=8003000c 000b8003=8004000b 
000a8004=8005000a 00098005=80060009 00088006=80070008 00078007=80080007 
00068008=80090006 00058009=800a0005 0004800a=800b0004 0003800b=800c0003 
............     bad, has expected .
..........

=======
Sent Data:
=======
8001000e[L0x00e|H0x001] 8002000d[L0x00d|H0x002] 8003000c[L0x00c|H0x003] 8004000b[L0x00b|H0x004] 
8005000a[L0x00a|H0x005] 80060009[L0x009|H0x006] 80070008[L0x008|H0x007] 80080007[L0x007|H0x008] 
......

Got 30 RMT symbols
8001000e=8001000e 8002000d=8002000d 8003000c=8003000c 8004000b=8004000b 
8005000a=8005000a 80060009=80060009 80070008=80070008 80080007=80080007 
80090006=80090006 800a0005=800a0005 800b0004=800b0004 800c0003=800c0003 
.....
=======
Sent Data:
=======
8001000e[L0x00e|H0x001] 8002000d[L0x00d|H0x002] 8003000c[L0x00c|H0x003] 8004000b[L0x00b|H0x004]

@SuGlider
Copy link
Collaborator

E rmt: user buffer too small, received symbols truncated

This may be related to this define RMT_MEM_RX RMT_MEM_NUM_BLOCKS_3 --> for the ESP32 it can go up to 8 BLOCKS.
It may also be related to the resolution (RMT_FREQ) and rmtSetRxMaxThreshold() value.

Using the same parameters from the example I don't see this error message.

@fanfanlatulipe26
Copy link
Author

fanfanlatulipe26 commented Mar 31, 2025

I only have once this message when I add

  if (!rmtSetEOT(RMT_TX_PIN, HIGH)) {
     Serial.println("rmtSetEOT failed\n");
  }

@SuGlider
Copy link
Collaborator

I only have once this message when I add

  if (!rmtSetEOT(RMT_TX_PIN, HIGH)) {
     Serial.println("rmtSetEOT failed\n");
  }

Correct, I've gotten the error message now.
The fix for this example is to do not use the EOT as HIGH and just start the samples with High level, instead of Low level.

@fanfanlatulipe26
Copy link
Author

Funny: I modified the test in this way yesterday night just before going to bed ;-)
The example will be now much better.
The user will see a good match between send and received data.
Only the last received symbol does not match the reference data but it is normal because we lack the transition to detect the end of the last low pulse.

But I was still wondering why we have this error. The rmtReadAsync should read at most rx_num_symbols symbols (30 in our case) and should not give this error.
In the test case, if we write 30 symbols but only read 20 (why not ?) we always get the error.
Reading the espressif documentation for rmt_receive the error is correct and in the specification of the driver because the driver only stop reading on timeout (max pulse level length)

If this buffer overflows due to an insufficient buffer size, the receiver can continue to work, but overflowed symbols are dropped and the following error message is reported: user buffer too small, received symbols truncated

Don't know if we can hide this error if we realy just need the beginning of the burst of pulses ...
Will you update the example in the package ?

@SuGlider
Copy link
Collaborator

SuGlider commented Apr 1, 2025

Yes, I'll update the example.

@SuGlider
Copy link
Collaborator

SuGlider commented Apr 1, 2025

The error may be because of some IDF way of setting TX line when EOT is HIGH. It can also happen because of the sequence of getting ready to read RMT on RX pin.

The error only happens in the very first transmission and I don't see it again after that.
It is a loop back circuit with many possible pin state transitions in between. Not sure.

@fanfanlatulipe26
Copy link
Author

Yes the very first ransmission was a bit special, starting with a LOW level and ending with a HIGH one and the reveiver decode 31 symbols . After that it only decode 30 symbols as expected.
Thank you for your help (-;
I am learning RMT trying. Espressif API is powerfull but a bit tricky. Arduino library is far simple.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Status: In Progress ⚠️ Issue is in progress
Projects
Development

Successfully merging a pull request may close this issue.

2 participants