树莓派4B-PCA9685驱动舵机

前言

不知道你们有没有遇到过这么一种情况,直接用树莓派的引脚输出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))

原创作者: kevenduan 转载于: https://www.cnblogs.com/kevenduan/p/18289747
1.1python软件的安装 先安装python软件优先,因为其他步骤如果用到sudo apt-get update 会导致python程序不是py2而是py3,就用不了我们的程序了 树莓派鼓励用户使用python和C++作为其开发语言,所以原则上可以不用安装python的编译器,但是树莓派自带的python(IDLE)和Thonny python IDE都过于简陋,不太适合python使用者进行复杂的OpenCV开发。在这里推荐Spyder作为树莓派的python IDE。这种编译器相对上述两种编译器略显笨重,但是对内核和运算值的控制更加灵活。   树莓派安装Spyder非常的方便,在命令行输入: sudo apt-get install spyder 下载时间可能比较长,因为在安装spyder3的同时很多python开发开发必要的依赖也一并被安装到树莓派里了,这也说明牺牲一定的空间下载spyder3是值得的。此时,我们已经可以在树莓派的开始菜单-programming中看到编译器了。注意: 1、 在下载spyder之前请不要输入 “sudo apt-get update/upgrade”, 否则会下载适用于python3.6的spyder,无法正常使用,比如图1-0中的spyder的python版本就是3.6,说明下载出现错误。 2、 如果看不到编译器说明安装过程出错,尝试重新执行:sudo apt-get update和 sudo apt-get install spyder3两条命令。   图 1-0下载完成后,在“start”中已经能看到Spyder编译器了     图 1-00 Spyder3的Python3.6版本 我们可以在preference/syntax coloring scheme中更换自己喜欢的主题,怎么样?是不是已经觉得树莓派和普通PC一样方便了呢?现在我们已经可以用在树莓派上舒适的开发python了。
### 树莓派 PCA9685 使用教程 #### 配置环境 为了使树莓派能够成功配置并使用PCA9685模块,需确保已安装必要的库文件。对于Python编程而言,`Adafruit_PCA9685` 库是一个不错的选择。可以通过pip工具来完成此库的安装: ```bash pip install adafruit-circuitpython-pca9685 ``` #### 初始化PCA9685对象 创建一个代表PCA9685硬件实例的对象时,可以指定其I2C地址以及所使用的I2C总线号。默认情况下,PCA9685的I2C地址为 `0x40` 或者有时也可能是 `0x41`;而树莓派上的标准I2C接口通常是 `/dev/i2c-1` 对应于总线编号 `1`。 ```python import board import busio as io import adafruit_pca9685 i2c_bus = io.I2C(board.SCL, board.SDA) pwm = adafruit_pca9685.PCA9685(i2c_bus, address=0x41)[^1] ``` 这段代码初始化了一个新的I2C连接,并指定了PCA9685的具体位置和通信参数。 #### 设置PWM频率 PCA9685支持多种PWM频率设置,默认值可能不适合某些应用场合下的需求。例如,在控制舵机的情况下,通常会将频率设定为约50Hz左右较为合适。 ```python pwm.frequency = 50 ``` 这一步骤非常重要,因为不同的负载(如电机、LED灯条等)往往需要特定范围内的脉冲宽度调制信号才能正常工作[^2]。 #### 控制单个通道输出 一旦完成了上述准备工作之后就可以开始向各个独立的PWM输出端口写入数值了。这里给出一段简单的例子用于调整第0号通道至最大亮度状态: ```python channel_num = 0 max_value = 4095 # 占空比的最大值取决于寄存器位宽 min_value = 1024 # 舵机最小占空比对应的值 mid_value = (max_value + min_value) // 2 # 将指定通道设为全亮 pwm.channels[channel_num].duty_cycle = mid_value ``` 以上操作实现了对单一PWM信道强度等级的精确调控功能。 #### 完整示例程序 下面提供了一段完整的Python脚本作为参考,它展示了如何利用PCA9685实现多路舵机的同时驱动效果。 ```python import time from board import SCL, SDA import busio as io from adafruit_pca9685 import PCA9685 def set_servo_angle(pca, channel, angle): """Set the specified servo to a specific angle.""" duty_cycle = int((angle / 180) * max_duty_cycle + min_duty_cycle) pca.channels[channel].duty_cycle = duty_cycle if __name__ == '__main__': i2c_bus = io.I2C(SCL, SDA) pwm = PCA9685(i2c_bus, address=0x41) pwm.frequency = 50 num_channels = 16 min_duty_cycle = 1024 max_duty_cycle = 4095 try: while True: for ch in range(num_channels): set_servo_angle(pwm, ch, 0) time.sleep(0.5) for ch in range(num_channels): set_servo_angle(pwm, ch, 90) time.sleep(0.5) for ch in range(num_channels): set_servo_angle(pwm, ch, 180) time.sleep(0.5) except KeyboardInterrupt: pass finally: print('Program terminated.') ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值