用 Raspberry Pi 控制伺服 MG90D
舵机介绍
舵机是一种位置(角度)伺服的驱动器,适用于那些需要角度不断变化并可以保持的控制系统。目前,在高档遥控玩具,如飞机、潜艇模型,遥控机器人中已经得到了普遍应用。我们这里使用的淘宝上常见的MG90舵机。如下图,需要注意,不同的型号,其转向的角度,力距不一样,可以根据自己的需求进行选用。
工作原理
舵机的控制信号由接收机的通道进入信号调制芯片,获得直流偏置电压。它内部有一个基准电路,产生周期为20ms,宽度为1.5ms的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。最后,电压差的正负输出到电机驱动芯片决定电机的正反转。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为0,电机停止转动。
舵机的控制一般需要一个20ms左右的时基脉冲,该脉冲的高电平部分一般为0.5ms-2.5ms范围内的角度控制脉冲部分,总间隔为2ms。以180度角度伺服为例,那么对应的控制关系是这样的:
脉宽、占空比和舵机转角之间的关系表格:
脉冲/ms | 占空比 | 角度 |
---|---|---|
0.5 | 2.5% | 0 |
1.0 | 5% | 45 |
1.5 | 7.5% | 90 |
2.0 | 10% | 135 |
2.5 | 12.5% | 180 |
数据推算
在上表的基础上,我们需要计算一些关键参数。
根据上表,如果我们要使舵机转到指定的角度θ(0≤θ≤180)θ(0≤θ≤180) ,则需要输入的脉冲占空比为:
D=2.5+(θ×(12.5−2.5))/180=2.5+(θ×10)/180
舵机转动需要一定时间,给它发指令应避免引起冲突。舵机的转速大概为0.2秒每60度,即0.003s/° 。而舵机的精度为180°/1024≈0.18°,对应的脉冲占空比精度为(12.5−2.5)/1024≈0.01 ,因此,在步进转动内(即每次转0.18°,后面直接取0.2°),给舵机发的指令间隔时间不应该低于0.2×0.003=0.0006s ,舍入一下即0.001s。而如果我们是任意指定转角,那么两次指令的间隔时间则应该长于180×0.260=0.4s,这是从0度转到180度的时间。
舵机接线
将舵机棕色线接到GND,红色线接到+5V引脚,橙色线接到GPIO.12(BCM18)引脚。
程序编写
Rotation.py
import RPi.GPIO as GPIO
import time
# 这个类表示单个的SG90模块
class Rotation:
frequency=50 #脉冲频率(Hz)
delta_theta=0.2 #步进转动间隔(度)
min_delay=0.0006 #转动delta_theta的理论耗时(s)
max_delay=0.4 #从0转到180的耗时(s)
def __init__(self,channel,min_theta,max_theta,init_theta=0):
'''
构造函数:
channel: 舵机信号线所连接的树莓派引脚编号(BCM编码)
min_theta: 舵机转动的最小角度
max_theta: 舵机转动的最大角度
init_theta: 舵机的初始角度
'''
self.channel=channel
if(min_theta<0 or min_theta>180):
self.min_theta=0
else:
self.min_theta=min_theta
if(max_theta<0 or max_theta>180):
self.max_theta=180
else:
self.max_theta=max_theta
if(init_theta<min_theta or init_theta>max_theta):
self.init_theta=(self.min_theta+self.max_theta)/2
else:
self.init_theta=init_theta #初始角度
#计算最小角度、最大角度的占空比
self.min_dutycycle=2.5+self.min_theta*10/180
self.max_dutycycle=2.5+self.max_theta*10/180
def setup(self):
'''
初始化
'''
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(self.channel,GPIO.OUT)
self.pwm=GPIO.PWM(self.channel,Rotation.frequency) #PWM
self.dutycycle=2.5+self.init_theta*10/180 #脉冲占空比的初始值
self.pwm.start(self.dutycycle) #让舵机转到初始位置
time.sleep(Rotation.max_delay)
def positiveRotation(self):
'''
正相步进转动,每次调用只转动delta_theta度
'''
self.dutycycle=self.dutycycle+Rotation.delta_theta*10/180
if self.dutycycle>self.max_dutycycle:
self.dutycycle=self.max_dutycycle
self.pwm.ChangeDutyCycle(self.dutycycle)
time.sleep(Rotation.min_delay)
def reverseRotation(self):
'''
反相转动,每次调用只转动delta_theta度
'''
self.dutycycle=self.dutycycle-Rotation.delta_theta*10/180
if self.dutycycle<self.min_dutycycle:
self.dutycycle=self.min_dutycycle
self.pwm.ChangeDutyCycle(self.dutycycle)
time.sleep(Rotation.min_delay)
def specifyRotation(self,theta):
'''
转动到指定的角度
'''
if(theta<0 or theta>180):
return
self.dutycycle=2.5+theta*10/180
self.pwm.ChangeDutyCycle(self.dutycycle)
time.sleep(Rotation.max_delay)
def cleanup(self):
self.pwm.stop()
time.sleep(Rotation.min_delay)
GPIO.cleanup()
ServoCtrl.py
import time
rot = Rotation(18, 0, 180)
rot.setup()
time.sleep(2)
for i in range(0,900):
rot.positiveRotation()
for i in range(0,900):
rot.reverseRotation()
rot.cleanup()
推荐阅读
-
用 Raspberry Pi 控制伺服 MG90D
-
StarRTC 、AndroidThings 、Raspberry Pi 小车、公共网络环境、视频远程控制 (I) 准备工作
-
用 Raspberry Pi 构建实时视频监控系统
-
用 Raspberry Pi 构建家庭 NAS
-
用 libgpiod 控制 Raspberry Pi LED 灯
-
微控制器设计 - 基于 Raspberry Pi 的 wifi 小车设计与实施
-
简单易懂版 - 什么是粒子群算法(PSO)?" - PSO 是这样工作的: 想象一群小鸟寻找食物,它们会互相学习、竞争并跟随最优秀的伙伴。这就是模仿群体智慧(Swarm Intelligence,SI)的粒子群优化算法,由 Eberhart 博士和 Kennedy 博士创造,属于多智能体优化系统(MAOS)的一员。 - 数学背后的逻辑: - 每只“鸟”(粒子)依据邻居过去的发现来飞得更好: 1. 受到激励的好位置(Pbest) 2. 与附近伙伴的成绩对比 3. 阿婆姨领先者的模仿 - 模型简化来说,每个粒子像 D 维空间的理想点,按特定速度飞行,速度随自身经验和同伴表现实时调整。我们用 Xi 表示 D 个粒子的集合,其中 Pi 存储过最佳位置,Pg 是群体中最优的位置,Vi 是粒子的速度。 - 更新规则: - **速度更新**:有点像梯度下降法中的导数概念,但因鸟群数量大,能有效跳出局部最优区域,引导群体朝全局最优方向前进。 - **位置更新**:在固定的时间内,新移动的距离就是 Vi(即速度向量在单位时间内的累积效果)。 - 参数简述:粒子群算法涉及多个参数,如粒子数量、学习因子(影响对过去经验的重视程度)、加速常数(控制探索与利用之间的平衡),这些参数的选择会影响算法的实际性能和收敛速度。