# Beaglebone Black LESSON 12: Control a Servo from Python Using PWM

This lesson will show how to use Python running on the Beaglebone Black to control the position of a servo. First, I am using a small servo that I have verified can be powered from the Beaglebone Black without drawing too much current. All servos are different, so if you are unsure of the current requirements of your servo, it is safest to power it from an external 5 Volt power source. You can still control it through the control line connected to the Beaglebone Black, just make sure the servo and Beaglebone have a common ground.

Most all servos have three wires; Power, Control, and Ground. For my servo, Control is Yellow, Power is Red, and Ground is Black. If you have a different servo, check the data sheet to see what colors are Control, Power and Ground on your servo. Note we are using pin P9_2 as ground, P9_7 as 5V power, and P9_14 as our control pin.

We will be controlling the position of the servo using PWM. We will have to play around with our individual servo to determine precisely what signal pulse width will result in the servo being in the full left position, and what pulse width will result in the servo being in the full right position.

For most servos, full left is somewhere around 1 milliseconds, and the pulse width that will give us full right position is about 2 milliseconds. These are ballpark numbers, and we will have to play around with things to find the exact values for our servo.

We will set up a 50 Hz PWM signal. A 50 Hz signal has a period of:

period = 1/frequency = .02 seconds = 20 miliseconds.

Hence, if we want to get to about the full left position we would want a duty cycle of about 5%. Because 20 milliseconds x .05 = 1 milliseconds. This one millisecond pulse width should put the servo about in the full left position. Similarly for the full right position, we would want a duty cycle of 10%, because that would give us a pulse width of 2 milliseconds, since:

PulseWidth = Period x DutyCycle

PulseWidth = 20 x .1 = 2 milliseconds.

We can use the following code to determine precisely for our servo what dutyCycle will give the precise full left and full right positions.

For my servo, running a 50 Hz PWM singnal, I find that a duty cycle of 2% puts it in the full left position and a duty cycle of 12% puts it in the full right position.

Now we would like to be able to just specify an angle we want and have it go to that angle. If we want an angle of 0 degrees we would apply a 2% duty cycle. This value is for my servo. You will have to play around with your servo and the code above to find what this number is for you. But for me, I have the point:

(0,2)

That is to say when I desire an angle of 0 on the servo, I should apply a dutyCycle of 2 to the PWM pin. Similarly, when I desire 180 degrees, I should apply a dutyCycle of 12. (Again, this number might vary for your servo). For my servo, I get the point:

(180, 12)

We can fit a line to these points, which would then allow us to calculate the dutyCycle for any desired angle. The slope from the two points above would be:

m=(y2-y1)/(x2-x1)=(12-2)/(180-0) = 10/180= 1/18

Using the point slope form of the line, we would get

y-y1 = m (x- x1)

y – 2 = 1/18( x – 0)

y= 1/18*x + 2

Now putting in our actual variable names we get:

dutyCycle = 1/18*desiredAngle + 2

You can develop the same type equation just using the values suitable for your servo from the experiment above.

Now we can use this code to smoothly move the servo to any desired position.

# Raspberry Pi LESSON 28: Controlling a Servo on Raspberry Pi with Python

In this lesson we will show you how to precisely control a Servo using the Raspberry Pi. First, for the small servo I am using, I have verified that it is safe to drive from the 5 volt pin (physical pin 2) on the Raspberry Pi. It is possible to damage your Raspberry Pi by drawing too much current out of a pin. So, if you are not sure about the current requirements of your Servo, it is best to power it from a 5 Volt source other than a Raspberry Pi pin. You can still control it from the Raspberry Pi if you use a common ground, but just get the power (red wire) from an external source. For my small servo, I can safely power it from Raspberry Pi physical pin 2.

The second point is that to control the servo, you have to use Pulse Width Modulation. So, I STRONGLY recommend that you go through LESSON 27 if you have not already. Lesson 27 shows you how to use PWM on the GPIO pins on the Raspberry Pi. If you are up to speed on PWM, this lesson will go a lot easier.

So, with that out of the way, we are ready to hook up our servo. For my servo, the ground wire is Black, the Red wire is 5 volt, and the yellow wire is the control line. If you are using a different servo, you will need to read the instructions to see what the color code is for your three wires, but it is likely similar to mine. The sketch below shows how you should hook the servo up. Notice I have the 5V hooked to the Pi physical pin 2, the servo ground hooked to the Pi physical pin 9, and the servo control line hooked to the Pi physical pin 11.

Now with the Servo hooked up, we are ready to try and control it. For this example, we will work in the Python shell. To enter the python shell, open a Terminal window, and at the command prompt type:

\$sudo python

