当前位置: 首页 > news >正文

嵌入式人工智能(45-基于树莓派4B的扩展板-舵机驱动板PCA9685)

1、简介

智能小车、机械臂、摄像头云台会有多个舵机,而微控制器芯片的PWM输出引脚不够的情况下,就可以用PCA9685(16路舵机)来解决这一问题。

PCA9685是一款I2C总线控制的16通道LED控制器,专为红/绿/蓝/琥珀(RGBA)彩色背光应用而优化。每个LED输出都有自己的12位分辨率(4096步)固定频率单独PWM控制器,可在可编程频率下工作,典型频率为24 Hz到1526 Hz,占空比可调节从0%到100%,以使LED达到特定的亮度值。所有输出的PWM频率都设置为相同。

每个LED输出可以关闭或打开(无PWM控制),或设置为其单独的PWM控制器值。LED输出驱动器被编程为开漏,带有在5V时25mA的电流下沉能力,或者是totem极,带有在5V时25mA的下沉和10mA的源能力。PCA9685的工作电压范围为2.3V至5.5V,输入和输出均可容忍5.5V。LED可以直接连接到LED输出(高达25mA,5.5V),或通过外部驱动器和最少量的离散元件控制更大电流或更高电压的LED。

2、驱动板特性

• PCA9685允许交替的LED输出开启和关闭时间以最小化电流浪涌。每个16个通道的开启和关闭时间延迟可以独立编程。这个特性在PCA9635中不可用。

• PCA9685具有4096个步骤(12位PWM)的单独LED亮度控制。

• 当在系统中合并多个LED控制器时,如果使用PCA9635,多个设备之间的PWM脉冲宽度可能会有所不同。PCA9685具有可编程分频器,以调整多个设备的PWM脉冲宽度。

• PCA9685具有外部时钟输入引脚,可接受用户提供的时钟(最大50 MHz)代替内部25 MHz振荡器。此功能允许多个设备同步。PCA9635没有外部时钟输入功能。

• 与PCA9635一样,PCA9685也具有用于PWM控制的内置振荡器。但是,与PCA9635的典型频率97.6kHz相比,PCA9685用于PWM控制的频率可调节约为24 Hz至1526 Hz。这允许使用PCA9685与外部电源控制器。所有位都以相同的频率设置。

• LEDn输出引脚的上电复位(POR)默认状态在PCA9685的情况下为LOW。而对于PCA9635,则为HIGH。

• 所有PWM输出线上都放一个220欧姆系列电阻器来保护他们,并能轻易的驱动LED。

3、多驱动板级联

地址选择引脚使你可以把62个驱动板挂在单个12C总线上,总共有992路PWM输出,级联的每个驱动板都需要有一个唯一的访问地址。每个驱动板的初始I2C地址是0×40,可以通过右上角的跳线修改I2C地址。用焊锡将一个跳线连上就表示一个二进制数字“1”。有6个地址控制脚,通过这些引脚可以控制设备的i2c地址。7位的I2C地址为:0x40 + A5:A0

Board 0:  Address = 0x40 Offset = binary 00000 (默认)
Board 1:  Address = 0x41  Offset = binary 00001 (如上图,接上A0)
Board 2:  Address = 0x42  Offset = binary 00010 (接上A1)
Board 3:  Address = 0x43  Offset = binary 00011 (接上A0和A1)
Board 4:  Address = 0x44  Offset = binary 00100 (接上A2)

4、外部电源接入

大多数的舵机设计电压都是在5~6V,尤其在多个舵机同时运行时,跟需要有大功率的电源供电。如果直接使用5V引脚直接为舵机供电,会出现一些难以预测的问题,所以建议你能有个合适的外部电源为驱动板供电。中间上面的绿色接线柱,是提供外围输入电压,舵机后面提示外围输入供电电压不要超过6V。V+线上放置一个大电容(在某些场合你会需要) 外围输入最大电压取决于这个10V1000uf的电容。

PCA9685-16路舵机是一个采用IIC通信,内置了PWM驱动器和一个时钟,这个意味着,这将和TLCG940系列有很大不同,你不需要不断发送信号占用你的单片机。它是5V的兼容,这意味你还可以用3.3V单片机控制并且安全地驱动到6V输出(当你想要控制白色或蓝色指示灯用3.4+正电压也是可以的)。约1.6Khz可调频PWM输出,为步进电机准备输出12位分辨率,可配置的推拉输出或开路输出,输出使能引脚能够快速禁用所有输出。 

