樹莓派4B-PCA9685驅動舵機

KevenDuan發表於2024-07-08

前言

不知道你們有沒有遇到過這麼一種情況,直接用樹莓派的引腳輸出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 輸出都具有較強的驅動能力,可以直接驅動舵機或者其他負載。

接線

  1. PCA9685綠端VCC和GND要和電池的正負極相連。
  2. PCA9685控制端的GND和VCC和樹莓派的3.3v(pin1)和GND(pin9)相連。
  3. 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)

相關文章