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

实例4:树莓派GPIO控制舵机转动

实例4:树莓派GPIO控制舵机转动

实验目的

  1. 通过背景知识学习,了解舵机的外观及基本运动方式。
  2. 了解四足机器人mini pupper腿部单个舵机的组成结构。
  3. 通过GPIO对舵机进行转动控制,熟悉PWM。
  4. 了解mini pupper舵机组的整体调零。

实验要求

使用Python语言编程,在编程中使用PWM方法,通过树莓派GPIO控制外部舵机来回摆动,角度范围为0°~180°,周期为四秒。

实验知识

1. 什么是舵机?

舵机(servomotor)是一种简化版本的伺服电机,是位置伺服的驱动器,能够通过输入PWM信号控制旋转角度,具备轻量、小型、简化和性价比高的特点。
舵机适用于那些需要角度不断变化并可以保持的简单控制系统,它能实现较为精确的电机控制,在航模、遥控玩具、机器狗等品类上运用良好。
在这里插入图片描述

图片1:一般舵机的外观

2. 舵机的运动方式

舵机的运动方式是绕轴摆动,“舵机”一词也和它的运动方式有关,舵机常用来摆动调整方向,就像海洋上的水手的舵一样,航模和船模常常用舵机的摆动来调整一些零部件的角度。

图片2:舵机的运动动图

3. 舵机的组成结构

舵机一般是由保护外壳、内部集成控制芯片、小型直流电机、减速器齿轮组、位置检测单元构成的。

当主控给舵机发出转动信号时,控制芯片驱动电机开始转动,通过减速器将动力传达到输出轴上的摆臂,由位置检测单元反馈转动结果信号给主控进行反馈调节。
一般来说,位置检测单元可以是可变电阻,当舵机转动时,可变电阻随之改变,由此可得转动的角度信息。舵机包含了电机、传感器和控制器,是一个集成度高的、完整的伺服电机系统。
在这里插入图片描述

图片3:舵机的内部结构拍摄

4. mini pupper定制舵机的部分硬件参数

芒砀科技MANGDANG针对mini pupper的运动需求,在原型舵机的基础上优化改进了机械结构,定制了mini pupper专用舵机,这使得mini pupper的控制更加精确、动力更加澎湃。
在这里插入图片描述
图片3:定制舵机的外观

参考链接:mini pupper定制电机规格书 课程附件 MiniPupper-Servo-Spec.pdf

5.mini pupper舵机的控制方法

对于舵机的控制,首先要了解其基本硬件参数以及舵机对信号通讯的要求。
如图所示,mini pupper一代舵机允许PWM的直接使用,也就是说,舵机可以直接连接到树莓派上的GPIO_PWM端口使用而不需要考虑通讯协议,这对机器人入门开发者来说较为友好。
在这里插入图片描述
图片4:舵机端口的连线

mini pupper一代舵机部分参数表

namevalue
端口1(黄)PWM Signal
端口2(红)Vcc
端口3 (棕)GND
信号周期20ms
信号频率50HZ
脉冲长度范围500us-2500us to 0°~180°
脉冲长度对应占空比2.5% - 12.5%
信号高电平范围2V-5V
信号低电平范围0.0V-0.45V
中间位对应脉冲1500 μsec

需要注意的是:
占空比=脉宽/周期
脉宽500us-2500us对应的占空比为2.5% - 12.5%

6. RPi的GPIO库中PWM的用法

import RPi.GPIO as GPIO	#	引入GPIO库
GPIO.setmode(GPIO.BOARD) #初始化GPIO引脚编码方式,需放在代码正式开始处
GPIO.setup(12, GPIO.OUT) #初始化GPIO引脚设置,需放在代码正式开始处
p = GPIO.PWM(channel, frequency)	#	创建pwm实例 channel为引脚号 frequency为频率
p.start(dc)	#	开始pwm	dc为初始占空比(0.0 <= dc <= 100.0)
p.stop() # 停止pwm
p.ChangeFrequency(freq)   # 改变频率(Hz)freq
p.ChangeDutyCycle(dc)  # 改变占空比(0.0 <= dc <= 100.0)
GPIO.cleanup() # 清理GPIO引脚

