Servo Motor Control with AndroiDAQ

Servo motors are common motion control actuators that are used in robotics, radio controlled devices, 3D printers, and other motion drive systems. Using servo motors with AndroiDAQ is easy. This article contains a brief history of the servo motor, some basic operational background for servo motors, and how to connect and use a servo motor with the AndroiDAQ data acquisition and control module. 

 

The steam engine governor is considered to be the first servo mechanism using a powered feedback system. Its first recorded use was in 1868, by JJL Farcot, who described steam engines and hydraulics for use in steering a ship. Servo mechanisms are considered to be closed-loop systems, as the mechanism uses position feedback to control its motion and final position. 

 

A Servo Motor consists of three major parts: a motor, a controller circuit, and a feedback system, which usually consists of a potentiometer which is connected to the motor’s output shaft. The motor typically drives a set of gears, which turns the output shaft of the motor and the potentiometer simultaneously. The potentiometer’s measured resistance controls the output angle of the motor shaft. This resistance is fed into the servo controller circuit and when the controller circuit detects that the motor position is correct, it stops the servo motor. If the controller circuit detects that the angle is not correct, for whatever the motor it trying to control, it will turn the servo motor the correct direction until the angle is correct. Normally a servo motor is used to control an angular motion of between 0 and 180 degrees. They typically can not turn any further unless they are modified, due to a mechanical stop which is build onto the main output gear or the potentiometer itself. Servo motors are generally used as a high performance alternative to the stepper motor. 

 

Servo motors are controlled by sending to the servo’s control wire a pulse train of variable width, or better, a pulse width modulated signal. This pulse train has to have specific parameters such as a minimum pulse, a maximum pulse, and a repetition rate. This signal is typically derived and sent to the servo control wire by a microcontroller such as the one on AndroiDAQ. The shaft angle of the servo is determined by the duration of the pulse train sent. Given the pulse train’s constraints of having a minimum pulse, a maximum pulse, and a repetition rate, a neutral position is defined. This neutral position is where the servo has exactly the same amount of potential rotation in the clockwise direction as it does in the counterclockwise direction. This neutral position is typically always around 1.5 milliseconds. 

 

Now let’s tackle connecting a servo motor to the AndroiDAQ module. For this article we will use Parallax’s standard servo motor which is available here: http://www.parallax.com/product/900-00005. This servo motor has three wires which are used to power and control the servo. The black wire is connected to ground, the red wire is connected to a power source, which is typically an external power supply due to the current spikes that occur when operating a servo under load, and the white wire, which is used to control the servo’s angular motion via the pulse train described above.

 

Below is a diagram to help you in connecting your servo motor to the AndroiDAQ module. Where we are testing this servo circuit without any load on the servo motor, we are connecting the servo’s red power lead directly to AndroiDAQ’s auxiliary 5-volt DC source pin. This 5-volt source from AndroiDAQ can supply up to 750-milliamps of power. When you are ready to place a load on your servo motor, for example to control a pan and tilt camera head, we suggest that you use an external power supply for servo operations. For this example we are using I/O pin 13 of the AndroiDAQ module, but you can use whichever I/O pin on AndroiDAQ module that you desire, as long as you remember to change the I/O pin number to correspond to your pin number in the firmware code. You will also note that we connect the white wire from the servo to the AndroiDAQ module with a 470-ohm resistor. This resistor limits the current draw from the servo motor connection, protecting the AndroiDAQ I/O pin from excess current draw. 

 

AndroiDAQ Connections to ServoFigure 1 Servo connection with AndroiDAQ

 

At the heart of any microcontroller project is the microcontroller firmware. AndroiDAQ was designed to allow you to easily modify its firmware using Parallax’s Propeller Tool, available here:

http://www.parallax.com/downloads/propeller-tool-software