这个地方说明书上的意思我重新给同学们解释下。如果不仔细思考理解,可能很多同学有点晕。

VCC和V+这两个地方是有区别的。VCC是给PCA9685芯片供电的电压3-5V。而V+是给舵机供电的电压。那么问题来了,1是扩展板好几个地方都有V+,哪里是输入哪里是输出?2是V+的那个一会最大6V,一会6-10V是什么意思呢?

扩展板要给舵机供电,首先要有电压输入,如果仅接VCC,无法提供输出电压。要提供输出电压必须接上左图的绿色接线柱,这个输入电压范围为6-10V,然后V+的所有输出电压就有了。这个输出的电压都是来自绿色接线柱的输入电压,输入多少输出就是多少,但是为了保护舵机,扩展板提供稳压保护,即便输入的电压有9V,它输出的电压最大不超过6.5V,因为大多数舵机的工作电压5-6V。所以如果要带的舵机额定电压需要6.5V以上,就单独供电,把PWM信号线接扩展板即可。

这里我再扩展下,介绍输出电压、电流与负载的关系。这里我可以拿手机电池和手机充电器给大家举例。如果手机电池的的输入电压为5V,那么充电器的输出电压一定要5V才行不能大也不能小。如果输入电压大了不烧坏手机说明内部有保护的稳压电路,小了更不行,芯片不能工作。而充电器提供的输出电流则越大越好,当然价格也高,这个完全看负载所需的电流,只要电池所需要的输入电流小于等于充电器提供的输出电流都可以。但是要是充电器输出电流小于电池需要的输入电流则不行,它有一个阈值,低于阈值充不进去电,高于阈值则充电比较慢,也能充。舵机也是一样,所以最好是满足负载所需的电压和电流才行。

我们也做了很多实验了,树莓派或其他芯片提供的输出电压往往可以满足负载,但输出电流较弱,驱动大电流的设备往往需要单独供电。

5、电路原理图

6、PCA9685的驱动

该模块仍然采用IIC总线,可以查看其地址为0x40。


from __future__ import division
import logging
import time
import math# Registers/etc:
PCA9685_ADDRESS    = 0x40
MODE1              = 0x00
MODE2              = 0x01
SUBADR1            = 0x02
SUBADR2            = 0x03
SUBADR3            = 0x04
PRESCALE           = 0xFE
LED0_ON_L          = 0x06
LED0_ON_H          = 0x07
LED0_OFF_L         = 0x08
LED0_OFF_H         = 0x09
ALL_LED_ON_L       = 0xFA
ALL_LED_ON_H       = 0xFB
ALL_LED_OFF_L      = 0xFC
ALL_LED_OFF_H      = 0xFD# Bits:
RESTART            = 0x80
SLEEP              = 0x10
ALLCALL            = 0x01
INVRT              = 0x10
OUTDRV             = 0x04logger = logging.getLogger(__name__)class PCA9685(object):"""PCA9685 PWM LED/servo controller."""def __init__(self, address=PCA9685_ADDRESS, i2c=None, **kwargs):"""Initialize the PCA9685."""# Setup I2C interface for the device.if i2c is None:import Adafruit_GPIO.I2C as I2Ci2c = I2Cself._device = i2c.get_i2c_device(address, **kwargs)self.set_all_pwm(0, 0)self._device.write8(MODE2, OUTDRV)self._device.write8(MODE1, ALLCALL)time.sleep(0.005)  # wait for oscillatormode1 = self._device.readU8(MODE1)mode1 = mode1 & ~SLEEP  # wake up (reset sleep)self._device.write8(MODE1, mode1)time.sleep(0.005)  # wait for oscillatordef set_pwm_freq(self, freq_hz):"""Set the PWM frequency to the provided value in hertz."""prescaleval = 25000000.0    # 25MHzprescaleval /= 4096.0       # 12-bitprescaleval /= float(freq_hz)prescaleval -= 1.0logger.debug('Setting PWM frequency to {0} Hz'.format(freq_hz))logger.debug('Estimated pre-scale: {0}'.format(prescaleval))prescale = int(math.floor(prescaleval + 0.5))logger.debug('Final pre-scale: {0}'.format(prescale))oldmode = self._device.readU8(MODE1);newmode = (oldmode & 0x7F) | 0x10    # sleepself._device.write8(MODE1, newmode)  # go to sleepself._device.write8(PRESCALE, prescale)self._device.write8(MODE1, oldmode)time.sleep(0.005)self._device.write8(MODE1, oldmode | 0x80)def set_pwm(self, channel, on, off):"""Sets a single PWM channel."""self._device.write8(LED0_ON_L+4*channel, on & 0xFF)self._device.write8(LED0_ON_H+4*channel, on >> 8)self._device.write8(LED0_OFF_L+4*channel, off & 0xFF)self._device.write8(LED0_OFF_H+4*channel, off >> 8)def set_all_pwm(self, on, off):"""Sets all PWM channels."""self._device.write8(ALL_LED_ON_L, on & 0xFF)self._device.write8(ALL_LED_ON_H, on >> 8)self._device.write8(ALL_LED_OFF_L, off & 0xFF)self._device.write8(ALL_LED_OFF_H, off >> 8)