参考链接:RPi GPIO库中PWM()函数的详细资料

实验步骤

1. 编写Python程序 servo_PWM_GPIO.py

#!/usr/bin/python
# coding:utf-8
# servo_PWM_GPIO.py
# 树莓派GPIO控制外部舵机来回摆动,角度范围为0~180°,周期为4秒。
try:import RPi.GPIO as GPIO
except RuntimeError:print("Error importing RPi.GPIO!  This is probably because you need superuser privileges. "" You can achieve this by using 'sudo' to run your script")
import timedef servo_map(before_value, before_range_min, before_range_max, after_range_min, after_range_max):"""功能:将某个范围的值映射为另一个范围的值参数:原范围某值,原范围最小值,原范围最大值,变换后范围最小值,变换后范围最大值返回:变换后范围对应某值"""percent = (before_value - before_range_min) / (before_range_max - before_range_min)after_value = after_range_min + percent * (after_range_max - after_range_min)return after_valueGPIO.setmode(GPIO.BOARD)  # 初始化GPIO引脚编码方式
servo_SIG = 32
servo_VCC = 4
servo_GND = 6
servo_frec = 50
servo_time = 0.01
servo_width_min = 2.5
servo_width_max = 12.5
# servo_degree_div =servo_width_max - servo_width_min)/180
GPIO.setup(servo_SIG, GPIO.OUT)
# 如果你需要忽视引脚复用警告,请调用GPIO.setwarnings(False)
# GPIO.setwarnings(False)
servo = GPIO.PWM(servo_SIG, servo_frec)  # 信号引脚=servo_SIG 频率=servo_frec in HZ
servo.start(0)
servo.ChangeDutyCycle(servo_width_min)  # 回归-90°
print('预设置完成,两秒后开始摆动')
time.sleep(2)
try:  # try和except为固定搭配,用于捕捉执行过程中,用户是否按下ctrl+C终止程序while 1:for dc in range(1, 181, 1):dc_trans = servo_map(dc, 0, 180, servo_width_min, servo_width_max)servo.ChangeDutyCycle(dc_trans)# print(dc_trans)time.sleep(servo_time)time.sleep(0.2)for dc in range(180, -1, -1):dc_trans = servo_map(dc, 0, 180, servo_width_min, servo_width_max)servo.ChangeDutyCycle(dc_trans)# print(dc_trans)time.sleep(servo_time)time.sleep(0.2)
except KeyboardInterrupt:pass
servo.stop()  # 停止pwm
GPIO.cleanup()  # 清理GPIO引脚

2. 运行程序servo_PWM_GPIO.py并观察效果

在servo_PWM_GPIO.py的目录下执行以下命令:

sudo python servo_PWM_GPIO.py

此时应观察到舵机在树莓派的控制下来回摆动,角度范围为0°~180°,周期为四秒。

3. 尝试运行Python程序 servo_PWM_GPIO_2.py[可选]

如果你希望尝试手动输入一个角度值来转动舵机,你可以试试servo_PWM_GPIO_2.py