We know that servo motors are controlled by sending to the servo’s control wire a pulse train of variable width or a pulse width modulated signal. From the servo motor data sheet (see: http://www.parallax.com/sites/default/files/downloads/900-00005-Standard-Servo-Product-Documentation-v2.2.pdf) we read that “the Parallax Standard Servo is controlled through pulse width modulation, where the position of the servo shaft is dependent on the duration of the pulse. In order to hold its position, the servo needs to receive a pulse every 20 ms.” So for the 0 to 180 degree range of motion, it takes a pulse-width modulated signal of 0.75–2.25 milliseconds of high pulses, and then to hold that position repeat this pulse train at 20 millisecond intervals. We could derive an algorithm in the firmware which sends x amount of pulses with a pulse width of y, and repeat the sending of this pulse train every 20 milliseconds. For example, we could send pulses with a 2-millisecond width, every 20 milliseconds, which would move the servo to approximately the 10 o’clock position. The same holds true if we send pulses with a 1.5-millisecond width, every 20 milliseconds, which would move the servo to approximately the center position, or if we send pulses with a 1.0-milli-second width, every 20 milliseconds, which would turn the servo to approximately the 2 o’clock position (see code snippet below).  

 

PUB ServoMove

   servoPin := 13                                            ' set I/O location of control wire on servo

   outa[servoPin] := 0                                     ' set servoPin to low

   dira[servoPin] := 1                                      ' make servoPin an output

   repeat

      outa[servoPin] := 1                                  ' set servoPin to high

      waitcnt((clkfreq/10000) * 15 + cnt)            ' wait 1.5m

      outa[servoPin] := 0                                  ' set servoPin to low

      waitcnt((clkfreq/1000) * 20 + cnt)              ' wait 20ms

 

This is all well and good though there is an easier way. Parallax has a user exchange library where community members share "open source" objects and snippets that are written for Parallax Semiconductor's Propeller microcontroller.  This OBEX exchange library is at: http://obex.parallax.com/content/welcome-new-obex. Doing a quick search on the OBEX site for servos, we find that there is a little subroutine called the PWM2C Servo Engine.spin by Kwabena W. Agyeman. With this servo engine, one only has to send the desired position, in milliseconds, and this driver takes care of the pulse train timing and math for you. This subroutine also has the ability to control two servos at once.

 

When using this subroutine, if you want to have the servo move to the centered position, you send the subroutine a 1500, or to move to the 2 o’clock position send a 1000, or to move to the 10 o’clock position a 2000, etc.. This spin subroutine is now included in the AndroiDAQ firmware. Under the AndroiDAQ firmware, one only needs to Start the Servo engine and then send to the left or right servo, depending on if you are using one or two servos, a leftPulseLength(milliseconds) or rightPulseLength(milliseconds) command for the desired position. We have implemented this servo engine in the newest version of the AndroiDAQ firmware such that millisecond commands are only required that can be sent via USB, Wi-Fi, or Bluetooth. An example command to move the servo using Parallax Serial Terminal would look like this: 014\r 01500\r. Here the 014 tells AndroiDAQ that you will be moving the servo (menuloop item 14) and the 01500 tells the AndroiDAQ module the desired position (setting) to move the servo. A zero always precedes an AndroiDAQ command to tell the MenuLoop that a command is following the zero. A “\r” or carriage return is always send after a command to tell AndroiDAQ look for the next sequence in the command.

 

PUB MoveServo

''Move Servo motor to setting (1500 is 90 degrees)

  servoPin := 13

  SERVO.SEREngineStart(servoPin, -1, 50)  ‘Start Servo Engine

  menu := 0

  repeat

    menu := debug.rxcheck                              ‘Look for setting coming from UART

    if menu > 0

        setting := debug.GetDec                        ‘ Get setting from UART  (750-2250 range)

        SERVO.leftPulseLength(setting)          ‘ Move Servo to setting

        quit                                                         ‘ Quit

  SERVO.SEREngineStop

 

This article describes servos motors and how simple it is to use servos with the AndroiDAQ module. Please look for future articles which will provide instructions on how to use stepper motors with the AndroiDAQ module. Stepper motors are also quite easy to use with the included Stepper motor driver in the AndroiDAQ firmware. We will then combine the servo and stepper motor operations with AndroiDAQ and then create a simple webcam pan and tilt mechanism that can be used for following and targeting a subject in the cameras field of view using OpenCV.

We invite you to read more about the AndroiDAQ data acquisition module for Android, LabVIEW, JAVA, and Python: About the AndroiDAQ module.

 

AndroiDAQ with xBee WiFi module