My Android Things

Android Things Tutorials (IoT)

Tutorial 10 : Controlling a servo motor using Android Things

What is Servo Motor:
A Servomotor, or servo, is a small device that has an output shaft. This shaft can be positioned to specific angular positions by sending the servo a coded signal. As long as the coded signal exists on the input line, the servo will maintain the angular position of the shaft. As the coded signal changes, the angular position of the shaft changes. We have precise control on servo motor in terms of angular position, acceleration and velocity, capabilities that a regular motor does not have

(Servo Motor)

Servos are extremely useful in practice. They may be used to operate remote-controlled toy cars, robots, or airplanes. Servos are also used in industrial applications, robotics, in-line manufacturing, pharmaceutics, and food services.

How is a Servo Controlled?
Servos are controlled by sending an electrical pulse of variable width, or pulse width modulation (PWM), through the control wire. There is a minimum pulse, a maximum pulse, and a repetition rate. A servo motor can usually only turn 90 degrees in either direction for a total of 180 degree movement. The motor’s neutral position is defined as the position where the servo has the same amount of potential rotation in the both the clockwise or counter-clockwise direction. The PWM sent to the motor determines position of the shaft, and based on the duration of the pulse sent via the control wire; the rotor will turn to the desired position. The servo motor expects to see a pulse every 20 milliseconds (ms) and the length of the pulse will determine how far the motor turns. For example, a 1.5ms pulse will make the motor turn to the 90-degree position. Shorter than 1.5ms moves it to 0 degrees, and any longer than 1.5ms will turn the servo to 180 degrees, as diagrammed below:


When these servos are commanded to move, they will move to the position and hold that position. If an external force pushes against the servo while the servo is holding a position, the servo will resist from moving out of that position. The maximum amount of force the servo can exert is called the torque rating of the servo. Servos will not hold their position forever though; the position pulse must be repeated to instruct the servo to stay in position.

What is PWM?
A Pulse Width Modulation (PWM) Signal is a method for generating an analog signal using a digital source. A PWM signal consists of two main components that define its behavior: a duty cycle and a frequency. The duty cycle describes the amount of time the signal is in a high (on) state as a percentage of the total time of it takes to complete one cycle. The frequency determines how fast the PWM completes a cycle (i.e. 1000 Hz would be 1000 cycles per second), and therefore how fast it switches between high and low states. By cycling a digital signal off and on at a fast enough rate, and with a certain duty cycle, the output will appear to behave like a constant voltage analog signal when providing power to devices. Below you can see an example of a 50% period signal. 


Below are some graphs demonstrating PWM signals with different duty cycles:

(25% Duty Cycle)


(50% Duty Cycle)



(75% Duty Cycle)

The PWM signals can be used for applications such as controlling the speed of DC motors, changing intensity of an LED, controlling Servo motors, etc.

The GIF shown below depicts the use of PWM for intensity control of an LED:



Raspberry Pi and PWM:
Raspberry Pi has two PWM channels i.e. PWM0 and PWM1.

PWM pins for the two PWM channels on 40-pin P1 header are as follows:

GPIO Pin

PWM0/PWM1

GPIO12

PWM0

GPIO18

PWM0

GPIO13

PWM1

GPIO19

PWM1

 

The PWM pins on Raspberry Pi 40-pin P1Header is shown in below figure,


(Raspberry Pi PWM Pins)


Hardware Requirement for our Recipe:
  • 5V servo motor
  • Breadboard and jumper wires
  • 1kO resistor
  • 5V outside power supply for Servo
  • Raspberry PI
The 1kO resistor is not essential, but it does protect the GPIO pin from unexpectedly high currents in the control signal, which could occur if a fault developed on the servo.

Hooking up the Servo:
In servo motors their are generally three cable output, and their use is as following:

We will connect these cable On the raspberry as following:
  • Servo red wire to 5v
  • Servo brown wire to 0v
  • Servo orange wire to Pi’s PWM0
We will not plug these cable directly to raspberry pi, as we will use outside powersource to power our servo motor. So connect the setup like this:


Programming It:

Create a new project as "MAT10" with "Android Things" template. There is no need to select UI layout file while creating project. 

Open up MainActivity.java and add the following static and member variables at the top of the class and resolve the dependencies to PWM:

private static final String TAG = "MAT10";
private static final String PWM_PIN = "PWM0";
private Pwm mPwm;
int i;
Timer t;

Change the onCreate method so it opens up a new connection to our PWM0 pin and Create a timer to move our servo motor every 3 seconds repeatedly.
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
i = 0;
PeripheralManagerService pms = new PeripheralManagerService();
try {
mPwm = pms.openPwm(PWM_PIN);
mPwm.setPwmFrequencyHz(50);
} catch (Exception es) {

}

t = new Timer();
t.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
NextMove();
}
}, 0, 3000);
}

In the above case we have instantiated the PWM module with a frequency of 50Hz. That frequency was selected because the servo motor expect a pulse every 20ms (period), that means 50 pulses per second or Hertz.

Now, to set the angle of the servo, we need to send a specific signal to it (Duty Cycle). This can differ from servo to servo, as normally it's from 2.5-12.5%, or 2-12%. Regardless, it will be a 10% window, And we know that for 0 degree angle we need .5ms duty cycle, for 90 degree angle we need 1.5ms duty cycle and for 180 degree angle we need 2.5ms duty cycle. We can calculate these as:



Otherwise if you want to calculate the duty cycle for your desired angle, divide by 18, then add the lowest available value, like 2.5
So, for 90 degrees, divide by 18, which is 5, then add 2.5, and you get 7.5. So on this servo 7.5% duty is 90 degrees. So either ways, you can get the desired duty cycle for your required angle.

Now we will use these duty cycle to swing servo arm by 0 degree, 90 degree and 180 degree every 3 seconds with the use of our timer defined in oncreate. Write following methods:
private void NextMove() {
switch (i % 3) {
case 0:
Swing0Degree();
break;
case 1:
Swing90Degree();
break;
case 2:
Swing180Degree();
break;
}
i++;
}

private void Swing0Degree() {
try {
mPwm.setPwmDutyCycle(2.5);
mPwm.setEnabled(true);
Log.e(TAG,"Swing0");
} catch (Exception ex) {

}
}

private void Swing90Degree() {
try {
mPwm.setPwmDutyCycle(7.5);
Log.e(TAG,"Swing90");
} catch (Exception ex) {

}
}

private void Swing180Degree() {
try {
mPwm.setPwmDutyCycle(12.5);
Log.e(TAG,"Swing180");
} catch (Exception ex) {

}
}

Also don't forget to close PWM pin in onDestroy.

Party time

Run the app on your Raspberry Pi by pressing run button on your Android Studio, you servo will start making swings every three seconds.


Final Run


Download Project Source
MAT10.zip (58.9KB)

Add comment

Loading