0
# Adafruit CircuitPython ServoKit
1
2
A CircuitPython helper library that provides a unified interface for controlling servo motors through Adafruit's PWM/Servo hardware kits. It abstracts the complexity of the underlying PCA9685 PWM controller, offering simple APIs for both standard positioning servos and continuous rotation servos with support for configurable I2C addressing, reference clock speeds, and PWM frequencies.
3
4
## Package Information
5
6
- **Package Name**: adafruit-circuitpython-servokit
7
- **Language**: Python (CircuitPython)
8
- **Installation**: `pip install adafruit-circuitpython-servokit`
9
- **Dependencies**: Adafruit-Blinka, adafruit-circuitpython-pca9685, adafruit-circuitpython-motor, adafruit-circuitpython-busdevice, adafruit-circuitpython-register
10
11
## Core Imports
12
13
Primary import for the ServoKit class:
14
15
```python
16
from adafruit_servokit import ServoKit
17
```
18
19
Required dependencies (automatically imported):
20
21
```python
22
import board
23
from adafruit_pca9685 import PCA9685
24
```
25
26
Optional imports for type hints:
27
28
```python
29
from typing import Optional
30
from busio import I2C
31
from adafruit_motor.servo import Servo, ContinuousServo
32
```
33
34
## Basic Usage
35
36
```python
37
import time
38
from adafruit_servokit import ServoKit
39
40
# Set channels to the number of servo channels on your kit.
41
# 8 for FeatherWing, 16 for Shield/HAT/Bonnet.
42
kit = ServoKit(channels=8)
43
44
# Control a standard servo on channel 0
45
kit.servo[0].angle = 180
46
time.sleep(1)
47
kit.servo[0].angle = 0
48
49
# Control a continuous rotation servo on channel 1
50
kit.continuous_servo[1].throttle = 1 # Forward
51
time.sleep(1)
52
kit.continuous_servo[1].throttle = -1 # Backward
53
time.sleep(1)
54
kit.continuous_servo[1].throttle = 0 # Stop
55
```
56
57
## Architecture
58
59
The library provides a simple abstraction over the Adafruit PCA9685 PWM controller chip:
60
61
- **ServoKit**: Main class representing the hardware kit, manages I2C communication and channel allocation through the underlying PCA9685 driver
62
- **_Servo**: Channel accessor for standard positioning servos (0-180 degrees)
63
- **_ContinuousServo**: Channel accessor for continuous rotation servos (-1.0 to 1.0 throttle)
64
- **Hardware Support**: Compatible with 8-channel FeatherWing and 16-channel Shield/HAT/Bonnet kits
65
- **Dependencies**: Built on adafruit-circuitpython-pca9685 and adafruit-circuitpython-motor libraries
66
67
## Capabilities
68
69
### Hardware Kit Initialization
70
71
Creates a ServoKit instance representing an Adafruit PWM/Servo hardware kit with configurable I2C settings and PWM parameters.
72
73
```python { .api }
74
class ServoKit:
75
def __init__(
76
self,
77
*,
78
channels: int,
79
i2c: Optional[I2C] = None,
80
address: int = 0x40,
81
reference_clock_speed: int = 25000000,
82
frequency: int = 50,
83
) -> None:
84
"""
85
Initialize ServoKit for controlling servo motors.
86
87
Parameters:
88
- channels: int - Number of servo channels (must be 8 or 16)
89
- i2c: Optional[I2C] - I2C bus instance (defaults to board.I2C())
90
- address: int - I2C address of PCA9685 controller (default: 0x40)
91
- reference_clock_speed: int - Internal reference clock frequency in Hz (default: 25000000)
92
- frequency: int - Overall PWM frequency in Hz (default: 50)
93
94
Raises:
95
- ValueError: If channels is not 8 or 16
96
"""
97
```
98
99
### Standard Servo Control
100
101
Controls standard positioning servos with angle-based positioning from 0 to 180 degrees.
102
103
```python { .api }
104
@property
105
def servo(self) -> "_Servo":
106
"""
107
Access to standard servo controls via channel indexing.
108
109
Returns:
110
_Servo instance providing indexed access to servo channels
111
"""
112
113
class _Servo:
114
def __getitem__(self, servo_channel: int) -> Servo:
115
"""
116
Get servo controller for specific channel.
117
118
Parameters:
119
- servo_channel: int - Channel number (0 to channels-1)
120
121
Returns:
122
Servo object from adafruit_motor.servo
123
124
Raises:
125
- ValueError: If channel number is out of range or already in use
126
"""
127
128
def __len__(self) -> int:
129
"""
130
Get number of available servo channels.
131
132
Returns:
133
int - Number of channels
134
"""
135
```
136
137
**Servo Object Interface** (from adafruit_motor.servo):
138
139
```python { .api }
140
class Servo:
141
@property
142
def angle(self) -> Optional[float]:
143
"""Current servo angle in degrees (0-180)"""
144
145
@angle.setter
146
def angle(self, value: Optional[float]) -> None:
147
"""Set servo angle in degrees (0-180)"""
148
```
149
150
### Continuous Servo Control
151
152
Controls continuous rotation servos with throttle-based speed and direction control.
153
154
```python { .api }
155
@property
156
def continuous_servo(self) -> "_ContinuousServo":
157
"""
158
Access to continuous servo controls via channel indexing.
159
160
Returns:
161
_ContinuousServo instance providing indexed access to continuous servo channels
162
"""
163
164
class _ContinuousServo:
165
def __getitem__(self, servo_channel: int) -> ContinuousServo:
166
"""
167
Get continuous servo controller for specific channel.
168
169
Parameters:
170
- servo_channel: int - Channel number (0 to channels-1)
171
172
Returns:
173
ContinuousServo object from adafruit_motor.servo
174
175
Raises:
176
- ValueError: If channel number is out of range or already in use
177
"""
178
179
def __len__(self) -> int:
180
"""
181
Get number of available servo channels.
182
183
Returns:
184
int - Number of channels
185
"""
186
```
187
188
**ContinuousServo Object Interface** (from adafruit_motor.servo):
189
190
```python { .api }
191
class ContinuousServo:
192
@property
193
def throttle(self) -> Optional[float]:
194
"""Current throttle value (-1.0 to 1.0)"""
195
196
@throttle.setter
197
def throttle(self, value: Optional[float]) -> None:
198
"""Set throttle value (-1.0 to 1.0, where -1.0=full reverse, 1.0=full forward, 0=stop)"""
199
```
200
201
## Types
202
203
```python { .api }
204
from typing import Optional
205
from busio import I2C
206
from adafruit_motor.servo import Servo, ContinuousServo
207
```
208
209
## Module Constants
210
211
```python { .api }
212
__version__: str # Library version string
213
__repo__: str # Repository URL
214
```
215
216
## Error Handling
217
218
The library raises `ValueError` exceptions in the following cases:
219
220
- **Invalid channel count**: ServoKit constructor called with channels not equal to 8 or 16
221
- **Channel out of range**: Attempting to access servo channel outside valid range (0 to channels-1)
222
- **Channel conflict**: Attempting to use a channel that's already assigned to a different servo type
223
224
## Hardware Compatibility
225
226
- **8-Channel PWM or Servo FeatherWing**: Use `channels=8`
227
- **16-Channel PWM/Servo Shield**: Use `channels=16`
228
- **16-Channel PWM/Servo HAT for Raspberry Pi**: Use `channels=16`
229
- **16-Channel PWM/Servo Bonnet for Raspberry Pi**: Use `channels=16`
230
231
All hardware uses the PCA9685 PWM controller and communicates via I2C.
232
233
## Usage Examples
234
235
### Multiple Servos Sequential Control
236
237
```python
238
import time
239
from adafruit_servokit import ServoKit
240
241
kit = ServoKit(channels=16)
242
243
# Move all servos sequentially
244
for i in range(len(kit.servo)):
245
kit.servo[i].angle = 180
246
time.sleep(1)
247
kit.servo[i].angle = 0
248
time.sleep(1)
249
```
250
251
### Multiple Servos Synchronized Control
252
253
```python
254
import time
255
from adafruit_servokit import ServoKit
256
257
kit = ServoKit(channels=16)
258
259
# Move all servos simultaneously
260
for i in range(len(kit.servo)):
261
kit.servo[i].angle = 180
262
time.sleep(1)
263
for i in range(len(kit.servo)):
264
kit.servo[i].angle = 0
265
time.sleep(1)
266
```
267
268
### Custom I2C Configuration
269
270
```python
271
import board
272
import busio
273
from adafruit_servokit import ServoKit
274
275
# Create custom I2C bus
276
i2c = busio.I2C(board.SCL, board.SDA)
277
278
# Initialize with custom settings
279
kit = ServoKit(
280
channels=16,
281
i2c=i2c,
282
address=0x41, # Custom I2C address
283
frequency=60 # Custom PWM frequency
284
)
285
```