Servo Shield¶
Servo Shield điều khiển lên đến tám servo hobby song song từ OpenMV Cam qua I2C, sử dụng bộ điều khiển servo/PWM PCA9685.
Để xem datasheet đầy đủ, ảnh và đặt hàng, hãy xem trang sản phẩm Servo Shield.
Tính năng nổi bật¶
Bộ điều khiển servo/PWM PCA9685
Tám kênh servo độc lập qua I2C
Có thể ghép chồng với Motor Shield và Pan and Tilt Shield
Sơ đồ chân¶
Tham chiếu chân¶
Chân |
Chức năng |
|---|---|
P4 |
I²C SCL — xung nhịp đến PCA9685 |
P5 |
I²C SDA — dữ liệu đến PCA9685 |
Rail VIN |
Cấp nguồn cho servo (từ chân VIN của camera) |
Rail 3.3V |
Cấp nguồn cho logic PCA9685 |
Rail GND |
Chân đất chung của servo và camera |
Địa chỉ I²C mặc định là 0x40. Kết nối cầu hàn trên bo để chuyển địa chỉ sang 0x60.
Ghi chú
Shield lấy nguồn servo trực tiếp từ chân VIN của camera. USB không cấp VIN trên bất kỳ OpenMV Cam nào, vì vậy VIN phải được cung cấp từ bên ngoài (pin, nguồn điện bàn hoặc tương tự) — chọn nguồn có công suất đủ cho tổng dòng khởi động của tất cả servo bạn dự định điều khiển.
Sử dụng¶
Điều khiển tám kênh servo qua PCA9685 trên I²C. Phạm vi độ rộng xung thay đổi giữa các servo, vì vậy hãy tinh chỉnh MIN_US và MAX_US cho phù hợp với servo của bạn — giá trị điển hình là khoảng 1000–2000 µs:
import time
from machine import SoftI2C, Pin
class PCA9685:
"""Minimal PCA9685 driver — 12-bit PWM on any of 8 channels."""
def __init__(self, bus, address=0x40, freq=50):
self._bus = bus
self._addr = address
bus.writeto_mem(address, 0x00, b"\x00") # reset Mode1
prescale = round(25_000_000 / (4096 * freq)) - 1
bus.writeto_mem(address, 0x00, b"\x10") # sleep
bus.writeto_mem(address, 0xFE, bytes([prescale])) # prescale
bus.writeto_mem(address, 0x00, b"\x00") # wake
time.sleep_us(5)
bus.writeto_mem(address, 0x00, b"\xA1") # restart + AI + allcall
self._period_us = 1_000_000 // freq
def set_duty(self, channel, duty):
duty &= 0xFFF # 12-bit
if duty == 0:
on, off = 0, 0x1000 # FULL_OFF
elif duty == 0xFFF:
on, off = 0x1000, 0 # FULL_ON
else:
on, off = 0, duty
self._bus.writeto_mem(
self._addr, 0x06 + 4 * channel,
bytes([on & 0xFF, on >> 8, off & 0xFF, off >> 8]))
def set_us(self, channel, pulse_us):
self.set_duty(channel, (pulse_us * 4096) // self._period_us)
MIN_US = 1000 # full-left pulse width (microseconds)
MAX_US = 2000 # full-right pulse width
bus = SoftI2C(scl=Pin("P4"), sda=Pin("P5"))
pca = PCA9685(bus, address=0x40, freq=50)
def angle(channel, deg):
pca.set_us(channel, MIN_US + (deg * (MAX_US - MIN_US)) // 180)
while True:
for ch in range(8):
angle(ch, 0)
time.sleep_ms(2000)
for ch in range(8):
angle(ch, 180)
time.sleep_ms(2000)
PCA9685 cũng xử lý PWM 12-bit thông thường ở bất kỳ tần số nào — tái sử dụng cùng lớp với set_duty (0–4095) để, ví dụ, làm mờ đèn LED trên kênh 0 ở 1 kHz. Hàm trợ giúp bên dưới chuyển đổi số thực 0,0–100,0% sang dải duty 0–4095 của chip:
import time
from machine import SoftI2C, Pin
bus = SoftI2C(scl=Pin("P4"), sda=Pin("P5"))
pca = PCA9685(bus, address=0x40, freq=1000)
def brightness(channel, pct):
pca.set_duty(channel, int(pct * 4095 / 100))
while True:
# Ramp up 0 → 100%.
for pct in range(101):
brightness(0, float(pct))
time.sleep_ms(20)
# Ramp down 100 → 0%.
for pct in reversed(range(101)):
brightness(0, float(pct))
time.sleep_ms(20)