This is an example project to keep the motor at a constant speed of 2500RPM using bidirectional dshot and a rudimentary PID controller. The motor will start turning after 10s after turning the RP2040 on.
[!NOTE] Two things about the state of this repo: I have some newer implementations of bidirectional DShot that are more resilient towards clock deviations between RP2040 and ESC and that won't require manual clock adjustments. Secondly, I am using the wizio-pico core here, that was deprecated and put offline a month or so after I put this project live. The code in this repo, as it is, will likely not compile. I'd recommend that you check out the newer, more complete and still maintained RP2040 Arduino Core by earlephilhower. Make sure that when you install it, you follow these instructions to enable long file paths on Windows and Git. You can find the newer code in my Kolibri-FC repo, or more detailed:
- The PIO program
- Startinga DShot transmission
- Reading the eRPM packet and preparing the buffer for the next transmission
- required platform.ini parameters, though I don't recommend 264MHz, rather go with 132MHz, as I am facing some issues with the chip stability right now, and the 264MHz is only required because of the slow PID loop on my end 🙈
outpin
is the DShot pinpwmpin
is an arbitrary pin (has to be outpin + 1) that does the 10kHz PID loop frequency (used as a quick and dirty timer only, not useful for actual output)appendChecksum()
is used to append a checksum to the outgoing DShot packetcalcRPM()
calculates the RPM based on the received packetcalcThrottle()
is the PID loop with the control constants kP, kI, and kDDELAY_SHIFT_COUNT
to the according valuepio_sm_set_clkdiv_int_frac
) set the appropriate clock dividers (integer and fractional). There are global defines for DShot 300 up to DShot 2400.bidir_dshot.pio.h
beforehand.pio_sm_get_blocking
to the actual pwmpin frequency.
pio_sm_put(pio, sm, appendChecksum((throttle + 48) << 1));
to set the throttle to your desired value, where throttle is the throttle value from 0 to 2000
Sorry for the very dirty documentation, it was not meant to go online like this yet ^^. Please post an issue if you have any questions.