#!/usr/bin/python
# coding:utf-8
# servo_PWM_GPIO_2.py
# 输入一个角度值,舵机将转动到对应的角度
try:import RPi.GPIO as GPIO
except RuntimeError:print("Error importing RPi.GPIO!  This is probably because you need superuser privileges. "" You can achieve this by using 'sudo' to run your script")
import timedef servo_map(before_value, before_range_min, before_range_max, after_range_min, after_range_max):"""功能:将某个范围的值映射为另一个范围的值参数:原范围某值,原范围最小值,原范围最大值,变换后范围最小值,变换后范围最大值返回:变换后范围对应某值"""percent = (before_value - before_range_min) / (before_range_max - before_range_min)after_value = after_range_min + percent * (after_range_max - after_range_min)return after_valueGPIO.setmode(GPIO.BOARD)  # 初始化GPIO引脚编码方式
servo_SIG = 32
servo_VCC = 4
servo_GND = 6
servo_frec = 50
servo_time = 0.01
servo_width_min = 2.5
servo_width_max = 12.5
# servo_degree_div =servo_width_max - servo_width_min)/180
GPIO.setup(servo_SIG, GPIO.OUT)
# 如果你需要忽视引脚复用警告,请调用GPIO.setwarnings(False)
# GPIO.setwarnings(False)
servo = GPIO.PWM(servo_SIG, servo_frec)  # 信号引脚=servo_SIG 频率=servo_frec in HZ
servo.start(0)
servo.ChangeDutyCycle(servo_width_min)  # 回归-90°
print('预设置完成,两秒后开始等待输入')
time.sleep(2)
# 为舵机指定位置
try:    # try和except为固定搭配,用于捕捉执行过程中,用户是否按下ctrl+C终止程序while 1:position = input("请输入0°-180°的角度值:\n")if position.isdigit()==1:dc = int(position)if (dc>=0) and (dc<=180):dc_trans=servo_map(dc, 0, 180,servo_width_min,servo_width_max)servo.ChangeDutyCycle(dc_trans)print("已转动到%d°处"%dc)else:print("Error Input:Exceed Range")else:print("Error Input:Not Int Input")
except KeyboardInterrupt:passservo.stop()  # 停止pwm
GPIO.cleanup()  # 清理GPIO引脚

4.尝试调零[可选]

为了确保控制精度,mini pupper上的舵机组通常在使用前先进行一次调零。
试试在命令行中运行舵机调零脚本 run_set_neatral.sh

sudo ./run_set_neatral.sh
#!/usr/bin/env sh# step 1 stop robot service
systemctl stop robot# step 2 set neatral positionecho 1500000 > /sys/class/pwm/pwmchip0/pwm0/duty_cycle
echo "pwm 0 setting pwm off parameter --> 90 degree "echo 1500000 > /sys/class/pwm/pwmchip0/pwm1/duty_cycle
echo "pwm 1 setting pwm off parameter --> 90 degree"echo 500000 > /sys/class/pwm/pwmchip0/pwm2/duty_cycle
echo "pwm 2 setting pwm off parameter --> 0 degree"echo 2500000 > /sys/class/pwm/pwmchip0/pwm3/duty_cycle
echo "pwm 3 setting pwm off parameter --> 180 degree"sleep 1echo "Done ! "

如果希望了解校准的详细信息,你可以查看mini pupper的官方文档:校准

确保 Mini Pupper 已预先组装好,使用GUI校准工具来优化腿部的位置。
对于每条腿,移动杆,使所有腿都成 45 度角。 腿的角度会随着滑动条在屏幕上的位置而变化。
如果它不动,则说明您执行的步骤不正确。
您可以使用 iPhone 的倾斜传感器app、尺子或量角器来测量角度。

实验总结

经过本知识点的学习和实验操作,你应该能达到以下水平:

知识点内容了解熟悉掌握
舵机舵机的外观及基本运动方式
舵机单个舵机的组成结构
PWMPWM方法对舵机进行转动控制
调零与校准mini pupper舵机组的调零与校准

版权信息:教材尚未完善,此处预留版权信息处理方式
mini pupper相关内容可访问:https://github.com/mangdangroboticsclub

相关文章:

实例4:树莓派GPIO控制舵机转动

实例4&#xff1a;树莓派GPIO控制舵机转动 实验目的 通过背景知识学习&#xff0c;了解舵机的外观及基本运动方式。了解四足机器人mini pupper腿部单个舵机的组成结构。通过GPIO对舵机进行转动控制&#xff0c;熟悉PWM。了解mini pupper舵机组的整体调零。 实验要求 使用Py…...

【音视频处理】为什么MP3不是无损音乐?音频参数详解,码率、采样率、音频帧、位深度、声道、编码格式的关系