It is important to include sudo, as the Raspberry Pi only allows access to the GPIO pins to the superuser. Hence, you need to enter the python shell as a superuser. When you type the command above, you should be moved into the Python shell, and should see the python shell prompt of >>>.

We are now ready to control the servo. We must first import the RPi library. These first steps should be familiar if you did LESSON 27.

>>>import RPi.GPIO as GPIO

Now we need to tell the Pi what pin numbering scheme we want to use. I like to use the physical pin numbers (See LESSON 25 for a diagram). So, we need to issue the command:

>>>GPIO.setmode(GPIO.BOARD)

Now we need to tell the Pi that physical pin 11 will be an output pin:

>>>GPIO.setup(11,GPIO.OUT)

The servos position is controlled by the pulsewidth of a 50 Hz PWM signal. Hence, we need to turn the PWM sequence on at 50 Hz. Note that for a 50 Hz signal, the Period of the signal is 1/50=.02 seconds, or 20 milliseconds. Keep this Period in mind as we will come back to it later. We start by creating a PWM object on Pin 11 with a 50 Hz signal with the command:

>>>pwm=GPIO.PWM(11,50)

We can now start the pwm sequence by giving a command to specify the DutyCycle of the signal. Before we do this, we need to talk a little bit about how servos work. A typical servo wants to see a frequency of 50 Hz on the control line. The position it moves to depends on the pulse width of the signal. Most servos behave roughly as such, but you will need to tweak these numbers for your particular servo. Typically, the servo will go to the full left position when it sees a pulse width of 1 millisecond, it will go the middle position when it sees a pulse width of 1.5 millisecond, and it will go to the full right position when it sees a pulse width of 2 millisecond. Note however, that on the Raspberry Pi we do not specify a pulse width, but we specify a DutyCycle. So, we can use the following relationship:

DutyCycle =PulseWidth/Period

Remember that Period = 1/frequency, so:

DutyCycle = PulseWidth/(1/frequency) = PulseWidth * frequency

The PulseWidth that will give us a full left position is 1 milllisecond. We now calculate the applied DutyCycle to give us the desired position:

DutyCycle = PulseWidth*frequency=.001 *50 = .05 = 5%

So, for a 50 Hz signal, if we set the DutyCycle to 5, then we should see the servo move to the full left position. Similarly, if we set DutyCycle to 7.5, we should get the middle position, and if we set it to 10 we should be in the full right position. You can get all the intermediate positions by linearly scaling between 5 and 10. Note that these values will vary between brands, and between individual servos, so play around with your servo to get it calibrated. We are now ready to apply a command to position the servo. If we want the servo in the full left position, we should set the DutyCycle to 5%. We do that with the command:

>>>pwm.start(5)

This will start the PWM signal, and will set it at 5%. Remember, we already specified the 50 Hz signal when we created the pwm object in our earlier commands. Now if we want to change the position, we can change the DutyCycle. For example, if we want to go to the middle position, we want a DutyCycle of 7.5, which we can get with the command:

>>>pwm.ChangeDutyCycle(7.5)

Now if we want the full right position, we want a duty cycle of 10, which we would get with the command:

>>>pwm.ChangeDutyCycle(10)

Remember, it is not DutyCycle that actually controls servo position, it is PulseWidth. We are creating DutyCycles to give us the desired PulseWidth.

Now, play around with your particular servo and then find the specific DutyCycles that lead to full left and full right positions. For my servo, I find that full left is at DutyCycle=2, and full right is at DutyCycle=12. With these values, I can create a linear equation that will give me any angle I want between 0 and 180. This will make the Raspberry Pi behave much more like the simple and intuitive operation of the Arduino.

To do the linear equation I need two points. Well, I know that for a desired angle of 0, I should apply a DutyCycle of 2. This would be the point (0,2). Now I also know that for a desired angle of 180, I should apply a DutyCycle of 12. This would be the point (180,12). We now have two points and can calculate the equation of the line. (Remember, play with your servo . . . your numbers might be slightly different than mine, but the methodology below will work if you use your two points)

Remember slope of a line will be:

m=(y2-y1)/(x2-x1)=(12-2)/180-0)=10/180 = 1/18

We can now get the equation of the line using the point slope formula.

y-y1=m(x-x1)

y-2=1/18*(x-0)

y = 1/18*x + 2

Putting in our actual variables, we get

DutyCycle = 1/18* (DesiredAngle) + 2

Now to change to that position, we simply use the command:

pwm.ChangeDutyCycle(DutyCycle)

I hope this makes sense. Watch the video as I step you through it carefully. If the writeup above does not make sense, hopefully the video will clear things up.

# LESSON 18: Distance Meter Using Ultrasonic Sensor and Arduino

