Skip to content

Commit 5a50830

Browse files
authored
Merge pull request #27 from ladyada/master
servo disable, rename examples
2 parents 117e146 + 1839848 commit 5a50830

7 files changed

+108
-41
lines changed

adafruit_motor/servo.py

+13-2
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,17 @@ def set_pulse_width_range(self, min_pulse=750, max_pulse=2250):
5454
def fraction(self):
5555
"""Pulse width expressed as fraction between 0.0 (`min_pulse`) and 1.0 (`max_pulse`).
5656
For conventional servos, corresponds to the servo position as a fraction
57-
of the actuation range.
57+
of the actuation range. Is None when servo is diabled (pulsewidth of 0ms).
5858
"""
59+
if self._pwm_out.duty_cycle == 0: # Special case for disabled servos
60+
return None
5961
return (self._pwm_out.duty_cycle - self._min_duty) / self._duty_range
6062

6163
@fraction.setter
6264
def fraction(self, value):
65+
if value is None:
66+
self._pwm_out.duty_cycle = 0 # disable the motor
67+
return
6368
if not 0.0 <= value <= 1.0:
6469
raise ValueError("Must be 0.0 to 1.0")
6570
duty_cycle = self._min_duty + int(value * self._duty_range)
@@ -102,11 +107,17 @@ def __init__(self, pwm_out, *, actuation_range=180, min_pulse=750, max_pulse=225
102107

103108
@property
104109
def angle(self):
105-
"""The servo angle in degrees. Must be in the range ``0`` to ``actuation_range``."""
110+
"""The servo angle in degrees. Must be in the range ``0`` to ``actuation_range``.
111+
Is None when servo is disabled."""
112+
if self.fraction is None: # special case for disabled servos
113+
return None
106114
return self.actuation_range * self.fraction
107115

108116
@angle.setter
109117
def angle(self, new_angle):
118+
if new_angle is None: # disable the servo by sending 0 signal
119+
self.fraction = None
120+
return
110121
if new_angle < 0 or new_angle > self.actuation_range:
111122
raise ValueError("Angle out of range")
112123
self.fraction = new_angle / self.actuation_range

docs/examples.rst

+12-8
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,22 @@ Simple tests
33

44
Ensure your device works with this simple test.
55

6-
.. literalinclude:: ../examples/motor_dc_motor.py
7-
:caption: examples/motor_dc_motor.py
6+
.. literalinclude:: ../examples/motor_servo_sweep.py
7+
:caption: examplesmotor_servo_sweep.py
88
:linenos:
99

10-
.. literalinclude:: ../examples/motor_stepper_motor.py
11-
:caption: examples/motor_stepper_motor.py
10+
.. literalinclude:: ../examples/motor_pca9685_dc_motor.py
11+
:caption: examples/motor_pca9685_dc_motor.py
1212
:linenos:
1313

14-
.. literalinclude:: ../examples/motor_servo_sweep.py
15-
:caption: examples/motor_servo_sweep.py
14+
.. literalinclude:: ../examples/motor_pca9685_stepper_motor.py
15+
:caption: examples/motor_pca9685_stepper_motor.py
16+
:linenos:
17+
18+
.. literalinclude:: ../examples/motor_pca9685_servo_sweep.py
19+
:caption: examples/motor_pca9685_servo_sweep.py
1620
:linenos:
1721

18-
.. literalinclude:: ../examples/motor_continuous_servo.py
19-
:caption: examples/motor_continuous_servo.py
22+
.. literalinclude:: ../examples/motor_pca9685_continuous_servo.py
23+
:caption: examples/motor_pca9685_continuous_servo.py
2024
:linenos:
File renamed without changes.

examples/motor_pca9685_servo_sweep.py

+56
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import time
2+
3+
from board import SCL, SDA
4+
import busio
5+
6+
# Import the PCA9685 module. Available in the bundle and here:
7+
# https://github.com/adafruit/Adafruit_CircuitPython_PCA9685
8+
from adafruit_pca9685 import PCA9685
9+
from adafruit_motor import servo
10+
11+
i2c = busio.I2C(SCL, SDA)
12+
13+
# Create a simple PCA9685 class instance.
14+
pca = PCA9685(i2c)
15+
# You can optionally provide a finer tuned reference clock speed to improve the accuracy of the
16+
# timing pulses. This calibration will be specific to each board and its environment. See the
17+
# calibration.py example in the PCA9685 driver.
18+
# pca = PCA9685(i2c, reference_clock_speed=25630710)
19+
pca.frequency = 50
20+
21+
# To get the full range of the servo you will likely need to adjust the min_pulse and max_pulse to
22+
# match the stall points of the servo.
23+
# This is an example for the Sub-micro servo: https://www.adafruit.com/product/2201
24+
# servo7 = servo.Servo(pca.channels[7], min_pulse=580, max_pulse=2350)
25+
# This is an example for the Micro Servo - High Powered, High Torque Metal Gear:
26+
# https://www.adafruit.com/product/2307
27+
# servo7 = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2600)
28+
# This is an example for the Standard servo - TowerPro SG-5010 - 5010:
29+
# https://www.adafruit.com/product/155
30+
# servo7 = servo.Servo(pca.channels[7], min_pulse=400, max_pulse=2400)
31+
# This is an example for the Analog Feedback Servo: https://www.adafruit.com/product/1404
32+
# servo7 = servo.Servo(pca.channels[7], min_pulse=600, max_pulse=2500)
33+
# This is an example for the Micro servo - TowerPro SG-92R: https://www.adafruit.com/product/169
34+
# servo7 = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2400)
35+
36+
# The pulse range is 750 - 2250 by default. This range typically gives 135 degrees of
37+
# range, but the default is to use 180 degrees. You can specify the expected range if you wish:
38+
# servo7 = servo.Servo(pca.channels[7], actuation_range=135)
39+
servo7 = servo.Servo(pca.channels[7])
40+
41+
# We sleep in the loops to give the servo time to move into position.
42+
for i in range(180):
43+
servo7.angle = i
44+
time.sleep(0.03)
45+
for i in range(180):
46+
servo7.angle = 180 - i
47+
time.sleep(0.03)
48+
49+
# You can also specify the movement fractionally.
50+
fraction = 0.0
51+
while fraction < 1.0:
52+
servo7.fraction = fraction
53+
fraction += 0.01
54+
time.sleep(0.03)
55+
56+
pca.deinit()

examples/motor_servo_sweep.py

+27-31
Original file line numberDiff line numberDiff line change
@@ -1,56 +1,52 @@
11
import time
2-
3-
from board import SCL, SDA
4-
import busio
5-
6-
# Import the PCA9685 module. Available in the bundle and here:
7-
# https://github.com/adafruit/Adafruit_CircuitPython_PCA9685
8-
from adafruit_pca9685 import PCA9685
2+
import board
3+
import pulseio
94
from adafruit_motor import servo
105

11-
i2c = busio.I2C(SCL, SDA)
12-
13-
# Create a simple PCA9685 class instance.
14-
pca = PCA9685(i2c)
15-
# You can optionally provide a finer tuned reference clock speed to improve the accuracy of the
16-
# timing pulses. This calibration will be specific to each board and its environment. See the
17-
# calibration.py example in the PCA9685 driver.
18-
# pca = PCA9685(i2c, reference_clock_speed=25630710)
19-
pca.frequency = 50
6+
# create a PWMOut object on the control pin.
7+
pwm = pulseio.PWMOut(board.D5, duty_cycle=0, frequency=50)
208

219
# To get the full range of the servo you will likely need to adjust the min_pulse and max_pulse to
2210
# match the stall points of the servo.
2311
# This is an example for the Sub-micro servo: https://www.adafruit.com/product/2201
24-
# servo7 = servo.Servo(pca.channels[7], min_pulse=580, max_pulse=2350)
12+
# servo = servo.Servo(pwm, min_pulse=580, max_pulse=2350)
2513
# This is an example for the Micro Servo - High Powered, High Torque Metal Gear:
2614
# https://www.adafruit.com/product/2307
27-
# servo7 = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2600)
15+
# servo = servo.Servo(pwm, min_pulse=500, max_pulse=2600)
2816
# This is an example for the Standard servo - TowerPro SG-5010 - 5010:
2917
# https://www.adafruit.com/product/155
30-
# servo7 = servo.Servo(pca.channels[7], min_pulse=400, max_pulse=2400)
18+
# servo = servo.Servo(pwm, min_pulse=400, max_pulse=2400)
3119
# This is an example for the Analog Feedback Servo: https://www.adafruit.com/product/1404
32-
# servo7 = servo.Servo(pca.channels[7], min_pulse=600, max_pulse=2500)
20+
# servo = servo.Servo(pwm, min_pulse=600, max_pulse=2500)
3321
# This is an example for the Micro servo - TowerPro SG-92R: https://www.adafruit.com/product/169
34-
# servo7 = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2400)
22+
# servo = servo.Servo(pwm, min_pulse=500, max_pulse=2400)
3523

3624
# The pulse range is 750 - 2250 by default. This range typically gives 135 degrees of
3725
# range, but the default is to use 180 degrees. You can specify the expected range if you wish:
38-
# servo7 = servo.Servo(pca.channels[7], actuation_range=135)
39-
servo7 = servo.Servo(pca.channels[7])
26+
# servo = servo.Servo(board.D5, actuation_range=135)
27+
servo = servo.Servo(pwm)
4028

4129
# We sleep in the loops to give the servo time to move into position.
30+
print("Sweep from 0 to 180")
4231
for i in range(180):
43-
servo7.angle = i
44-
time.sleep(0.03)
32+
servo.angle = i
33+
time.sleep(0.01)
34+
print("Sweep from 180 to 0")
4535
for i in range(180):
46-
servo7.angle = 180 - i
47-
time.sleep(0.03)
36+
servo.angle = 180 - i
37+
time.sleep(0.01)
38+
39+
print("Move to 90 degrees")
40+
servo.angle = 90
41+
time.sleep(1)
42+
print("Release servo motor for 10 seconds")
43+
servo.fraction = None
44+
time.sleep(10)
4845

4946
# You can also specify the movement fractionally.
47+
print("Sweep from 0 to 1.0 fractionally")
5048
fraction = 0.0
5149
while fraction < 1.0:
52-
servo7.fraction = fraction
50+
servo.fraction = fraction
5351
fraction += 0.01
54-
time.sleep(0.03)
55-
56-
pca.deinit()
52+
time.sleep(0.01)

0 commit comments

Comments
 (0)