前言
不知道你們有沒有遇到過這麼一種情況,直接用樹莓派的引腳輸出PWM控制舵機,舵機是會出現抖動的。就算程式碼進行一定的時延遲最佳化還是會有影響的。
現在我們可以使用PCA9685
這個模組去驅動舵機。
PCA9685 是一種常用的 PWM(脈衝寬度調製)驅動器晶片,通常用於控制舵機、電機和其他需要精確控制的裝置。該晶片可以透過 I2C 匯流排與微控制器或微控制器通訊,以實現對多路 PWM 訊號的生成和控制。
16 路 PWM 輸出:PCA9685 可以同時控制最多 16 路 PWM 輸出,每路輸出的佔空比都可以獨立設定,但是16路PWM頻率一樣。
12 位解析度:PCA9685 提供了 12 位解析度的 PWM 輸出,可以實現精細的輸出控制。
內部振盪器:晶片內部整合了振盪器,可以產生穩定25MHz的時鐘訊號,無需外部晶振。
可程式設計頻率:可以透過配置暫存器來設定 PWM 輸出的頻率,範圍從 24 Hz 到 1526 Hz。
I2C 介面:使用標準的 I2C 序列匯流排介面與主控裝置通訊,方便整合到各種微控制器系統中。
輸出驅動能力:每路 PWM 輸出都具有較強的驅動能力,可以直接驅動舵機或者其他負載。
接線
- PCA9685綠端VCC和GND要和電池的正負極相連。
- PCA9685控制端的GND和VCC和樹莓派的3.3v(pin1)和GND(pin9)相連。
- PCA9685的SCL和SDA和樹莓派的SCL0(pin5)以及SDA0(pin3)相連。
安裝PCA9685驅動
adafruit/Adafruit_CircuitPython_PCA9685: Adafruit CircuitPython driver for PCA9685 16-channel, 12-bit PWM LED & servo driver chip. (github.com)
在樹莓派終端輸入:
pip3 install adafruit-circuitpython-pca9685
或者輸入:
sudo pip3 install adafruit-circuitpython-pca9685
如果只是想下載虛擬環境到你當前的專案裡可以:
mkdir project-name && cd project-name
python3 -m venv .venv
source .venv/bin/activate
pip3 install adafruit-circuitpython-pca9685
安裝Motor驅動
adafruit/Adafruit_CircuitPython_Motor: Helpers for controlling PWM based motors and servos (github.com)
在樹莓派終端輸入:
pip3 install adafruit-circuitpython-motor
或者輸入:
sudo pip3 install adafruit-circuitpython-motor
如果只是想下載虛擬環境到你當前的專案裡可以:
mkdir project-name && cd project-name
python3 -m venv .venv
source .venv/bin/activate
pip3 install adafruit-circuitpython-motor
測試程式
# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT
import time
import board
from adafruit_motor import servo
from adafruit_pca9685 import PCA9685
i2c = board.I2C() # uses board.SCL and board.SDA
# i2c = busio.I2C(board.GP1, board.GP0) # Pi Pico RP2040
# Create a simple PCA9685 class instance.
pca = PCA9685(i2c)
# You can optionally provide a finer tuned reference clock speed to improve the accuracy of the
# timing pulses. This calibration will be specific to each board and its environment. See the
# calibration.py example in the PCA9685 driver.
# pca = PCA9685(i2c, reference_clock_speed=25630710)
pca.frequency = 50
# To get the full range of the servo you will likely need to adjust the min_pulse and max_pulse to
# match the stall points of the servo.
# This is an example for the Sub-micro servo: https://www.adafruit.com/product/2201
# servo7 = servo.Servo(pca.channels[7], min_pulse=580, max_pulse=2350)
# This is an example for the Micro Servo - High Powered, High Torque Metal Gear:
# https://www.adafruit.com/product/2307
# servo7 = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2600)
# This is an example for the Standard servo - TowerPro SG-5010 - 5010:
# https://www.adafruit.com/product/155
# servo7 = servo.Servo(pca.channels[7], min_pulse=400, max_pulse=2400)
# This is an example for the Analog Feedback Servo: https://www.adafruit.com/product/1404
# servo7 = servo.Servo(pca.channels[7], min_pulse=600, max_pulse=2500)
# This is an example for the Micro servo - TowerPro SG-92R: https://www.adafruit.com/product/169
# servo7 = servo.Servo(pca.channels[7], min_pulse=500, max_pulse=2400)
# The pulse range is 750 - 2250 by default. This range typically gives 135 degrees of
# range, but the default is to use 180 degrees. You can specify the expected range if you wish:
# servo7 = servo.Servo(pca.channels[7], actuation_range=135)
servo7 = servo.Servo(pca.channels[0])
# We sleep in the loops to give the servo time to move into position.
for i in range(180):
servo7.angle = i
time.sleep(0.03)
for i in range(180):
servo7.angle = 180 - i
time.sleep(0.03)
# You can also specify the movement fractionally.
fraction = 0.0
while fraction < 1.0:
servo7.fraction = fraction
fraction += 0.01
time.sleep(0.03)
pca.deinit()
參考資料
Introduction — Adafruit motor Library 1.0 documentation (circuitpython.org)
Introduction — Adafruit PCA9685 Library 1.0 documentation (circuitpython.org)