In Lesson 17 we learned to use an ultrasonic sensor to measure the speed of sound. There is a different way to use the sensor. Since we know the speed of sound, we can use it to measure distance, since d = r*t (distance = rate * time). You know the rate, that is the speed of sound. You can measure the ‘time’ using the ultrasonic sensor, just as you did in Lesson 17. This is the time for a ping to go from the sensor to the target and back. Knowing this, you can then calculate the distance to the target.

For you hackers, just jump right in and do the assignment. You should be able to do it with what you have already learned. What I want you to do, though, is come up with some creative way to display the distance . . . something better than just printing it on the Serial Monitor. I will make a scale and display it using a servo. You can do whatever you think would be most interesting. For those who need a little extra help, I will step you though my project below.  The first thing you need is to hook up your circuit. I have the sensor hooked up like in Lesson 17 and have added a servo. The servo black wire needs to hook to ground, the red wire to 5V from the arduino, and the white wire, which is the control wire, I have hooked to pin  6 of the arduino. Remember that you need to verify that your servo will not draw too much current from the Arduino. The servos in the Sparkfun Inventor Kits work fine, and can be driven directly from the arduino 5V power pin.  Also, your servo might have different colored wires. Many have Red for power, Orange for control , and Brown for Ground.  Always confirm the color code with the data sheet for the specific servo you are using. Also, remember that before using a servo, you need to determine its suitable range of motion. This was explained in Lesson 16.  For my project, I am using the following schematic. It would be better to hook to the ultrasonic sensor by putting the wires behind the sensor, so they do not interfere with the ‘ping’ coming from the front. I drew them in front so you could see them clearly, but wire them on the back side of the sensor.

When you get your circuit set up, we will need to do some math. Our objective is to measure distances between 0 and 7 inches. This sensor could probably do a good job measuring distances up to three feet, but for this project we will focus on 0 to 7 inches. We then want to put a pointer on the servo, and have it point at a scale that will indicate distance. Since the servo swings in an arc, we can best thing about the output of the servo as an angle. On the scale I draw, I want to have the numbers be between angles of 37 degrees and 143 degrees. For a distance measured of 0 inches, I want the servo to point at 37 degrees. For a distance measured of 7 inches, I want to point to 143 degrees. Then, everything should scale between those numbers.  You can see that I drew my scale for my servo above on a piece of polar graph paper. Polar graph paper makes it easy to draw specific angles and ranges of angle. You can print your own polar graph paper at HERE.  Now, the math that has to be done is to calculate the angle you should set your servo at based on what distance measurement you are reading. The numbers have to match the scale you draw for the servo. For mine, I want a measurement of 0 inches to put the servo at 37 degrees, and a measurement of 7 inches to put the servo at 143 degrees. These match the positions of the ‘0’ and ‘7’ on my scale. By this time you should be comfortable doing the math, but if you need help, you can check my notes below.

You will need to draw our own servo scale. You can arrange the scale however you like, but in the end, you have to do the math so that your servo points at the right distance number on your scale.

With that out of the way, we now need to do the coding. There is not really anything new to learn as far as coding goes. This is really a combination of what you learned in lesson 16 and lesson 17.  In this project though, instead of measuring the speed of sound, we will be measuring the distance to a target, given the known speed of sound. Then we use the math above to calculate where to point the servo. The video above will take you through the code step by step, but I include the code below. You should not copy and paste the code, but just look at it if you get stuck. For those of you in my class when I check you project for a grade, I will be looking to see if you are working independently, or just copying what I am doing.

Now your assignment is to come up with a new and different way to display the distance. On this new assignment measure distances between 0 and 18 inches. Figure out a cool way to convey that distance to the user. Think of a good idea. If you are having trouble coming up with an idea, maybe build a bar graph with 10 LED’s, and the number of lit LED’s indicating distance. In any event, you will need to do your math on the project, and an important part of the grade is showing me your graph where you map your output values onto your input values, like I did above.

# LESSON 16: Controlling a Servo with Arduino

Its time to get moving! In this project we show you how to get things moving with Arduino. You will need an arduino, a servo, a potentiometer and some wires. If you have the sparkfun inventor kit, it has everything you need (You can pick up the inventor kit HERE).