一共这个舵机控制类就4个函数,init为初始化函数,set_pwm_freq设置频率,set_pwm控制单个舵机,set_all_pwm控制全部舵机。

7、实验代码与现象

(1)我手头没有多个舵机,先用多个LED流水灯做实验,多个舵机的实验代码我也放到最后,回头拿到机械臂之后,我再想办法连接到树莓派上面。因为这个PCA9685的输出最大电压为6.5V。机械臂上有的舵机电压可能要大于6.5V。(我回头要实验看下,这个9685能否给机械臂提供供电)

(2)我们这边要控制多个LED的灯光,可以多个灯不同时亮暗,采用多线程实现。

import pca9685
import time
import threadingLed_pwm = pca9685.PCA9685(busnum=1)
Led_pwm.set_pwm_freq(600)  # 设置频率为60HZdef LED0_ctrl():for i in range(0,5000,10):Led_pwm.set_pwm(0,0,i)time.sleep(0.01)def LED1_ctrl():for i in range(0,3000,10):Led_pwm.set_pwm(1,0,i)time.sleep(0.01)def LED2_ctrl():for i in range(4000,0,-20):Led_pwm.set_pwm(2,0,i)time.sleep(0.03)
try:while True:t0=threading.Thread(target=LED0_ctrl)  # 多线程t1=threading.Thread(target=LED1_ctrl)t2=threading.Thread(target=LED2_ctrl)t0.start()   # 开启线程t1.start() t2.start() t0.join()t1.join()t2.join()
except KeyboardInterrupt:exit()

(3)Python有个专门的舵机旋转角度控制函数,我们安装这些库来调用。

# sudo pip install adafruit-circuitpython-pca9685
# sudo pip install adafruit-circuitpython-servokit

from adafruit_pca9685 import PCA9685
from board import SCL, SDA
import busio
from adafruit_motor import servoi2c_bus = busio.I2C(SCL, SDA)
pwm = PCA9685(i2c_bus)                                     # 使用默认地址初始化PWM设备
pwm.frequency = 50                                         # 将频率设置为50 Hz
servo_12 = servo.Servo(pwm.channels[12])                   # 指定第12通道的舵机(从0开始)
servo_15 = servo.Servo(pwm.channels[15])                   # 指定第15通道的舵机print('Moving servo on channel 0, press Ctrl-C to quit...')
servo_12.angle = 90
servo_15.angle = 90
while True:# 伺服电机转动最小角度和最大角度servo_12.angle = 0servo_15.angle = 0time.sleep(1)servo_12.angle = 180servo_15.angle = 180time.sleep(1)

可以接舵机试试,控制角度非常方便。

相关文章:

嵌入式人工智能(45-基于树莓派4B的扩展板-舵机驱动板PCA9685)

1、简介 智能小车、机械臂、摄像头云台会有多个舵机,而微控制器芯片的PWM输出引脚不够的情况下,就可以用PCA9685(16路舵机)来解决这一问题。 PCA9685是一款I2C总线控制的16通道LED控制器,专为红/绿/蓝/琥珀&#xff…...

