Hobby Servo Examples - Adafruit Circuit Playground Bluefruit¶
The following short Python programs demonstrate operation of hobby circuit actuators using the Adafruit Circuit Playground Bluefruit (CPB) board. These assume the board has an external hobby servo and power battery circuit attached.
Each can be run by copying the program into code.py
on the CIRCUITPY drive offered by the board. The text can be pasted directly
from this page, or each file can be downloaded from the CircuitPython sample
code folder on this site.
Related Pages
Essential Documentation
Contents
Hobby Servo Summary¶
A hobby servo is a closed-loop actuator: it uses a position sensor to control the output shaft to a commanded angle.
The output has limited travel. The LKY62 has a nominal range of 180 degrees but the travel limits are actually somewhat more.
Internally it includes a DC motor, gear train, position sensing potentiometer, and a control circuit.
The output shaft is splined (i.e. grooved) and supplied with matching molded plastic servo horns. The horns are the only practical way to connect to the output.
The horns are used with tendon lines (tension-only) or pushrods (push or pull) to connect the movement to a mechanism.
The LKY62 servos typically operate on 5 to 6 Volts and can draw upwards of 1000 mA (much more than the CPB output).
The command signal is a pulse train emitted at 50 Hz (every 20 msec). Each pulse is about 1 to 2 msec long and the pulse length encodes the target angle.
Hobby Servo Power Circuit¶
The CPB VOUT power output is intended only for small external sensors and it not sufficient to run even a medium-size hobby servo. The following diagrams illustrate how to use an external 4-AA battery pack to power a hobby servo driven by the CPB.
Servo Sweep¶
This minimal sketch demonstrates the basic configuration for setting up a servo output and issuing motion commands. The resulting movement is shown in the following video.
Direct download: cpb_servo_sweep.py.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | # cpb_servo_sweep.py
# Demonstrate oscillating movement of a hobby servo. Note that only a tiny
# micro-servo (e.g. "SG90 9g") is safe to drive directly off the board; in
# general, hobby servos require a separate battery supply. The wiring for this
# is as follows:
#
# 1. The servo control line (typ. orange) connects to SDA A5
# 2. The servo ground line (typ. brown) connects to GND
# 3. The servo power line (typ. red) connects to 6V battery
# Related documentation:
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/pwmio/index.html#module-pwmio
# https://circuitpython.readthedocs.io/projects/motor/en/latest/api.html#module-adafruit_motor.servo
# ----------------------------------------------------------------
# Import the standard Python time functions.
import time
# Import the low-level hardware libraries.
import board
import pwmio
# Import the Adafruit helper library.
from adafruit_motor import servo
# ----------------------------------------------------------------
# Initialize hardware.
# Create a PWMOut object on pad SDA A5 to generate control signals.
pwm = pwmio.PWMOut(board.A5, duty_cycle=0, frequency=50)
# Create a Servo object which controls a hobby servo using the PWMOut.
actuator = servo.Servo(pwm, min_pulse=1000, max_pulse=2000)
# ----------------------------------------------------------------
# Begin the main processing loop.
while True:
print("Starting cycle.")
for angle in range(0, 180, 5):
actuator.angle = angle
time.sleep(0.02)
print("Reversing cycle.")
for angle in range(180, 0, -5):
actuator.angle = angle
time.sleep(0.02)
print("Pausing.")
time.sleep(0.5)
|
Sine Servo¶
This sketch moves the servo back and forth in a smooth motion. It is constructed as a non-blocking event loop, so this is a more practical starting point for combining with with additional sensor and actuator code. The resulting movement is shown in the following video.
Direct download: cpb_sine_servo.py.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 | # cpb_sine_servo.py
# Demonstrate oscillating movement of a hobby servo using a non-blocking event
# loop structure. This program style supports operating multiple devices for
# input and output.
# Note that only a tiny micro-servo (e.g. "SG90 9g") is safe to drive directly
# off the board; in general, hobby servos require a separate battery supply.
# The wiring for this is as follows:
#
# 1. The servo control line (typ. orange) connects to SDA A5
# 2. The servo ground line (typ. brown) connects to GND
# 3. The servo power line (typ. red) connects to 6V battery
# Related documentation:
# https://circuitpython.readthedocs.io/en/latest/shared-bindings/pwmio/index.html#module-pwmio
# https://circuitpython.readthedocs.io/projects/motor/en/latest/api.html#module-adafruit_motor.servo
# ----------------------------------------------------------------
# Import standard Python modules.
import time, math
# Import the low-level hardware libraries.
import board
import pwmio
# Import the Adafruit helper library.
from adafruit_motor import servo
# ----------------------------------------------------------------
# Initialize hardware.
# Create a PWMOut object on pad SDA A5 to generate control signals.
pwm = pwmio.PWMOut(board.A5, duty_cycle=0, frequency=50)
# Create a Servo object which controls a hobby servo using the PWMOut.
actuator = servo.Servo(pwm, min_pulse=1000, max_pulse=2000)
# ----------------------------------------------------------------
# Initialize global variables for the main loop.
phase_angle = 0.0
phase_rate = 2*math.pi / 6.0 # one cycle per six seconds, in radians/second
next_servo_update = time.monotonic_ns()
next_status_update = time.monotonic_ns()
# ----------------------------------------------------------------
# Enter the main event loop.
while True:
# Read the current integer clock.
now = time.monotonic_ns()
# If the time has arrived to update the servo command signal:
if now >= next_servo_update:
next_servo_update += 20000000 # 20 msec in nanoseconds (50 Hz update)
actuator.angle = 90 + 90 * math.sin(phase_angle)
phase_angle += phase_rate * 0.020
# If the time has arrived to display the status:
if now >= next_status_update:
next_status_update += 500000000 # 0.5 sec in nanoseconds (2 Hz update)
print(actuator.angle)
|