CircuitPython Servos

To the left are the connections for the Crickit with the Circuit Playground Express.

 

Note: The black wire on the servo connectors always points inward towards the microcontroller and center of Crickit. The light wire: yellow, orange, white, etc. faces outward from the Crickit.

Here is the Feather Crickit connected to four servos.

The Crickit HAT for Raspberry Pi can also control up to 4 servos like other Crickit boards. Note the location of the Servo header block with 4 rows of three male pins.

Test Servos

Lets start by controlling some servos. You'll want at least one servo to plug in and test out the servo code. Visit our recommended servo page to check that you have a servo that works. Once you do, plug in a servo into SERVO #1 spot, making sure the yellow or white wire is next to the 1 text label.

This example will show rotating one servo from 0 to 180 degrees with a stop at 90 degrees.

Download: file
import time
from adafruit_crickit import crickit

print("1 Servo demo!")

while True:
    print("Moving servo #1")
    crickit.servo_1.angle = 0      # right
    time.sleep(1)
    crickit.servo_1.angle = 90     # middle
    time.sleep(1)
    crickit.servo_1.angle = 180    # left
    time.sleep(1)
    crickit.servo_1.angle = 90     # middle
    time.sleep(1)
    # and repeat!
Are your servos not moving a full 180 degrees? Don't fret! This is normal, see below about min/max pulse lengths to 'tune' your servo!

We start by importing the libraries that we need to have time delays ( import time ) and then the main crickit python library that will make it super easy to talk to the motors and sensors on crickit (from adafruit_crickit import crickit)

The crickit object represents the motors and servos available for control. The servos are available on the sub-objects named servo_1, servo_2, servo_3, servo_4

Each of these are adafruit_motor.servo type objects for the curious

Control Servo

Now that we know the servo objects, we can simply assign the angle! crickit.servo_1.angle = 0 is all the way to the left, crickit.servo_1.angle = 90 is in the middle, and crickit.servo_1.angle = 180 is all the way to the right. You'll want to test this to ensure it works with your specific servo, as 0 might be to the right and 180 to the left if it was geared differently.

More Servos!

OK that was fun but you want MORE servos right? You can control up to four!

Download: file
import time
from adafruit_crickit import crickit

print("4 Servo demo!")

# make a list of all the servos
servos = (crickit.servo_1, crickit.servo_2, crickit.servo_3, crickit.servo_4)

while True:
    # Repeat for all 4 servos
    for my_servo in servos:
        # Do the wave!
        print("Moving servo #", servos.index(my_servo)+1)
        my_servo.angle = 0      # right
        time.sleep(0.25)
        my_servo.angle = 90     # middle
        time.sleep(0.25)
        my_servo.angle = 180    # left
        time.sleep(0.25)
        my_servo.angle = 90     # middle
        time.sleep(0.25)
        my_servo.angle = 0      # right

This example is similar to the 1 servo example, but instead of accessing thecrickit.servo_1 object directly, we'll make a list called servos that contains 4 servo objects with

servos = (crickit.servo_1, crickit.servo_2, crickit.servo_3, crickit.servo_4)

Then we can access the individual using servo[0].angle = 90 or iterate through them as we do in the loop. You don't have to do it this way, but its very compact and doesn't take a lot of code lines to create all 4 servos at once!

One thing to watch for is that if you use a list like this, servo[0] is the name of the Servo #1 and servo[3] is Servo #4!

Min/Max Pulse control

Originally servos were defined to use 1.0 millisecond to 2.0 millisecond pulses, at 50 Hz to set the 0 and 180 degree locations. However, as more companies started making servos they changed the pulse ranges to 0.5ms to 2.5ms or even bigger ranges. So, not all servos have their full range at thoe 'standard' pulse widths. You can easily tweak your code to change the min and max pulse widths, which will let your servo turn more left and right. But don't set the widths too small/large or you can hit the hard stops of the servo which could damage it, so try tweaking the numbers slowly until you get a sense of what the limits are for your motor.

All you need to do is add a line at the top of your code like this

crickit.servo_1.set_pulse_width_range(min_pulse=500, max_pulse=2500)

The above is for Crickit Servo #1, you'll need to duplicate and adjust for all other servos, but that way you can customize the range uniquely per servo!

Here we've change the minimum pulse from the default ~750 microseconds to 500, and the default maximum pulse from 2250 microseconds to 2500. Again, each servo differs. Some experimentation may be required!

Download: file
import time
from adafruit_crickit import crickit

print("1 Servo demo with custom pulse widths!")

crickit.servo_1.set_pulse_width_range(min_pulse=500, max_pulse=2500)

while True:
    print("Moving servo #1")
    crickit.servo_1.angle = 0      # right
    time.sleep(1)
    crickit.servo_1.angle = 180    # left
    time.sleep(1)

Continuous Rotation Servos

If you're using continuous servos, you can use the angle assignments and just remember that 0 is rotating one way, 90 is 'stopped' and 180 and rotating the other way. Or, better yet, you can use the crickit.continuous_servo_1 object instead of the plain servo_1

Again, you get up to 4 servos. You can mix 'plain' and 'continuous' servos

Download: file
import time
from adafruit_crickit import crickit

print("1 Continuous Servo demo!")

while True:
    crickit.continuous_servo_1.throttle = 1.0 # Forwards
    time.sleep(2)
    crickit.continuous_servo_1.throttle = 0.5 # Forwards halfspeed
    time.sleep(2)
    crickit.continuous_servo_1.throttle = 0   # Stop
    time.sleep(2)
    crickit.continuous_servo_1.throttle = -0.5 # Backwards halfspeed
    time.sleep(2)
    crickit.continuous_servo_1.throttle = -1 # Forwards
    time.sleep(2)
    crickit.continuous_servo_1.throttle = 0   # Stop
    time.sleep(2)

If your continuous servo doesn't stop once the loop is finished you may need to tune the min_pulse and max_pulse timings so that the center makes the servo stop. Or check if the servo has a center-adjustment screw you can tweak.

Disconnecting Servos or Custom Pulses

If you want to 'disconnect' the Servo by sending it 0-length pulses, you can do that by 'reaching in' and adjusting the underlying PWM duty cycle with:

crickit.servo_1._pwm_out.duty_cycle = 0

or

crickit.servo_1._pwm_out.fraction = 0

Likewise you can set the duty cycle to a custom value with

crickit.servo_1._pwm_out.duty_cycle = number

where number is between 0 (off) and 65535 (fully on). For example, setting it to 32767 will be 50% duty cycle, at the 50 Hz update rate

Or you can use fractions like crickit.servo_1._pwm_out.fraction = 0.5

Download: file
import time
from adafruit_crickit import crickit

print("1 Servo release demo!")

while True:
    print("Moving servo #1")
    crickit.servo_1.angle = 0      # right
    time.sleep(10)
    print("Released")
    crickit.servo_1._pwm_out.duty_cycle = 0
    time.sleep(10)
    # and repeat!
This guide was first published on May 16, 2018. It was last updated on May 16, 2018. This page (CircuitPython Servos) was last updated on Oct 14, 2019.