Servo Motors, or simply servos, are integrated motors that contain their own power and control circuitry. They're generally available in two flavors: positional or angular. Servos can be accurately driven to specific angles and are often used in radio control equipment for control surfaces and steering. You'll also see them in robotic arms. Continuous rotation or 360 degree servos are essentially a motor with a speed and direction control in a handy package.
G'day, I'm going to show you how to get started with the PiicoDev Servo Driver so you can control up to four Servo Motors using a Raspberry Pi Pico. The PiicoDev Servo Driver features the standard PiicoDev connectors for daisy-chaining to other modules, there's four servo channels, a high-power input for providing power to the servos, a power LED to let you know that it's on, and an address switch. This address switch allows you to add up to three additional Servo Drivers to the same PiicoDev bus. For now, make sure both these switches are in the off position.
To follow along, you'll of course need a Raspberry Pi Pico, PiicoDev expansion board and Servo Driver, and a PiicoDev cable to connect all this hardware. You'll need a power supply to power the servos and of course you'll need at least one servo. For this tutorial, we'll work with this positional servo and this continuous rotation servo.
Servos are usually packaged with some assorted mounting hardware. These are the servo horns and some fasteners to hold them on and secure the servo. You can even get some special servo wheels which are great for continuous rotation servos. For now, pick your favourite servo horn, press it onto the splined shaft, and secure with a screw.
There are four servo channels labelled one through four. Connect your servo to Channel One.
Connecting a three pin connector with connections for ground power and signal on the server driver is easy. These are labelled negative, positive, and Sig respectively. Make sure you connect your server correctly as they may be damaged if you plug them in the wrong way around. Your server may have different colored wires to this one. In general, the darkest wire is the negative wire. You can also identify the negative wire on the server connector itself. It's indicated by a small facet or chamfer that runs along one edge of the connector. That's the negative pin.
Plug the Pico into the expansion board, making sure it's the right way around. Plug in your PiicoDev cable and connect the other end to your Servo driver. Connect to your computer with a USB cable and connect power to your Servo driver.
A note about power: servers can be really power hungry. The regular PiicoDev bus and cables simply can't provide enough current to drive these motors. So, we'll need to connect an external power supply via one of the USBC connectors. Exactly how much current your project really needs depends on how many servos you drive at the same time, how big those servers are, and how much torque they need to deliver. A good starting point is to budget about 0.7 amps per small Servo at about 2.4 amps for a large Servo.
We're going to work with phony for this tutorial. If you haven't used Thonny and Raspberry Pi Pico before, check the article for help getting started. Find the download section in the article, right click PiicoDev unified.py and save link as. I'm going to save this file to a PiicoDev directory in my documents and do the same for PiicoDev servo.py. Open funny, connect to your Pico, and upload those two files.
Back in the article, this first example will be for a positional or angular server. If you're working with a continuous rotation server, here they are. loop and then inside that loop we could set the servo.angle to something like X times 10 and then we could have a delay of one second and then we could increment X by one
We'll get to that one next. Find the Angular Servers example and copy and paste all of that code into Thonny. Click the Green Run button and when prompted to save, I'll save this to my Pico as main.py. And the server has sprung to life. Cool! This little routine is stepping the server between three positions, back to the start and then it slowly sweeps it, so we've got some stepping and some smoother sweeping.
Let's take a closer look at the code. We start by importing a sleep function to create a delay and then from the PiicoDev Server module we import the Servo and the Servo Driver. We call the Server Driver initialization function which returns a Driver object and we call that controller. So when you see controller in this script, we're referring to this physical PiicoDev Servo Driver.
Next, we initialize the servo. So, we call the PiicoDev Servo initialization function and we need to tell that what controller it's connected to and the channel number. We are connected to our controller which is the only server driver we have connected and we're plugged in to channel number one. This returns a Servo object that we call servo. So, where you see Servo in this script, we're referring to this physical server.
Now, driving the server to different angles is as easy as writing the servo.angle attribute. We set the server angle to zero, there's a delay for a second, we set the server angle to 90-degrees, another delay, we set the server angle to 180-degrees and after another delay it goes back to zero. So, that's that stepping behavior at the start of the script.
Next up, we have the sweeping behavior and for that we use a loop. We say for x in range zero degrees to 180-degrees in steps of 5-degrees, we set the servo angle to x and there's a very short delay.
And so, to remix this code, we could just create a while true loop and then inside that loop we could set the servo.angle to something like x times 10 and then we could have a delay of one second and then we could increment x by one. speed to a value of 50 and that's causing the server to spin at a speed of 50
We can set up a loop while true so that the angle equals zero and the server angle equals 90. This will just drive the servo back and forth forever. Not all servos behave in exactly the same way depending on different manufacturers. They may require certain signal characteristics from the servo driver when we initialize a server. In this way, we are initializing it with very common and generally pretty safe parameters. However, if you find your server makes a grinding sound, you may need to change the timing information on how it's driven.
If we comment out this line of code and uncomment this line of code, this is a more explicit way to set up the server. We are still on controller channel one, but now we have some extra information. These parameters Min us and Max us describe the pulse length in milliseconds that the server is expecting to be driven by. Servers are driven by pulses and those pulses have lengths. In general, 600 microseconds is a pretty common minimum pulse length and 2400 microseconds is a pretty common maximum pulse length, but you can update these from your server manufacturer's data sheet if you need to.
Not all angular servers are 180-degrees. For example, this larger servo is a 270 degree server. To make the most out of your servo, you may have to update the degrees property as well. I'm going to unplug my positional server and swap in my continuous rotation server.
I'll add all of that code and paste it back into Thonny. I'll paste over everything in Main and click the Green Run button. Our continuous servo springs to life. It's easiest to drive continuous servers using the speed attribute. You can see this script is setting continuous server dot speed to a value of 50 and that's causing the server to spin at a speed of 50.
We can control the speed of a servo by setting the speed to a value between -1 and 1. A value of 1 is the fastest, and 0.2 is the slowest. We can reverse the servo by setting the speed to a negative value, and come to a complete stop by setting the speed to 0.
You might find that at the end of the script, your servo just wants to keep running. There are two paths forward here. If your servo has a tuning potentiometer on the back, you can use a screwdriver to tune the zero point. If your continuous servo does not have a physical potentiometer, you can use the midpoint pulse length for a zero speed during initialization. This is similar to the min and max microseconds arguments from the angular servo example.
I stripped out all the code except the line that tries to stop the servo, and we can see that the servo is still running. Let's pretend it doesn't have a tuning pot and find the zero point. I'll change this 1500 to maybe 1600, and that's actually quite a bit faster. Maybe I need to be at 1450, and there it is. So I had to change from 1500 to 1450 to bring the servo to a stop using code.
Now it's not too hard to drive multiple servos too. Here I've connected one angular servo to each channel of the driver. I'll start by remixing the angular servo example.
Need each real server needs its own call to the initialization function, so I'll just copy and paste this line another three times and update the channel number for each server. Now we have four server instances in our code that we can control independently. I'll create an infinite loop that just sets each servo to the same angle in a sequence and there's a delay between each servo. When I run the script, we can see each server travels 90-degrees in sequence - pretty cool, right?
Now it's also possible to daisy-chain up to four servo drivers on the same bus. Recall this first driver has both address switches off. To add the second server driver, I'll first set a unique address switch configuration by setting address switch number one, address switch number two stays off. Then daisy-chain the PiicoDev and USB connections and add an additional four servos. Now in the code, I'll be explicit with the address switch setting for my first driver just so we don't get confused. Then create a second instance of PiicoDev servo driver. Here, the address switch argument ASW encodes the state of the address switches. Since address switch 1 is on, I'll put a 1 in the first column of the argument. The second switch is off, so there's a zero.
Now for the familiar process of initializing the individual servos and this time we're using a different servo driver to tell them apart. I renamed my first driver controller A and the second one is controller B. Eight is a lot of servers to write code for, so I'll put them all in this list called servers and use a for loop to perform an action for each server. Run the code and there's eight servers being controlled individually. And look what happens when I drive them all together to produce this nice wavy effect. Now this idea is extensible for up to four servo drivers for a total of 16 servos.
That's heaps of servos, so you may need to do some power measurements to make sure your power supply can handle it. There you have it, a way to drive multiple servers and multiple servo drivers with a Raspberry Pi Pico. If you make anything cool with this information, we'd love for you to share it on our forums. If you have some questions or need some help, then reach out to us there too. We're full-time makers and happy to help. Until next time, happy making!
Makers love reviews as much as you do, please follow this link to review the products you have purchased.