【数据结构与算法】建立多个栈的三种方案的优缺点分析

在一个算法中需要建立多个栈时可以选用以下三种方案之一,试问这三方案相比各有什么优缺点? (1)分别用多个顺序存储空间建立多个独立的顺序栈。 (2)多个栈共享一个顺序存储空间。 (3)…...

DjangoRF-14-创建request子应用

注意,本应该是requests模块,为了区分,避免错误,用request 1、进入apps,创建request django-admin startapp request 2、因为只发送请求,没有数据库相关,不需要model。 3、进行序列化 from rest_framework …...

SOMEIP_ETS_005:检查字节序

测试目的: 验证DUT在发送和接收参数时对字节序的处理能力。 描述 本测试用例旨在检验DUT在处理具有不同字节序的参数时,是否能够正确地发送和接收数据,并确保返回的UINT32值是传入的两个参数(UINT8和UINT16)的和。 …...

为什么要对医疗器械进行网络安全评估?

对医疗器械进行网络安全评估的原因主要有以下几点: 一、保障患者安全 直接关联患者健康:医疗器械与患者的生命健康直接相关,任何网络安全漏洞都可能导致设备被非法控制或数据泄露,进而威胁患者的生命安全。例如,黑客可…...

沃尔玛1P账号的强悍作用重要反映在那些方面?——WAYLI威利跨境助力商家

沃尔玛作为全球最大的零售商之一,其品牌影响力非常强大。商家通过入驻沃尔玛商超并开设1P账号,能够借助沃尔玛的品牌影响力来提升自身的品牌知名度和美誉度。这种品牌背书的效应,有助于商家吸引更多的消费者关注和购买自己的产品。 一、沃尔玛…...

学习python你不能不知道的几个接单平台!实现如月上万不是梦

学Python后,寻找兼职平台是一个很好的实践和提升技能的方式。以下是一些比较推荐的Python兼职平台: 国内平台 程序员客栈 网址:https://www.proginn.com介绍:程序员客栈是中国非常领先的自由工作平台,为中高端程序员、…...

Golang面试题三(map)

1.map底层实现 由图看出,其实map的底层结构体是hmap,同时hmap里面维护着若干个bucket数组(即桶数组)。bucket数组中每个元素都是bmap结构的,bmap中存储着8个key-value的键值对,如果是满了的话,当…...

[windows10]win10永久禁用系统自动更新操作方法

WinR打开运行 输入regedit打开注册表 点击确定打开注册表 按照如下路径找到UX 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\WindowsUpdate\UX\Settings 在空白处点击鼠标右键,新建选择DWORD,然后重命名为FlightSettingsMaxPauseDays 双击FlightSet…...

《西行取经:大学生编程之路的禅悟与陷阱规避2》

《西行取经:大学生编程之路的禅悟与陷阱规避2》 阿弥陀佛,贫僧唐僧,虽身处古代,心却向往智慧之光。观今世大学生于编程之途,犹如我等西天取经,路途遥远且布满荆棘。今欲以吾之“取经”心得,为尔…...

JVM从入门到放弃

前言:关于JVM,其实有很多大厂开发了不同版本的JVM,比较知名的有:Sun HotSpot VM、BEA JRockit VM、IBM J9 VM、 Azul VM、 Apache Harmony、 Google Dalvik VM、 Microsoft JVM等等。现在使用的比较多的JDK8版本就是Sun HotSpot V…...

中国地面太阳总辐射逐日资料

数据内容 数据包含站点总辐射辐照度日数据 数据样例 Station_ID_CStaion_NameYearMonDayV1431154832寿光2023116.285754832寿光2023127.778354832寿光2023138.374454832寿光2023147.19154832寿光2023157.506254832寿光2023168.505254832寿光2023179.822154832寿光20231810.0…...

微商来客小程序系统源码分享

微商来客小程序系统源码,这是最新的V7.5.8版本微商来客小程序快速开发系统源码,可以无限开发生成小程序,支持快速生成微信小程序,支付宝小程序,百度小程序,QQ小程序,头条/抖音小程序。能创建的小…...

Java面试题--JVM大厂篇之Parallel GC与其他垃圾回收器的对比与选择

