Servo Shield¶
Servo Shield mengendalikan hingga delapan servo hobi secara paralel dari OpenMV Cam melalui I2C, menggunakan kontroler servo/PWM PCA9685.
Untuk datasheet lengkap, foto, dan pemesanan, lihat halaman produk Servo Shield.
Sorotan¶
Kontroler servo/PWM PCA9685
Delapan saluran servo independen melalui I2C
Dapat ditumpuk dengan Motor Shield dan Pan and Tilt Shield
Pinout¶
Referensi pin¶
Pin |
Fungsi |
|---|---|
P4 |
I²C SCL — clock ke PCA9685 |
P5 |
I²C SDA — data ke PCA9685 |
Rel VIN |
Menyuplai servo (dari pin VIN kamera) |
Rel 3.3V |
Menyuplai logika PCA9685 |
Rel GND |
Ground umum servo dan kamera |
Alamat I²C default adalah 0x40. Hubungkan solder bridge on-board untuk memindahkan alamat ke 0x60.
Catatan
Shield mengambil daya servo langsung dari pin VIN kamera. USB tidak menyuplai VIN pada OpenMV Cam mana pun, sehingga VIN harus disuplai secara eksternal (baterai, catu daya meja, atau serupa) — pilih sumber yang mampu menangani arus stall gabungan dari semua servo yang akan dikendalikan.
Penggunaan¶
Kendalikan delapan saluran servo melalui PCA9685 lewat I²C. Rentang lebar pulsa bervariasi antar servo, jadi sesuaikan MIN_US dan MAX_US dengan servo Anda — nilai tipikal sekitar 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 juga menangani PWM 12-bit umum pada frekuensi berapa pun — gunakan kembali kelas yang sama dengan set_duty (0–4095) untuk, misalnya, memudarkan LED pada saluran 0 pada 1 kHz. Helper di bawah ini menskalakan float 0,0–100,0% ke rentang duty 0–4095 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)