友情提示:380元/半年,儿童学编程,就上码丁实验室。
什么是舵机
舵机是伺服电机下的一个小类,伺服电机常用于需要高精度定位的领域,比如机床、工业机械臂、机器人等。
而舵机则是国人起的俗称,因为航模爱好者们最初用它控制船舵、飞机舵面而得名。是伺服电机的简化版,原本伺服电机的三环控制被简化成了一环,即只检测位置环。内部由直流电机,电位器,一些逻辑芯片,出轮组成,价格和品质差异大。


以上是航模中常用的9g舵机,所使用材料基本上是塑料,轻盈、便宜。但是掉齿、卡齿、烧坏
是家常便饭。(之前做航模弄坏过好多这种,需要的话买好一点的比如银燕)

我的小车上所使用这个MG996R,会比9g力量大稳定性强很多。
如何驱动舵机
舵机有引出三根线(黑白灰或者棕红橙):
棕/黑—->GND
橙/白—->+5V
黄/灰—->PWM信号线
以上的前两根提供舵机电源,最后一根是信号线。信号线使用的是PWM来控制电机的位置。什么是PWM信号?

脉冲宽度调制(Pulse Width Modulation)就是一种矩形波,通过高电平时间所占周期的比例也就是占空比来表示不同信号。占空比可以从0%到100%。不过舵机往往不是360°都可以旋转的,所以在控制舵机的占空比并不是从0%到100%都可以的。本文使用的舵机型号是MG996R,从数据手册上可以看到,该舵机内部的基准信号是周期为20ms,宽度为1.5ms的PWM信号,如图。

如果我们输入一个和基准信号相同的占空比的信号,电机就转到0°位置。该舵机的最小角度是-90°最大是90°,总共可用角度为180°。周期T=20ms,高电平脉冲宽度0.5ms对应角度为-90°,高电平脉冲宽度2.5ms对应的旋转角度为90°中间为线性变化。如下如所示。

Python编写舵机程序
使用python来编写程序前,先要确保树莓派的设置GPIO时ENABLE状态的,否则不能初始化GPIO。然后导入RPi.GPIO模块。以下整理了GPIO的常用的一些操作。
import RPi.GPIO as GPIO#导入GPIO模块
#GPIO操作 written by K2O
GPIO.setmode(GPIO.BCM) #可选择GPIO编号方式BCM或者BOARD
GPIO.setup(GPIO_PIN, GPIO.OUT) #配置GPIO为输出模式
GPIO.setup(GPIO_PIN, GPIO.IN) #配置GPIO为输入模式
GPIO.output(GPIO_PIN,GPIO.HIGH) #指定某一个GPIO通道输出高电平
GPIO.output(GPIO_PIN,GPIO.LOW) #指定某一个GPIO通道输出低电平
GPIO.wait_for_edge(GPIO_PIN, GPIO.RISING) #输入模式检测上升沿
#有关PWM written by K2O
p = GPIO.PWM(channel,frequency) #创建一个 PWM 实例
p.start(dc) #启用 PWM(0.0 <= dc >= 100.0)
p.ChangeFrequency(freq) #更改频率
p.ChangeDutyCycle(dc) #更改占空比
p.stop() #停止 PWM
#最后释放GPIO
GPIO.cleanup()
在第一次我使用PWM时是按照51单片机的经验直接用循环来写的,后来发现树莓派有直接控制GPIO口输出PWM信号的语句,非常的方便。树莓派的GPIO编号有两种方式,分别是BCM和BOARD,这里我使用BCM编号。当然舵机的两个电源线可以连接树莓派的5V和GND(这里要注意树莓派通常的GPIO是3.3V),只有两个引脚是5V输出,信号线是可以使用3.3V来使用。连接如下图:

如果真正做工程,电源最好不要从树莓派上取,可以统一做一块管理各个部分的电源的PCB。
在我的程序里我对舵机部分定义了一个叫做steer的类。

我的程序使用舵机的步骤
1、在使用时先实例化steer1。
2、然后使用方法steer1.start()。初始化舵机,包括了配置GPIO模式为OUT输出,设定频率为50Hz。对17引脚创建一个PWM实例,设置初始的占空比为7.5%(1.5ms高电平每周期),这时舵机回中。
def start(self):
print("start is called")
self.p = GPIO.PWM(self.channel, self.frequency)#创建一个 PWM 实例
self.p.start(self.dc)#启用 PWM(0.0 <= dc >= 100.0)
print("channel=%d, dc=%f, frequency=%d" %(self.channel,self.dc,self.frequency))
3、之后要舵机转向使用方法steer1.turn(cd),需要参数cd,根据实际小车需求的角度,舵机的占空比范围为5%~10%,turn(cd)中参数cd定为-2.5~2.5(对应5%~10%),0为回正,-2.5最左,2.5最右。实际可转角度大约90°。
def turn(self, deg):
if -2.5<=deg<=2.5:
dc = deg +7.5
steer.duty(self, dc)
else:
rdeg = float(input("please input the steering angle again:"))
print(rdeg)
steer.turn(self, rdeg)
def duty(self, dc):
#dc = int(input("change dutycycle:"))
if 5<=dc<=10:
self.p.ChangeDutyCycle(dc)#更改占空比
else:
rdc = float(input("please input the dutycycle valve again:"))
print(rdc)
steer.duty(self, rdc)
4、最后结束时使用方法steer1.stop(),舵机回中,调用PWM的方法stop()。
5、全部程序执行完后要使用GPIO.cleanup()释放GPIO,否则会占用GPIO,之后的程序再使用就会报错。
小车整体连接(暂时)

始发于知乎专栏:氧化鉀君