For curiosity and learning, I wanted to poke at a commercial brushless motor controller. Thanks to the current popularity of multirotor aircraft, the cheapest option on Amazon that day was a four-pack designed for small quadcoptor drones. Among the listing description is a string "BLHeli_S" that meant nothing to me at the time. Once I received the product and looked it over, I saw "BLHeli_S" written on the label as well, I thought I should at least do a web search to learn more.

BLHeli_S is a development of BLHeli motor control firmware, whose source code is on GitHub. From what I can understand, BLHeli_S is a port to SiLabs 16-bit microcontrollers offering higher performance than original BLHeli 8-bit hardware target. At first, I was thrilled there might be another brushless motor algorithm I could try to learn from, but my enthusiasm quickly cooled when I realized BLHeli_S was written in assembly language for maximum performance. That's hard core. Understanding that codebase might take more work than I'm willing to put in.

I found additional information on Ardupilot website, which supports BLHeli_S and the even newer BLHeli32 motor controller firmware. In addition to standard RC servo control signal, these controllers also support a more advanced protocol called DShot. It allows higher bandwidth and lower latency, as well as digital checksum to detect and discard corrupted control signals. The most fascinating feature is bidirectional communication, which allows the motor controller to send back information like motor RPM. BLHeli_S also supports OneShot and OneShot125 protocols, but they offer neither the wide compatibility of RC servo style PWM nor the advanced features of DShot. I'm probably never going to touch those.

I could find scattered reviews of BLHeli_S like this one. The most interesting page I stumbled cross was What is DShot ESC Protocol which pointed me to Betaflight. Skimming through Betaflight's GitHub repository, I found its DShot command driver. It was much easier than trying to find Ardupilot's implementation. (This is as close as I got. [UPDATE: According to comment by David, the RCOutput_bdshot.cpp file I found handles telemetry coming back from the ESC. Outbound DShot control is handled by RCOutput_serial.cpp in the same directory.])

Looking for implementations outside of those large flight controller projects, I found several GitHub repositories of people taking a stab at it.

  • https://github.com/bird-sanctuary/arduino-bi-directional-dshot runs on Atmel AVR Arduino as a diagnostics and debug tool.
  • https://github.com/gueei/DShot-Arduino with a writeup on https://arduino.stackexchange.com/questions/43851/dshot-implementation-on-arduino-esc-protocol
  • https://github.com/derdoktor667/DShotRMT proclaims to implement bidirectional DShot using ESP32 RMT peripheral and reusable as an Arduino library.

I also found an Arduino forum thread of someone asking about bidirectional DShot protocol, and the answer was a link to DShot - the missing Handbook. I doubt I would learn SiLabs assembly to dig into BLHeli firmware itself, but it might be interesting to talk to my new BLHeli_S brushless controllers via bidirectional DShot.

For my first experiment, though, I'm going with the tried-and-true RC servo PWM.