espressif / esp-idf

Espressif IoT Development Framework. Official development framework for Espressif SoCs.
Apache License 2.0
13.31k stars 7.2k forks source link

RMT DShot example not working (IDFGH-12528) #13533

Open wjxway opened 5 months ago

wjxway commented 5 months ago

Answers checklist.

General issue report

IDF version ESP-IDF v5.3-dev-1353-gb3f7e2c8a4

Dev board XIAO-ESP32-S3

Operating System used Windows

How did you build your project? Through PlatformIO

Power Supply used USB

What is the expected behavior? The only thing I modified on the example code is DSHOT_ESC_GPIO_NUM 6 The example code should be able to send out packets of 16 pulses continuously and drive a ESC.

What is the actual behavior? See the attached image RigolDS2 It is not continuously transmitting, the pulses are of incorrect number and time, and the idle level is incorrect, and of course the motor is not spinning.

I tried to add IRAM_ATTR before callback functions and played with several parameters including DMA, but none are helping with this issue.

BTW, personally I prefer the old API as it's easier to write and understand, especially when the conversion process is very simple (where I can directly construct the sequence or easily modify it) or complicated and offers better performance if you directly play with RMTMEM. However it does not offer simultanuous update ability. Would it be possible to add simultanuous update ability to the old API manually by playing with the registers?

wjxway commented 5 months ago

It would be nice to offer both the old and the new API, I personally find the old API easier to write (it's definitely more concise) and have higher performance.

suda-morris commented 5 months ago

I just test the example with a DShot motor (DSHOT300 protocol), it spins as expected. Same example, only changed the GPIO.

image

suda-morris commented 5 months ago

WRT

offers better performance if you directly play with RMTMEM.

Yes, it's always the best performance if we ask the user to write the code by read/write the SOC register directly. But the issue is, the code can only work for one ESP chip. The SOC changes so much, we can hardly promise a compatible register layer. On previous chips, like esp32, it's OK to read/write the RMTMEM in the application code, but after esp32s3, because the RMT has the DMA ability, that RMTMEM can also be controlled by DMA. Also, since the RMTMEM is a shared resource, shared by multiple channels, it's not good to use them without an abstraction layer.

wjxway commented 5 months ago

Intriguing, I will do the test again using a seperate board and motor driver to see if it can work.

Also, since the RMTMEM is a shared resource, shared by multiple channels, it's not good to use them without an abstraction layer.

I agree that an abtraction layer should be provided, I guess I am wondering if the old api will continue to exist for compatibility in the future and if we can still directly manipulate RMTMEM in esp32-s3? I have built a optical communication system and it is only fast enough if I directly manipulate RMTMEM on esp32, but I might want to upgrade the version of arduino/IDF or switch to esp32-s3 in the future. Thanks!

wjxway commented 5 months ago

I also have found a bunch of weird quirks when using the RMT peripheral that is not well documented, i.e. what will happen if a pulse is filtered out because it's too short? what will happen if the ending pulse is too short and get filtered out? (I think on esp32 it will create a weird rmt_item32_t object in RMTMEM like 0b0 000000000010 0 001010010000000) what will the output pulse length be if the pulse start between two ticks and end between two ticks? It would be nice to have a more detailed documentation for them.