For this project, our objective is to control the position of a servo based on the setting of a potentiometer. The servo should “track” the position of the potentiometer. In order to do this, we will need to start with our Voltage Divider Potentiometer circuit from LESSON 10. In addition, we will need to hook the servo up. for the servo in the sparkfun kit, it has three wires . . . red, white, and black. The red line is for power, so it should be hooked up to 5V from the arduino. The black line is ground, and should be hooked up to ground on the arduino. The white line is the control line, and it should be hooked up to one of the arduino pins with a squiggly line.  For this example, I am using pin 9. The small servo that comes with the sparkfun kit can be powered directly from the arduino. Understand that many servos draw lots of power, and require a separate power supply, and just the control line connects to the arduino. Realize that you must be careful and not hook a larger servo to the arduino for power, as that can damage your arduino. The one in the sparkfun kit can be driven by the arduino without a problem.  Also, some servos have a different color code on the wires. Many have red/orange/brown wires. For many of these types, the red is for power, the orange is for the control line, and the brown is for ground. Be sure to check the instructions on your servo to verify the color code.  As a reminder, this is circuit diagram for the potentiometer, which you will be using in this project.

Most servos are designed to be operational in a range from 0 degrees to 180 degrees. The truth is though, that most will not operate over that full range. Also, you need to know that overdriving the servo beyond the range it wants to be in can damage both your arduino and your servo. Each servo is different, and sometimes two servos with same model number from the same manufacturer will have different ranges. Especially in the cheap ones (like in the sparkfun kit) have very different ranges.

So before going to far in any project you need to determine the range that your particular servo will operate in. In order to do this we need to write a simple program that will move the servo. In order to control the servo from the arduino, there are several things that must be done. The first is that you must “load” a library. A library is a special set of code written by the folks who make or sell the device in order to make it easier for you to work with. Libraries allow us to work with components in a more intuitive way. For the servo, you need to load the servo library, which comes with the arduino software you originally downloaded. To load the library, you need the following code at the top of your program:

Then, you need to create a servo “object”. This object will then be something you interact with to make the servo move. You can all the object anything you want, but I think I will call mine “myPointer” since I am going to make my servo point at things. The code to create the servo object would then look like this:

OK, now to make the servo go to a certain position, I would just have to issue a command like this:

This command goes to ‘pos’ which should nominally be between 0 and 180.  But remember that most servos will not go over that full range, so we will need to play around to see what range our servo can safely achieve. Also, the short 15 millisecond delay after moving the servo gives it time to get there and settle down. Never try and write the servo faster than it can naturally move.

The one other thing you need to do is let the arduino know which pin the servo is connected to for the control line. We are using pin 9, and will set up a variable at the top of the code to set servoPin=9, but it can be any pin that can analogWrite (one with a squiggly line).  To tell your arduino where the servo is connected, for the case of my servo which I names myPointer, the following code should be put in the void setup:

What you need to do now is write a program that will input the user for a position, and then write that position to the servo. The purpose of this is to determine the natural range of your particular servo. You should write this program yourself, but if you get stuck you can look at my code below. You should use this as a help if you need it, but your should not cut and paste it. Write your own code!

OK, with this code we should see the arduino prompt the user to a position and then write that position to the servo. The thing to do with this code is play around and figure out what range of motion your arduino can achieve. If you arduino sits and twitches, you have probably overdriven it. Keep playing with the numbers until you determine the range your servo can sweep to without jittering.

Once you know that range, you can play around with the code and the servo. Create a program that will smoothly sweep the servo through its range of motion. For my servo, I created the following code. Again, play with it yourself, and use this code only if you get stuck. Also, realize that my servo operates from 15 to 170 degrees, so that is why I used those numbers. You need to determine the range of motion for your servo, and use those numbers in the program.

Now we need to write a program that will set the position based on the position of the potentiometer. We want the servo to point to the left if the potentiometer is positioned all the way to the left. Similarly we want the servo to point to the right if the potentiometer is all the way to the right. We need to do the math carefully to make sure that we do not try and overdrive the servo.  You must assume the user has no knowledge of servos and will turn the potentiometer to any position. In order to make sure the servo is not over-driven, you must carefully do the math. For this case, what is the independent variable? It is the number coming off the potentiometer. That is what you or the user “sets”, that is the independent variable, that is the horizontal axis. Now, what is the dependent variable? That is the pos (position) number. That is what you want to calculate from the independent variable. To do the math, think about the two points you know. You know that the potentiometer reads from 0 to 1023. You know that for my servo (yours will be different) the range of useful motion is from 15 to 170. So, when the potentiometer is set to 0 we want the position to be 15. There, you have one point, the point (0,15). Now we also know that when the potentiometer reads 1023, we want to position the servo at 170. So, now we have another point, the point (1023, 170). Now we have two points and can create the equation that will allow us to calculate the Pos based on the reading from the potentiometer. You should be able to do this by yourself now, but if you get stuck you can look at my notes. Remember, you need to do it for your values of useful range on the servo, not my numbers of 15 and 170.

So with this equation you can now calculate a pos for the servo based on the reading from the potentiometer. You should be able to write the code now to control the servo position from the potentiometer. If you get stuck watch the video that provides step-by-step directions on the code.