在树莓派 Pico 上编程使用舵机

舵机是一种位置伺服的驱动器,主要是由外壳、电路板、无核心马达、齿轮与位置检测器所构成。其工作原理是由接收机或者单片机发出信号给舵机,其内部有一个基准电路,产生周期为 20ms,宽度为 1.5ms 的基准信号,将获得的直流偏置电压与电位器的电压比较,获得电压差输出。经由电路板上的 IC 判断转动方向,再驱动无核心马达开始转动,透过减速齿轮将动力传至摆臂,同时由位置检测器送回信号,判断是否已经到达定位。适用于哪些需要角度不断变化并可以保持的控制系统。当电机转速一定时,通过级联减速齿轮带动电位器旋转,使得电压差为 0,电机停止转动。

一般舵机旋转的角度范围是 0 度到 180 度。舵机转动的角度与脉宽在 0.5ms~2.5ms 的区间内呈线性关系。舵机有 90°、180°、270°、360° 最大转角。

控制原理

通过向舵机的信号信号线发送 PWM 信号来控制舵机的输出量;一般来说,PWM 的周期以及占空比,我们是可控的,所以 PWM 脉冲的占空比直接决定了输出轴的位置。

当我们向舵机发送脉冲宽度为 1.5 毫秒的信号时,舵机的输出轴将移至中间位置(90度);脉冲宽度为 1ms 时,舵机的输出轴将移至最小的位置(0度);脉冲宽度为 2ms 时,舵机的输出轴将移至最小的位置(180度)。

注意:不同类型和品牌的伺服电机之间最大位置和最小位置的角度可能会不同。许多伺服器仅旋转约 170 度(或者只有 90 度),但宽度为 1.5ms 的伺服脉冲通常会将伺服设置为中间位置(通常是指定全范围的一半)。

以 180 度角度伺服为例,对应的控制关系是这样的:
0.5ms – 0 度;
1.0ms – 45 度;
1.5ms – 90 度;
2.0ms – 135 度;
2.5ms – 180 度;

既然是要控制输出 PWM 的周期和占空比,需要明确定时器的周期、PWM 输出占空比计算公式:
定义几个相关量,系统运行时钟(sys_clk)、定时器时钟预分频值(psc)、计数重装载值(arr)、比较计数值(ccr)。

定时器频率计算公式:f = sys_clk / [( arr + 1 ) * ( psc + 1 )];
占空比计算公式:duty = ccr/arr * 100%;

定时器设置与角度值换算

本示例使用的舵机为周期 20ms、转角 180° 的模拟舵机。本示例编程推导思路如下:

1、任意角脉宽计算公式 :angle = 0.5ms + 角度值 *(2ms/180°)[角度值=[0,180]]
2、占空比计算公式 :duty = ccr/arr * 100%
3、定时器频率计算公式:f = sys_clk / [( arr + 1 ) * ( psc + 1 )]

1. 设置 arr
公式 1 推导:从 0 位置转到 180 位置,脉宽的最大增量 = (2.5ms – 0.5ms) = 2ms;此处将 arr 设置为 (2000-1)。

2. 设置 psc
公式 3 推导:psc = sys_clk/[ f * (arr + 1) ] – 1;本示例中 f=50hz,sys_clk=72Mhz,arr=(2000-1),即:psc = 72Mhz/(50hz * 2000) – 1; psc = 720。

3. 角度与 ccr 值换算:ccr = 500 + 角度值 *(2000/180°)

硬件接线

舵机具有三个接线:
棕色:GND,接 Pico 的 GND。
红色:+4.5 ~ +6V 电源输入,接 Pico 的 VSYS。
橙色:指令脉冲信号,接 Pico 的 GP28。

例程

以市面上常见的 9g 舵机为例,下面的代码将舵机的角度在 -90、0、90 三个角度中间切换,并循环 3 次。

from machine import Pin,PWM
import time
 
pwm = PWM(Pin(28))
pwm.freq(50)

for _ in range(3):
    pwm.duty_u16(1600)
    time.sleep(1)

    pwm.duty_u16(4815)
    time.sleep(1)

    pwm.duty_u16(7953)
    time.sleep(1)

    pwm.duty_u16(4815)
    time.sleep(1)

使用电位器控制舵机角度

这个例子读取电位器的输入,并转为舵机的角度。使舵机的角度从 -90 度到 90 度之间变化。

电位器接线

电位器模块的 VCC 接树莓派 Pico 的 3V3 引脚。
电位器模块的 GND 接树莓派 Pico 的 GND 引脚。
电位器模块的 OUT 引脚接树莓派 Pico 的 GP27 引脚。

代码如下:

from machine import Pin,PWM
import time
 
pwm = PWM(Pin(28))
 
pwm.freq(50)
 
control = machine.ADC(27)
 
while True:
    adc = control.read_u16()
    duty = int(adc * (7953-1600)/0xffff) + 1600
    pwm.duty_u16(duty)
    time.sleep(0.1)

运行之后,转动电位器,可以看到舵机的角度随之变化。

参考:[1]、[2]、[3]。

你还可以:
查看系列教程中的其他文章
购买本教程所用到的 Pico 套件



坐沙发

发表评论

你的邮件地址不会公开


*