Custom firmware for multirotor ESCs
Multirotor flight control requires an update frequency on the order of hundreds of cycles per second. Most ESCs sold for RC plane use are capable of reading a PPM input at frequencies of up to 400 Hz, but they do not translate the PPM input to motor speed output at the same rate.
tl;dr: Flash Atmel-based ESCs with simonk’s firmware to improve responsiveness and test with a power supply before hooking it up to an actual battery.
Flashing the ESC
Fortunately, ESCs based on Atmel chips can be reprogrammed with Simon Kirby (simonk)’s firmware, which makes the ESC capable of updating the motor speed at these high frequencies. There is a giant RCGroups thread on the topic as well as a video demonstrating the difference it makes.
Once the programming pins have been wired to the ESC, we can clone simonk’s repository, build, and flash the ESC. (My ESCs are of the Mystery 40A kind, which takes the bs.hex firmware image.)
git clone git://github.com/sim-/tgy cd tgy make all avrdude -c stk500 -P /dev/ttyACM0 -p m8 -e -U flash:w:bs.hex
When testing a new firmware image (which may or may not work, depending on how careful you are about checking compatibility), it is a bad idea to power the ESC straight off a (lithium polymer) battery! Different ESCs are wired differently to different combinations of N-channel and P-channel FETs, so the wrong firmware image can create a short through which the battery will happily try to discharge hundreds of amps of current. A power supply, on the other hand, can be current limited. Even if the current limit is set too high, the power supply will detect a short and cut off the current before the ESC can destroy itself.
The risk of using the wrong firmware image can be reduced by checking this list of ESCs and their appropriate firmware versions.
If the wrong firmware is loaded, the FETs on the ESC itself will beep instead of the motor. This is bad! The wrong firmware can still start to spin the motor, but the power will be sourced from places from which power should not be sourced, which may damage the ESC.
If the correct firmware is loaded, the ESC will be much more responsive compared to one with the factory firmware.
Testing the firmware
To test the responsiveness of the two firmwares, I taped my tricopter to the edge of a table and tested one ESC-rotor pair.
I then set the throttle at a level insufficient to hold up the tricopter. By doing this, I could drop the tricopter and compare the rate at which it fell at various D controller gains, starting at 0 and incrementing by 5, up to 25 (the P and I gains were left at 0).
In the following video, I test an ESC with the factory firmware and see that it does not respond significantly to the D controller’s throttle inputs even at a D gain of 25. The various D gains are shown in the bottom right corner of the video. I then switch to using an ESC flashed with simonk’s firmware and set the D gain to 15 for comparison.
The following video shows the same test (D gain changed from 0 to 25) done with an ESC flashed with simonk’s firmware.
Admittedly, these tests are not rigorous, and there are factors (e.g., changing throttle levels due to human error or falling battery voltage) that could have affected the apparent responsiveness of the ESCs. However, the D response of the factory firmware does not change significantly between a D gain of 5 and 25 while that of simonk’s firmware shows an obvious improvement between 5 and 10.
Modifying the firmware
The great thing about simonk’s firmware, other than the fact that it is better than the factory ESC firmware, is that it is open source. Eventually, I would like to customize the firmware to do cool things with the ESC myself, at least if I do not decide to design my own ESC first. But a cursory look through the code revealed at least this easy modification:
In tgy.asm, there are STOP_RC_PULS and FULL_RC_PULS that determine the pulse widths the ESC interprets as the minimum and maximum throttle inputs. The difference between these two values must be reflected in POWER_RANGE. For example, if STOP_RC_PULS is 100 and FULL_RC_PULS is 1700, their difference is 1600, so POWER_RANGE should be 1600 * CPU_MHZ / 16 + MIN_DUTY. (However, simonk notes that increasing the range of the possible pulse widths will decrease the switching frequency. Increasing the pulse width range from the default 800 us to 1600 us, for example, will bring the switching frequency down to the 10 kHz range, which is audible and annoying.)
A more useful modification would be to change the range from the default [1060, 1860] to [100, 900] so the ESC can take a 1 kHz PWM signal in the eventuality that I implement a 1 kHz controller.
Strangely, two of my ESCs registered a 1060 us pulse input as the minimum throttle (as they are supposed to) and armed at that input. A third ESC refused to arm until I gave it a pulse input of around 1050 us. All three ESCs still seem to have the same pulse-width-to-throttle range, however.
I flashed a friend’s HobbyKing Blue Series 12A ESCs with the bs_nfet firmware. They worked beautifully!