Servo Shield¶
Servo Shield керує до восьми хобійних сервоприводів паралельно від OpenMV Cam по I2C, використовуючи контролер серво/PWM PCA9685.
Повний технічний опис, фотографії та інформацію про замовлення дивіться на сторінці продукту Servo Shield.
Основні характеристики¶
Контролер серво/PWM PCA9685
Вісім незалежних каналів сервоприводів по I2C
Поєднується з Motor Shield та Pan and Tilt Shield
Розпіновка¶
Довідник виводів¶
Вивід |
Функція |
|---|---|
P4 |
I²C SCL — тактовий сигнал до PCA9685 |
P5 |
I²C SDA — дані до PCA9685 |
Шина VIN |
Живлення сервоприводів (від виводу VIN камери) |
Шина 3.3В |
Живлення логіки PCA9685 |
Шина GND |
Спільна земля сервоприводів і камери |
Адреса I²C за замовчуванням — 0x40. Підключіть перемичку пайки на платі, щоб перемістити адресу на 0x60.
Примітка
Плата розширення живить сервоприводи безпосередньо від виводу VIN камери. USB не живить VIN на жодній OpenMV Cam, тому VIN має бути підключений зовнішньо (батарея, лабораторний блок живлення або аналогічний) — вибирайте джерело, розраховане на сумарний струм стопоріння всіх сервоприводів, які ви плануєте використовувати.
Використання¶
Керування вісьмома каналами сервоприводів через PCA9685 по I²C. Діапазон ширини імпульсів різниться між сервоприводами, тому налаштуйте MIN_US та MAX_US відповідно до вашої моделі — типові значення близько 1000–2000 мкс:
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 також підтримує загальний 12-бітний PWM на будь-якій частоті — повторно використовуйте той самий клас з set_duty (0–4095) для, наприклад, плавного згасання світлодіода на каналі 0 при 1 кГц. Допоміжна функція нижче масштабує значення від 0,0 до 100,0% у діапазон 0–4095 мікросхеми:
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)