In this blog post, we shall deal with controlling drone motors and some other hardware devices. A lot of hardware like the ESC, servo motors, piezoelectric speakers to name a few are designed such that they can be controlled with PWM (Pulse Width Modulation). The basic crux is that PWMs are square waves and the width of the pulse (duty cycle) will dictate how fast a motor spins. For example, a 50% duty cycle may cause the motor to spin at say 10,000 RPMs and a 25% duty cycle may cause the motor to spin at say 2000 RPMs. For exact technical spec on your hardware can usually be found in your hardware’s datasheet or manual.

Image result for pulse width modulation pwm

Servo Motors

Let’s try experimenting with a servo motor. I have with me an EMAX servo motor. These can be bought online for about US$1-2 per piece. However, there are more expensive (and precise) servos available which cost in US$20-30 range per piece. Before starting with a drone motor (Brush-less DC Motors, BLDC), I recommend playing with a servo to make the transition less prone to body injuries.

So, I have the EMAX ES08MA2 servo, try searching this on google, you should get its datasheet (some people call it manual, but datasheet seems to be a cooler word for it, you get my point!). Following is the relevant excerpt. You can notice the datasheet lists the exact dimensions of this device along with the amount of torque and angular velocities of it. But for now I am most interested in knowing how to control it, so look at the 2nd row titled, ‘STD DIRECTION’. It says it turns counterclockwise when you provide a pulse of 1500 micro-sec to 1900 micro-sec (or 1.5ms to 1.9ms). So, 20ms is the pulse period (this is a commonly known fact amongst hardware tinkerers so this is often not specified explicitly in the datasheet, note down this fact). So if you provide a logic high (5V) for say 1.6ms (anything between 1.5ms-1.9ms) out of 20ms (so the duty cycle is about 8%, for 1.6ms). So it turns about 8% of 360 degrees (full circle) or about 30 degrees or so. In conclusion, the width of the pulse defines the position of the servo arms. Notice the three wires coming out of the servo. In my case, the red wire is 5V DC power supply, brown is the ground wire and yellow is the signal wires. So the signal needs to be provided into the yellow wire, along with power supply and ground as needed. You servo’s wire coding might be different so check it out on your datasheet.

Image result for emax servo pin
For EMAX Servos. Your servo’s wire coding might be different than this.
Obtained from : https://www.emaxmodel.com/es08ma-ii.html#product_tabs_description_tabbed

How to Generate PWMs?

Now that we know WHY, let us see the HOW. Here are some of the ways to generate the PWMs. We shall briefly discuss these.

  • Servo Testers
  • Function Generators
  • Arduino
  • Specialized Servo Controller Boards
 
 
 
 

Time for Fun!

In this section, we put all that we learned to use. I have the following devices with me: a) EMAX servo motor, b) Servo tester, c) Oscilloscope (optional), d) Arduino. I also want to test out these i) ESC+BLDC (drone motor setup) ii) piezoelectric buzzer.

Demo 1 : Servo tester+Servo motors:I am demonstrating the servo tester device to drive a servo motor.

Demo-2 : Arduino + Servo motors : In this demo, I am programming my arduino board (I have the Teensy2++, it is almost like Arduino Nano).

// Code for Demo-2
#include <Servo.h>

Servo myservo; 
int led = 17;

int mc = 1500; 
void setup() {
myservo.attach(16);  //< Initialize 16th pin as servo signal
myservo.writeMicroseconds( 1500 ); //< init servo with 1500.
  pinMode(led, OUTPUT);     //< LED just for visual

}

void loop() {
  myservo.writeMicroseconds( mc ); //< command the servo. 
  mc+=50;

  digitalWrite(led, HIGH);   // turn the LED on (HIGH is the voltage level)
  delay(100);               // wait for a second
  digitalWrite(led, LOW);    // turn the LED off by making the voltage LOW
  delay(500);  

}

Demo-3: Arduino-PC (Linux) communication with USB: A Arduino board shows up as a file on Linux. You programs in C/C++/Python and even Java or whatever, need to write and read to this file to communicate with the Arduino. In this example, the Arduino responds back with the same text it received.

// Code for Demo-3
int led = 17;

void setup() {
  // put your setup code here, to run once:
  Serial.begin( 9600 );
  Serial.println( "Hello\n" ); 
    pinMode(led, OUTPUT);     

}

int c=0;
char incoming_string[100];  
void loop() {

  // If you see anything is available, read it all, 
  // 1 character at a time
  while( Serial.available()  ) {
    incoming_string[c] = Serial.read();
    c++; 
  }

  if( c > 0 ) {
    incoming_string[c] = '\0'; //< Don't forget this

    // Send back whatever was received
    Serial.write( "I received: " );
    Serial.write( incoming_string );
    c = 0;

    // Blink the LED to indicate this action
    digitalWrite(led, HIGH);
    delay(100);             
    digitalWrite(led, LOW); 
    delay(100);  
  }
  delay(5); 
}

Demo-4: Arduino + USB input (from PC) + Servo motors: Here I read input from PC (through serial communication). From my Linux terminal, I am going to echo out numbers to Arduino which will be pulse widths. The Arduino will read these pulse widths and act accordingly on the servo.

// Code for Demo-4 
#include <Servo.h>

int led = 17;
Servo myservo; 
void setup() {
  // put your setup code here, to run once:
  Serial.begin( 9600 );
  Serial.println( "Hello\n" ); 
  pinMode(led, OUTPUT);
  myservo.attach( 16 );
  myservo.writeMicroseconds( 1000 );      

}

int c=0;
int num = 0;
void loop() {

  // If you see anything is available, read it all, 
  // 1 character at a time
  while( Serial.available()  ) {
    char this_char = Serial.read();
    if( this_char == '\n' )
      break;
    int this_digit = (int)(this_char - '0');
    if( this_digit >= 0  && this_digit <= 9 ) {
      num = 10*num + this_digit; 
      Serial.write( "OK " ); 
    }
    else {
      Serial.write( "NOTOK " );
      c=0 ;
      num=0;
      break; //if you see any non digit charater just ignore everthing
    }
    c++; 
  }

  if( c > 0 ) {
    // Send back whatever was received
    Serial.write( "# of digits rcvd=" );
    Serial.write( char(c+'0') );
    Serial.write( '\n' ); 
    
    // Blink the LED to indicate this action
    digitalWrite(led, HIGH);
    delay(100);             
    digitalWrite(led, LOW); 
    delay(100);

    Serial.write( "Setting pulse at " );
    Serial.write( String( num ).c_str() );
    myservo.writeMicroseconds( num ); 
    c = 0;
    num=0;  
  }
  delay(5); 
}

Demo-5: Brushless DC Motor aka Drone Motors: I am repeating the tests I did with servo motors on BLDC. To drive a BLDC motor you will also need an ESC. Please please please do not have your propellers on (you have been warned). Another friendly advise, when dealing with drone motors be extra careful, always test with servos before jumping on BLDC. If things go wrong with your BLDC and the propellers are mounted, you can easily end up in a hospital (or maybe a clinic). Here is what the following videos are about: i) Servo tester and BLDCs, ii) USB+arduino+BLDC.

Other Advanced Techniques

What we saw above is most suitable for common servo motors and BLDC motors which run in 50 Hz (ie. they can be signaled 50 times a second). However, some higher quality ESCs can be signaled at say 400 Hz. See for example the T-motor Air series ESC. It is signally 400 times a second. What this means is that the signal period can be as low as 2.5mili-seconds. Recall the periods we used in our trials were 20 mili-seconds. What you can achieve with such ESCs more controllable flights.

However, our usual Arduino Servo libraries are fixed at 50Hz frequency. This is kind of a bummer, because if you have access to one of these expensive ESC you are essentially not making its full use. Fortunately where is another Arduino library (PWM.h). With this you can essentially choose the frequency of the pulses. Check the documentation of your ESC to know more about the operating params of your ESC. In the following video, we will try to look at a the manual for rather expensive ESC from DJI and try to control it at higher frequencies.

Image result for t motor esc
A high refresh rate ESC from T-motors.

TODO : Try PWM.h

Other Things to be Aware of Drone Motors

  • KV (RPM per volts): This measure is often listed in the motor datasheets. For example, if the motor is rated as 2KV means that for every volt the max rpm can be 2000 (ie. 2K). So if you supply 15 volts to the motor it can spin at maximum 30,000 RPM.
  • Max current of the motors and how to choose ESC for this current: The maximum current draw is also specified in the motor datasheets. Typically around 15-20 Amps. You want to use an appropriate ESC. The crux is the Amps rating of ESC has to be greater than motor’s max current. In the event, the motor tries to draw higher current than the ESC can handle, the ESC would burn.
  • Some exotic (and expensive) ESC and motors. Shenzen based T-motors is renowned to make world-class BLDC motors. They sell some exotic motors and ESCs. Some of their motors have silver wires which makes it a bit more efficient compared to copper windings and hence the cost. Some of their motors have very high current draws of up to 60Amps. Some of their expensive motors have titanium bodies so that it reduces wear and tear. They also make a range of ESCs. Some of their ESCs and motors are waterproof. If you have the budget you may like to buy these stuff, but it remains a bit beyond hobbyist to make use of such exotic motors and ESC.

Ending Remarks

Hopefully, you gained some know-how on components that are controlled by PWM. The takeaway message was that the width of the pulse will determine the speed for the motor (for drone motors). You can now quickly test components with servo tester and write custom programs with Arduino. In particular, you have all the basics to control the ESC+BLDC motor setup for drones. For future reference, I have collected all these scripts HERE

Some of you might ask, why have Arduino in between, how about controlling ESC+BLDC with directly with your PC (or phone). This is definitely possible but is like using Nuclear Missiles to kills ants. Most of the modern motherboards do not have a PWM generator, mainly because the market does not demand this. But the sanest way to accomplish this is to get yourself a USB-TTL device and connect to your Arduino as a serial device and code up device drivers. Click HERE for more of my thoughts on this.

If you find any mistakes in this post or its associated videos, please do correct me. I would appreciate a comment if you find this post helpful. If you do have any questions regarding this post, do not hesitate to contact me via your comments.

Leave a Reply

Please log in using one of these methods to post your comment:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s