-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
Comments
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! |
I ran the example with the new esp32-hal-rmt.c.
|
Let me check it. It sends 30 samples and prints 60 samples. |
Word on the left of "=" is the received RMT symbol, and on the left the sent one.
and
and
And the result
|
Sorry, I didn't manage to past the waveform ... |
Not correct... check #11200 (comment) |
80010011 8001 0011 1 tick high, 17 ticks low |
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 Level Bit 15 during Bits 0..14 number of Ticks is sent first. 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);
} |
Indeed, received data has the 16bits swapped. When applying the |
This code ilustrates waveforms and how to encode it using RTM (transmission only): |
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.
Now, as expected only the first burst is bad but the following are perfect:
|
This may be related to this Using the same parameters from the example I don't see this error message. |
I only have once this message when I add
|
Correct, I've gotten the error message now. |
Funny: I modified the test in this way yesterday night just before going to bed ;-) 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.
Don't know if we can hide this error if we realy just need the beginning of the burst of pulses ... |
Yes, I'll update the example. |
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. |
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. |
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
Other Steps to Reproduce
I tried with other GPIOs. Same results
I have checked existing issues, online documentation and the Troubleshooting Guide
The text was updated successfully, but these errors were encountered: