树莓派通过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这个数值需对每个舵机进行标定,有可能需要增大,有可能需要减小

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/20800.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

1. Mybatis基础操作

目录 1.1 需求 1.2 准备 1.3 删除 1.3.1 功能实现 1.3.2 日志输入 1.3.3 预编译SQL 1.3.3.1 介绍 1.3.3.2 SQL注入 1.3.3.3 参数占位符 1.4 新增 1.4.1 基本新增 1.4.2 主键返回 1.5 更新 1.6 查询 1.6.1 根据ID查询 1.6.2 数据封装 1.6.3 条件查询 1.6.4 参…

Virtualbox中对SD卡进行格式化和分区

系统:Ubuntu 22.04.4 LTS 方法一:在虚拟机的ubuntu系统中使用fdisk命令方式分区,具体请参考: imx6ull - 制作烧录SD卡-CSDN博客 方法二:使用Ubuntu自带GUI工具Disks Disks相比命令行工具更加简单无脑,用…

Nginx配置详细解释:(1)全局配置

自启动安装nginx:前面博客有解释 systemctl stop firewalld setenforce 0 [rootNode1 ~]#:mkdir /data [rootNode1 ~]#:cd /data [rootNode1 data]#:yum -y install gcc pcre-devel openssl-devel zlib-devel openssl openssl-devel [rootNode1 data]#:wget http://nginx.o…

数据恢复大革新!EasyRecovery16版本带来UIUX及性能的重大提升

全球领先的数据恢复解决方案提供商Ontrack与其中国区总代理近日共同宣布,其广受欢迎的数据恢复软件EasyRecovery16迎来了重大更新,版本号提升至v16.0.0.5。这一更新为用户带来了一系列值得关注的新功能和改进,进一步巩固了EasyRecovery在数据…

Apache Calcite - 自定义标量函数

前言 上一篇文章中我们介绍了calcite中内置函数的使用。实际需求中会遇到一些场景标准内置函数无法满足需求,这时候就需要用到自定义函数。在 Apache Calcite 中添加自定义函数,以便在 SQL 查询中使用自定义的逻辑。这对于执行特定的数据处理或分析任务…

1.1 OpenCV随手简记(一)

OpenCV学习篇 OpenCV (Open Source Computer Vision Library) 是一个开源的计算机视觉库,它提供了大量的算法和函数,用于图像处理、计算机视觉和机器学习等领域。 1. OpenCV 简介 1.1 OpenCV 的起源和发展 OpenCV 项目始于 1999 年,由 In…

【火猫欧洲杯】意甲:孔蒂亲自推动,送走尼日利亚锋霸

本赛季那不勒斯作为卫冕冠军发挥不佳,联赛仅仅排在第10名,休赛期他们率先炒掉了主帅卡尔佐纳,基本上锁定了前国米主帅孔蒂。孔蒂对于执教那不勒斯也非常期待,根据意大利媒体爆料,孔蒂已经开始准备推动转会,将球队的进攻核心奥斯梅恩卖掉,如果可以他想将自己的爱将卢卡库换回来。…

Java 22的FFM API,比起Java 21的虚拟线程

哪个对Java未来的发展影响更大?两个 Java 版本中的重要特性:Java 21 的虚拟线程和 Java 22 的 FFM API。我这里有一套编程入门教程,不仅包含了详细的视频讲解,项目实战。如果你渴望学习编程,不妨点个关注,给…

MPB | 林科院袁志林组-​内生镰刀菌基因组染色体级别组装和注释

内生镰刀菌基因组染色体级别组装和注释 Chromosome-Scale Genome Assembly and Annotation Method of Endophyte Fusarium 单晓亮1, 2,袁志林1, 2,* 1中国林业科学研究院林木遗传育种国家重点实验室,北京;2中国林业科学研究院亚热带林业研究…

DeepFace ——用于高级人脸识别算法探索与应用

1. 概述 人脸识别作为人工智能和机器学习中的一个活跃领域,长期以来一直在追求模仿甚至超越人类视觉系统的能力。这项技术在安全、监控、身份验证等多个方面都有着广泛的应用,但同时也伴随着隐私、伦理和准确性等社会和文化方面的考量。 Meta&#xff0…

苹果电脑数据丢失怎么办 苹果电脑数据恢复软件免费版 如何使用EasyRecovery恢复数据

无论是使用苹果电脑还是Windows电脑,丢失文件是一个常见的问题。无论是意外的删除、格式化错误还是系统崩溃,都可能导致重要数据的丢失。此时就需要用到数据恢复工具恢复数据。然而数据恢复工具的选择是十分重要的,踩坑了不仅找不回数据&…

超级SDK版本管理器VMR v0.6.1预览版发布!

项目地址:https://github.com/gvcgo/version-manager/releases/tag/v0.6.1 官方文档:https://gvcgo.github.io/vdocs/ 支持的语言列表: bun, clang, codon, deno, dlang, dotnet, elixir, erlang, flutter, gcc, gleam, go, groovy, jdk, …

【启程Golang之旅】从结构到接口揭秘Go的“面向对象”面纱

欢迎来到Golang的世界!在当今快节奏的软件开发领域,选择一种高效、简洁的编程语言至关重要。而在这方面,Golang(又称Go)无疑是一个备受瞩目的选择。在本文中,带领您探索Golang的世界,一步步地了…

ICPC训练赛补题集

ICPC训练赛补题集 文章目录 ICPC训练赛补题集D - Fast and Fat (负重越野)I-路径规划G. Inscryption(邪恶铭刻)NEW Houses雪中楼(西安交通大学)L.BracketGenerationE - Checksum D - Fast and Fat (负重越野) 原题链接:原题链接 题意:体重大的背体重小的…

【面试题-004】ArrayList 和 LinkList区别

ArrayList 和 LinkedList 都是 Java 中常用的动态数组实现,都实现了 List 接口,但它们在内部数据结构和性能方面有所不同: 内部数据结构: ArrayList 是基于动态数组的数据结构,它允许快速随机访问。数组的大小在创建时…

用java实现客服聊天+网络爬虫下载音乐(java网络编程,io,多线程)

一 灵感: 在2022年的暑假,也就是我即将迈进高三的那个暑假,我并没有察觉自己应该要学习了,还是和过往的暑假一样玩着王者荣耀,凌晨2点睡觉,中午12点起床。我依稀记得这种状态一直持续到8月19。然而离开学还…

【MySQL】Linux安装MySQL

一、center OS环境准备 为了在Linux系统中查看MySQL5.8与8.0版本的区别 我们要准备两个虚拟机,需要的软件:VMware和CentOS7 因为博主之前在学习redis的时候已经安装过一个虚拟机了,所以我就直接克隆了一个CentOS2.0 修改mac地址&#xff0…

STM32作业实现(二)串口控制led

目录 STM32作业设计 STM32作业实现(一)串口通信 STM32作业实现(二)串口控制led STM32作业实现(三)串口控制有源蜂鸣器 STM32作业实现(四)光敏传感器 STM32作业实现(五)温湿度传感器dht11 STM32作业实现(六)闪存保存数据 STM32作业实现(七)OLED显示数据 STM32作业实现(八)触摸按…

深入理解Java中的List集合:解析实例、优化技巧与最佳实践

一:List 集合的基础 1.1 什么是 List 集合? List 集合是 Java 集合框架中的一种有序、可重复的数据结构,它继承自Collection 接口,允许存储多个元素。 与数组不同,List 集合的大小是动态可变的,可以根据…

通过指针变量访问整型变量

有两个与指针变量有关的运算符: (1)&:取地址运算符。 (2)*:指针运算符(或称间接访问运算符)。 例如:&a为变量a的地址,*p为指针变量p所指向的存储单元。 编写程序: 运行结果…