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

树莓派通过PCA9685控制FT2331M舵机(Python)

        很久之前整过PWM舵机,刚好最近师弟需要,并且网上现有教程不是很完整,就整理一下。方便交流以及后面回顾。

        首先要明确,在这个控制方式中需要用到哪些方面:

1、树莓派与PCA9685之间使用I2C通信

2、PCA9685通讯协议

3、FT2331M舵机性能参数

        一、树莓派与PCA9685 I2C通信

        接线        

        接线方式可如下图所示,参考树莓派4B使用PCA9685控制舵机:

         其中VCC供电为6V.

        开启I2C:

        在终端执行:

sudo raspi-config
Interfacing Options-->I2C-->YES-->Finish 

        保险起见 重启树莓派 终端输入 :

sudo reboot

        安装相关库文件:

sudo apt-get update
sudo apt-get install python-pip 
sudo pip install RPi.GPIO
sudo apt-get install python-smbus

        开启I2C并且完成树莓派与PCA9685接线之后,可以通过如下命令查看设备是否正常搭载:

ls /dev/*i2c*

        查看I2C搭载设备地址:

pi@raspberrypi:~ $ sudo i2cdetect -y 1  # 默认为I2C1,如果是I2C0.则只需要将1-->0即可

        关于I2C设备的操作,详细可看之前的文章关于树莓派4B两个I2C通道(I2C0、I2C1)的总结 。

        二、PCA9685通讯协议

相关代码我放在文中,并且有具体注释

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__)def software_reset(i2c=None, **kwargs):"""Sends a software reset (SWRST) command to all servo drivers on the bus."""# Setup I2C interface for device 0x00 to talk to all of them.if i2c is None:import Adafruit_GPIO.I2C as I2Ci2c = I2Cself._device = i2c.get_i2c_device(0x00, **kwargs)self._device.writeRaw8(0x06)  # SWRSTclass 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)def cmd(self, channel, Position):'''已经进行数据转换,position范围0-210度''''''PCA9685是一种PWM控制器,可以产生从0到4096之间的脉宽值,对应于PWM信号的高电平时间PWM频率被设置为60Hz,周期的时间为 1 / 60 秒,即约 16.67 毫秒(16666 微秒)servo_min = 150  # Min pulse length out of 4096servo_max = 600  # Max pulse length out of 4096servo_min 的实际脉宽时间为 (150 / 4096) * 16666 微秒 ≈ 610 微秒servo_max 的实际脉宽时间为 (600 / 4096) * 16666 微秒 ≈ 2440 微秒Ft2331舵机参数为0~240°对应500~2500us'''servo_min = int(500 * 60 / 1000000 * 4096)  # Min pulse length out of 4096servo_max = int(2500 * 60 / 1000000 * 4096)  # Max pulse length out of 4096Position = int(Position / (240 - 0) * (servo_max - servo_min) + servo_min)  # 240这个数值需对每个舵机进行标定,有可能需要增大,有可能需要减小self.set_pwm(channel, 0, Position)pwm = PCA9685()
pwm.set_pwm_freq(60)
channel = 0while True:pwm.cmd(channel, 0)time.sleep(1)pwm.cmd(channel, 90)time.sleep(1)pwm.cmd(channel, 180)time.sleep(1)pwm.cmd(channel, 90)time.sleep(1)

        三、FT233M1舵机参数

 舵机控制参数如下所示:

        从旋转角度那一栏可知,舵机由0-240°,对应周期时间为500-2500us。 

所以在第二节中的协议中,控制函数cmd(self, channel, Position)中存在(同样和通信频率有关),如下代码:

'''PCA9685是一种PWM控制器,可以产生从0到4096之间的脉宽值,对应于PWM信号的高电平时间PWM频率被设置为60Hz,周期的时间为 1 / 60 秒,即约 16.67 毫秒(16666 微秒)servo_min = 150  # Min pulse length out of 4096servo_max = 600  # Max pulse length out of 4096servo_min 的实际脉宽时间为 (150 / 4096) * 16666 微秒 ≈ 610 微秒servo_max 的实际脉宽时间为 (600 / 4096) * 16666 微秒 ≈ 2440 微秒Ft2331舵机参数为0~240°对应500~2500us'''servo_min = int(500 * 60 / 1000000 * 4096)  # Min pulse length out of 4096servo_max = int(2500 * 60 / 1000000 * 4096)  # Max pulse length out of 4096Position = int(Position / (240 - 0) * (servo_max - servo_min) + servo_min)  # 240这个数值需对每个舵机进行标定,有可能需要增大,有可能需要减小

相关文章:

  • python 构造函数
  • 【mybatis解决oracle查询in超过1000条数据】
  • Redis数据类型(上篇)
  • vue+antd实践:在输入框光标处插入内容
  • P9 【力扣+知识点】【算法】【二分查找】C++版
  • Cocos入门2:软件安装
  • Spring MVC 工作流程源码分析
  • Python爬虫之简单学习BeautifulSoup库,学习获取的对象常用方法,实战豆瓣Top250
  • 新能源汽车推行精益生产:绿色动力下的效率革命
  • 使用Lua基本实现分布式锁并自动续期
  • 代码随想录35期Day54-JavaScript
  • 通过LabVIEW提升生产设备自动化水平
  • centos7.8安装Mysql8.4
  • QT实现动态翻译切换
  • linux的磁盘分区与管理
  • Spark VS Hadoop:两大大数据分析系统深度解读
  • uva 10370 Above Average
  • Webpack 4 学习01(基础配置)
  • 对超线程几个不同角度的解释
  • 浅谈web中前端模板引擎的使用
  • 深度学习中的信息论知识详解
  • 试着探索高并发下的系统架构面貌
  • 数组的操作
  • 它承受着该等级不该有的简单, leetcode 564 寻找最近的回文数
  • 微服务入门【系列视频课程】
  • 主流的CSS水平和垂直居中技术大全
  • Python 之网络式编程
  • Semaphore
  • ‌[AI问答] Auto-sklearn‌ 与 scikit-learn 区别
  • #我与Java虚拟机的故事#连载09:面试大厂逃不过的JVM
  • %3cli%3e连接html页面,html+canvas实现屏幕截取
  • ( 用例图)定义了系统的功能需求,它是从系统的外部看系统功能,并不描述系统内部对功能的具体实现
  • (ISPRS,2023)深度语义-视觉对齐用于zero-shot遥感图像场景分类
  • (备份) esp32 GPIO
  • (二)Eureka服务搭建,服务注册,服务发现
  • (二)Linux——Linux常用指令
  • (二十六)Java 数据结构
  • (四)事件系统
  • (五)activiti-modeler 编辑器初步优化
  • (原创)Stanford Machine Learning (by Andrew NG) --- (week 9) Anomaly DetectionRecommender Systems...
  • (转)LINQ之路
  • (转)Oracle 9i 数据库设计指引全集(1)
  • (转)关于如何学好游戏3D引擎编程的一些经验
  • (转载)(官方)UE4--图像编程----着色器开发
  • ./configure、make、make install 命令
  • .dat文件写入byte类型数组_用Python从Abaqus导出txt、dat数据
  • .NET 4 并行(多核)“.NET研究”编程系列之二 从Task开始
  • .NET 8.0 发布到 IIS
  • .Net Remoting常用部署结构
  • .NET 漏洞分析 | 某ERP系统存在SQL注入
  • .NET 使用配置文件
  • .NET4.0并行计算技术基础(1)
  • .NET关于 跳过SSL中遇到的问题
  • .NET设计模式(2):单件模式(Singleton Pattern)
  • @Autowired自动装配