大家好&#xff0c;欢迎来到停止重构的频道。上期我们讨论了视频的相关概念&#xff0c;本期我们讨论音频的相关概念。包括采样率、码率、单双声道、音频帧、编码格式等概念。这里先抛出一个关于无损音频的问题。为什么48KHz采样率的.mp3不是无损音乐 &#xff0c;而48KHz采样率…...

Linux 环境变量

Linux 环境变量能帮你提升 Linux shell 体验。很多程序和脚本都通过环境变量来获取系统信息、存储临时数据和配置信息。在 Linux 系统上有很多地方可以设置环境变量&#xff0c;了解去哪里设置相应的环境变量很重要。 认识环境变量 bash shell 用环境变量&#xff08;environme…...

从功能测试(点点点)到进阶自动化测试,实现薪资翻倍我只用了3个月时间

前言 从事测试工作已3年有余了&#xff0c;今天想聊一下自己刚入门时和现在的今昔对比&#xff0c;虽然现在也没什么成就&#xff0c;只能说笑谈一下自己的测试生涯&#xff0c;各位看官就当是茶余饭后的吐槽吧&#xff0c;另外也想写一写自己的职场感想&#xff0c;希望对刚开…...

aspnetcore 原生 DI 实现基于 key 的服务获取

你可能想通过一个字符串或者其他的类型来获取一个具体的服务实现&#xff0c;那么在 aspnetcore 原生的 MSDI 中&#xff0c;如何实现呢&#xff1f;本文将介绍如何通过自定义工厂来实现。我们现在恰好有基于 Json 和 MessagePack 的两种序列化器有一个接口是这样的publicinter…...

华为OD机试 -最大子矩阵和(Python) | 机试题+算法思路+考点+代码解析 【2023】

最大子矩阵和 题目 给定一个二维整数矩阵 要在这个矩阵中 选出一个子矩阵 使得这个子矩阵内所有的数字和尽量大 我们把这个子矩阵成为“和最大子矩阵” 子矩阵的选取原则,是原矩阵中一段相互连续的矩形区域 输入 输入的第一行包含两个整数N,M (1 <= N,M <= 10) 表示…...

C2驾照科一学习资料(1)

目录 记1分 记3分 记6分 记9分 记12分 你有不伤别人的教养 却缺少一种不被人伤的气场 若没人护你周全 就请善良中带点锋芒为自己保驾护航 这个世界你若好到毫无保留 对方就会坏到肆无忌惮 记1分 《道路交通安全违法行为记分管理办法》规定&#xff0c;机动车驾驶人有下列…...

4576: 移动数组元素

描述给定一个n个元素的一维数组&#xff0c;将下标从0到p的元素全部平移到数组尾部。输入第一行有两个正整数n和p&#xff08;2<n<100&#xff0c;0<p<n&#xff09;。第二行有n个整数&#xff0c;表示数组的各个元素。输出在一行中按顺序输出移动后的各个数组元素…...

字符串中<br>处理

需求&#xff1a; 后端返回的字符串中带有br换行符&#xff0c;前端需要处理行内及行尾的换行符。具体需求可分为以下两个&#xff1a; 若是字符串末尾有换行符&#xff0c;需要去掉。若是字符串内有换行符&#xff0c;有两种需求&#xff1a;①将换行符转换成逗号或其它符号&…...

大数据技术原理与应用介绍

大数据技术原理与应用 概述 大数据不仅仅是数据的“大量化”&#xff0c;而是包含“快速化”、“多样化”和“价值化”等多重属性。 两大核心技术&#xff1a;分布式存储和分布式处理 大数据计算模式 批处理计算流计算图计算查询分析计算 大数据具有数据量大、数据类型繁…...

【Python】序列与列表(列表元素的增删改查,求之,列表推导式、列表的拷贝)

一、序列序列的概念&#xff1a;按照某种顺序排列的数据类型就叫做序列&#xff0c;比如字符串&#xff0c;列表&#xff0c;元组&#xff0c;集合序列的共同点是都有下标&#xff0c;支持index()方法和count()&#xff0c;也支持切片处理(等同于字符串序列的切片处理)l1 [0, …...

