I’ve recently become interested in making “machines” of various sorts. I was sorting through some of my RC (radio control) plane “stash” the other day and came across various brushless motors and electronic speed controllers (ESC) like these. In RC, Brushless ESCs are usually connected to a radio receiver which generates servo control pulses.

Turnigy Plush 40 ESC and brushless outrunner motor with 6 inch prop

So this morning I thought it would be fun to try and get a Wemos D1 mini controlling a brushless motor. I’ve done similar before. I can remember, back in the dark ages of 2013, using a Guzunty Pi to generate servo control signals to drive a brushless ESC.

I’ve also controlled servos directly with Arduino before now. This is handy because Wemos D1 mini can use the Arduino IDE. There’s also a ‘servo’ library that we ought to be able to use.

This also worked perfectly with a servo. Twiddle the potentiometer and the servo moves accordingly. YAY!

And Then it Got Harder

“This is easy – I’m on a roll” so I hooked it up to the brushless ESC instead of the servo and…

Nothing happened! GAH!

So I took out my trusty “servo driver” and tried the ESC with that.

Turnigy servo driver gives out correct pulses to control a servo (it has an ATMEGA inside – I looked)

It worked fine. “Oh!” I thought. The wiring looked good, so maybe it’s something to do with the Wemos‘ 3V3 logic levels? So I tried a level shifter to output a 5V signal. This didn’t help (you’ll see why later on).

So, fresh out of excuses, I decided to “get the ‘scope’ on it” and see exactly what was happening with the signals.

Lowest setting on the Wemos when still set to 0°. Shows 0.6 ms pulse width

Oscilloscope Results Proved Revealing…

The only appreciable difference was in the pulse widths. But since pulse width is the language of servos, it matters. The Wemos “zero point” of 0.6 ms is a lot lower than the 0.9 ms of the servo tester.

So you can see our Wemos is pushing out a pulse width that is rather too low. The way servo pulses are supposed to work, a servo would be at 0° at 1.0 ms, 90° at 1.5 ms and 180° at 2.0 ms pulse width. The ESC was not recognising the 0.6 ms pulses and thus refused to activate.

Let’s Test the Range

While I had the oscilloscope on the servo tester, I measured the ‘actual’ pulse width settings that affect the motor’s behaviour. I found that, below 1.25 ms the motor wouldn’t spin up and it reached maximum speed at 1.78 ms. This data would prove useful later on.

The data also showed why the logic level shifter didn’t change anything, since the ESC is triggered on 3V3 logic anyway. (I was firing blind before I scoped it).

With some further experimentation, changing the degree values in the sketch enabled me to tweak the output so that not only did the ESC react to the Wemos output, but it was fine-tuned to make best use of the ‘reactive range’. The ESC only changes the motor speed between 1.25 and 1.78 ms so I tweaked the sketch iteratively until I hit upon figures of 65° for LOW and 130° for HIGH. This meant that the full range sweep of the potentiometer was in use instead of having large ‘dead’ zones at each end where nothing changed.

Final Tweaked Sketch

/* Modified combination of sweep and knob, http://arduino.cc/en/Tutorial/Sweep
tweaked for a Turnigy Plush 40 brushless ESC
*/
#include <Servo.h>
Servo esc; // create servo object to control a servo
int val; // variable to read value from analog pin
void setup()
{
esc.attach(D7); // attaches servo on D7 to the servo object
}
void loop()
{
val = analogRead(0); // reads potentiometer value (between 0 and 1023)
val = map(val, 0, 1023, 65, 130); // scale it to use it with the servo (between 65 and 130)
esc.write(val); // sets servo position according to scaled value
delay(15); // waits for servo to get there
}
/* 65 degrees corresponds to 1.21 ms pulse width. Turnigy plush 40 won't spin motor until 1.25 is reached
* 130 degrees corresponds to 1.87 ms pulse width. Turnigy plush 40 maxes motor out at 1.78 ms
* If you use 0-180 the ESC won't spark up the motor at all, pulse needs to be >= 0.9 to get a response
* But also if you use 65-130 degrees you maximise the usable range of the potentiometer, so there's
* hardly any dead space. Gives you much better control along the range of movement
*/

Adjusted to a minimum of 65° on the Wemos output bringing a more usable 1.3 ms pulse width

Adjusted to a maximum of 130° on the Wemos output bringing a more usable 1.9 ms pulse width

Hope You Enjoyed the Story

Now I’ve got it all working exactly as I wanted it to. It took a bit longer than I thought it would, but it was educational.

I had fun with this and got to use my oscilloscope again. It would have been very difficult to debug this issue without one. Several of the parts I used here are available in the RasPiO online store. Come and have a look…

2 Responses to “Using Wemos D1 mini to control a brushless motor with ESC and servo signals”

Interesting – one question. The oscilloscope features you used during this venture amount to just about all I can ever imagine needing an o-scope for in my projects. I’ll never work with analog circuitry and I’m unlikely to ever need to think about complex waveforms, but I can imagine needing to spy on PWM type signals.