目录 引言: 正文: 结束语: 引言: Java工程师们,当我们在谈论JVM性能优化时,垃圾回收器(GC)无疑是一个绕不开的话题。而在所有的垃圾回收器中,Parallel GC无疑是一个备受关注的角色。今天,我们就来一探究…...

十分钟带你速通 Vue 组件

自定义组件 组件是可复用的 Vue 实例,在开发过程中,我们可以把重复用到的功能封装成自定义组件,达到便捷开发的目的。 组件的组织 通常一个应用会以一棵嵌套的组件树的形式来组织: 你可能会有头部导航、内容区、侧边栏等组件&a…...

基于RK3588+AI支持能源在线监测系统应用的AIOT产品方案

支持能源在线监测系统应用的AIOT产品方案 近年来,智慧能源行业受益于国家政策扶持、市场需求拉动和先进技术支撑呈现出了蓬勃发展态势。助推智慧能源发展,打造了支持能源在线监测系统应用的AIOT产品方案。 能源在线监测系统的市场潜力 随着社会经济的飞…...

山东大学考研机试题——整数序列

题目描述 传送门——AcWing 3717. 整数序列 - AcWing 很多整数可以由一段连续的正整数序列(至少两个数)相加而成,比如 2534567121325345671213。 输入一个整数 N,输出 N 的全部正整数序列,如果没有则输出 NONE。 输…...

一口酒一口水,不宜喝醉

一口酒一口水。这样交替着喝可以冲淡血液里的酒精浓度,但要注意不是往酒里兑水。 小口喝。每小时分解酒精的能力有限,如果超过负荷,血液里乙醛浓度会增加,引起酒醉。因此,喝酒时要尽量小口慢慢喝,给分解酒精…...

AI6-PPOCRLabel带GPU训练

一、移动PPOCRLabel 从anconda安装目录中找到PPOCRLabel文件夹,移动到PaddleOCR-release-2.8文件夹下 二、启动PPOCCRLabel cmd命令行进入paddle_py38环境,使用PPOCRLabel --lang ch来启动PPOCRLabel 三、打开图片文件夹自动标志 四、标签数据整理 …...

Unity四元数线性插值Lerp

inline glm::quat Lerp(glm::quat quat1, glm::quat quat2, float t)//普通插值 {t glm::clamp(t, 0.0f, 1.0f);return glm::normalize(quat1*(1-t)quat2*t); }...

QMC5883L的驱动

简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...

vue3+vite项目中使用.env文件环境变量方法

vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

算法:模拟

1.替换所有的问号 1576. 替换所有的问号 - 力扣(LeetCode) ​遍历字符串​:通过外层循环逐一检查每个字符。​遇到 ? 时处理​: 内层循环遍历小写字母(a 到 z)。对每个字母检查是否满足: ​与…...

用鸿蒙HarmonyOS5实现中国象棋小游戏的过程

下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...

6个月Python学习计划 Day 16 - 面向对象编程(OOP)基础

第三周 Day 3 🎯 今日目标 理解类(class)和对象(object)的关系学会定义类的属性、方法和构造函数(init)掌握对象的创建与使用初识封装、继承和多态的基本概念(预告) &a…...

结构化文件管理实战:实现目录自动创建与归类

手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...

【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架

文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...

MeshGPT 笔记

[2311.15475] MeshGPT: Generating Triangle Meshes with Decoder-Only Transformers https://library.scholarcy.com/try 真正意义上的AI生成三维模型MESHGPT来袭!_哔哩哔哩_bilibili GitHub - lucidrains/meshgpt-pytorch: Implementation of MeshGPT, SOTA Me…...

【笔记】AI Agent 项目 SUNA 部署 之 Docker 构建记录

#工作记录 构建过程记录 Microsoft Windows [Version 10.0.27871.1000] (c) Microsoft Corporation. All rights reserved.(suna-py3.12) F:\PythonProjects\suna>python setup.py --admin███████╗██╗ ██╗███╗ ██╗ █████╗ ██╔════╝…...

RLHF vs RLVR:对齐学习中的两种强化方式详解

在语言模型对齐(alignment)中,强化学习(RL)是一种重要的策略。而其中两种典型形式——RLHF(Reinforcement Learning with Human Feedback) 与 RLVR(Reinforcement Learning with Ver…...