update导致死锁

update delete 操作&#xff0c;如果走的索引&#xff0c;对索引和主键索引加行锁 如果没有走索引&#xff0c;锁整张表。 不开启事务&#xff0c;mysql本身也会加锁 一般MYSQL在执行CREATE,ALTER,INSERT等命令时会自动加锁 在对数据进行更新操作时 如果update没用到索引&…...

Java 集合 --- 如何遍历Map

Java 集合 --- 如何遍历MapMap的基本操作如何遍历MapType of HashMapMap没有继承Collection接口AbstractMap和AbstractCollection是平级关系 Map的基本操作 package map; import java.util.*; /*** This program demonstrates the use of a map with key type String and val…...

C#从值类型、引用类型到装箱和拆箱

上一篇文章讲了C#的值类型和引用类型&#xff0c;这里再来看看值类型和引用类型最直接的使用场景&#xff1a;装箱和拆箱。 一、基本概念 装箱&#xff1a;值类型转化为引用类型的过程。从托管堆中为新生成的引用类型对象分配内存,再把值类型的实例字段拷贝到托管堆上新对象的…...

Java中的逻辑运算符/移位运算符简单总结

前段时间刷到了力扣关于位运算的题&#xff0c;这里浅浅记录一下&#xff01; 1. 逻辑位运算 1.1 与 & &&#xff1a;按位与进行二进制计算&#xff0c;规则是同为1则为1&#xff0c;不同为0&#xff0c;具体如下&#xff1a; 0&00, 0&10, 1&00, 1&…...

活动预告 | GAIDC 全球人工智能开发者先锋大会

大会主题——“向光而行的 AI 开发者” 2023 全球人工智能开发者先锋大会&#xff08;GAIDC&#xff09; 由世界人工智能大会组委会、上海市经济和信息化委员会、上海市人才工作领导小组办公室及中国&#xff08;上海&#xff09;自由贸易试验区临港新片区管理委员会指导&…...

【Linux系统】认识操作系统和操作系统如何进行管理以及进程相关状态

进程概念1 认识冯诺依曼体系结构1.1 冯诺依曼体系结构存储器的作用2 操作系统(Operator System&#xff0c;OS)2.1 OS如何进行管理3 进程3.1 OS管理进程&#xff1a;先描述再组织3.2 描述进程-PCB3.3 查看进程3.4 通过系统调用获取进程标识符3.5 通过系统调用创建子进程——for…...

【0基础学爬虫】爬虫基础之HTTP协议的基本原理介绍

大数据时代&#xff0c;各行各业对数据采集的需求日益增多&#xff0c;网络爬虫的运用也更为广泛&#xff0c;越来越多的人开始学习网络爬虫这项技术&#xff0c;K哥爬虫此前已经推出不少爬虫进阶、逆向相关文章&#xff0c;为实现从易到难全方位覆盖&#xff0c;特设【0基础学…...

SpringBoot 整合定时任务

注解概览 EnableScheduling 在配置类上使用&#xff0c;开启计划任务的支持&#xff08;类上&#xff09; Scheduled 来申明这是一个任务&#xff0c;包括cron,fixDelay,fixRate等类型&#xff08;方法上&#xff0c;需先开启计划任务的支持&#xff09; pom依赖 <parent…...

我的零分周赛:CSDN周赛第30期,成绩“0”分,天然气定单、小艺读书、买苹果、圆桌

CSDN周赛第30期&#xff0c;成绩“0”分&#xff0c;天然气定单、小艺读书、买苹果&#x1f34e;、圆桌。 (本文获得CSDN质量评分【91】)【学习的细节是欢悦的历程】Python 官网&#xff1a;https://www.python.org/ Free&#xff1a;大咖免费“圣经”教程《 python 完全自学教…...

idea大量爆红问题解决

问题描述 在学习和工作中&#xff0c;idea是程序员不可缺少的一个工具&#xff0c;但是突然在有些时候就会出现大量爆红的问题&#xff0c;发现无法跳转&#xff0c;无论是关机重启或者是替换root都无法解决 就是如上所展示的问题&#xff0c;但是程序依然可以启动。 问题解决…...

Vue记事本应用实现教程

文章目录 1. 项目介绍2. 开发环境准备3. 设计应用界面4. 创建Vue实例和数据模型5. 实现记事本功能5.1 添加新记事项5.2 删除记事项5.3 清空所有记事 6. 添加样式7. 功能扩展&#xff1a;显示创建时间8. 功能扩展&#xff1a;记事项搜索9. 完整代码10. Vue知识点解析10.1 数据绑…...

【磁盘】每天掌握一个Linux命令 - iostat

目录 【磁盘】每天掌握一个Linux命令 - iostat工具概述安装方式核心功能基础用法进阶操作实战案例面试题场景生产场景 注意事项 【磁盘】每天掌握一个Linux命令 - iostat 工具概述 iostat&#xff08;I/O Statistics&#xff09;是Linux系统下用于监视系统输入输出设备和CPU使…...

全球首个30米分辨率湿地数据集(2000—2022)

数据简介 今天我们分享的数据是全球30米分辨率湿地数据集&#xff0c;包含8种湿地亚类&#xff0c;该数据以0.5X0.5的瓦片存储&#xff0c;我们整理了所有属于中国的瓦片名称与其对应省份&#xff0c;方便大家研究使用。 该数据集作为全球首个30米分辨率、覆盖2000–2022年时间…...

页面渲染流程与性能优化

页面渲染流程与性能优化详解&#xff08;完整版&#xff09; 一、现代浏览器渲染流程&#xff08;详细说明&#xff09; 1. 构建DOM树 浏览器接收到HTML文档后&#xff0c;会逐步解析并构建DOM&#xff08;Document Object Model&#xff09;树。具体过程如下&#xff1a; (…...

中医有效性探讨

文章目录 西医是如何发展到以生物化学为药理基础的现代医学&#xff1f;传统医学奠基期&#xff08;远古 - 17 世纪&#xff09;近代医学转型期&#xff08;17 世纪 - 19 世纪末&#xff09;​现代医学成熟期&#xff08;20世纪至今&#xff09; 中医的源远流长和一脉相承远古至…...

搭建DNS域名解析服务器(正向解析资源文件)

正向解析资源文件 1&#xff09;准备工作 服务端及客户端都关闭安全软件 [rootlocalhost ~]# systemctl stop firewalld [rootlocalhost ~]# setenforce 0 2&#xff09;服务端安装软件&#xff1a;bind 1.配置yum源 [rootlocalhost ~]# cat /etc/yum.repos.d/base.repo [Base…...

Unity中的transform.up

2025年6月8日&#xff0c;周日下午 在Unity中&#xff0c;transform.up是Transform组件的一个属性&#xff0c;表示游戏对象在世界空间中的“上”方向&#xff08;Y轴正方向&#xff09;&#xff0c;且会随对象旋转动态变化。以下是关键点解析&#xff1a; 基本定义 transfor…...

[特殊字符] 手撸 Redis 互斥锁那些坑

&#x1f4d6; 手撸 Redis 互斥锁那些坑 最近搞业务遇到高并发下同一个 key 的互斥操作&#xff0c;想实现分布式环境下的互斥锁。于是私下顺手手撸了个基于 Redis 的简单互斥锁&#xff0c;也顺便跟 Redisson 的 RLock 机制对比了下&#xff0c;记录一波&#xff0c;别踩我踩过…...

flow_controllers

关键点&#xff1a; 流控制器类型&#xff1a; 同步&#xff08;Sync&#xff09;&#xff1a;发布操作会阻塞&#xff0c;直到数据被确认发送。异步&#xff08;Async&#xff09;&#xff1a;发布操作非阻塞&#xff0c;数据发送由后台线程处理。纯同步&#xff08;PureSync…...