树莓派控制舵机

说在前面: 在网上找了一圈有关树莓派控制舵机的代码,发现好多都是一模一样的,重点是它们都贴着“原创”标签。 ^ __ ^!

一、所需材料

  • 9 G 180°微型舵机。
  • 树莓派4.
  • 5 V 电源。(可选)

二、PWM如何工作

树莓派不能直接输出模拟电信号,但我们可以使用PWM(脉宽调制)方法来模拟这一点。我们制作一个固定频率的数字信号,在那里我们将改变脉冲宽度,将“转换”改为“平均”输出电压的电平,我们可以使用这个“平均”电压水平来控制LED亮度。
频率本身不是重点,而是“占空比”,即脉冲“高”的时间除以波周期之间的关系。例如,假设我们在树莓派的 GPIO上产生一个50Hz的脉冲频率。周期(p)将是频率的倒数或20ms(1 / f)。如果我们的LED达到“半”亮度,我们的占空比必须为50%,这意味着“脉冲”将是10ms的“高”。而在这里,我们将用“占空比”来定义舵机的位置。

三、接线

一般舵机有三根控制线,分别为黄、红、灰(黑),这三根线分别接树莓派GPIO数据输出引脚、5V电源正极、GND。
对于舵机的供电,可以选择树莓派的5V输出,但为了树莓派的安全起见,建议用外部5V电源。充电宝就可以。

四、舵机校准

  1. 舵机参数

首先,你要清楚你的舵机参数。我使用的舵机基本参数如下:

范围 0°~180°
电源 5VDC
工作频率 50Hz(周期:20 ms)
脉冲宽度 1ms~2ms

理论上,1ms对应舵机0°,1.5ms对应舵机90°,2ms对应舵机180°。
在利用Python编写舵机位置时,利用的是上述位置所对应的的“占空比”。

位置角度 脉冲宽度 占空比
1ms 5.0%
90° 1.5ms 7.5%
180° 2ms 10%

其中,占空比 = 脉冲宽度/周期。 5.0% = 1ms/20ms
可以看出,占空比理论上应该在5%到10%之间变化。但是,舵机在实际上会有一些误差,需要我们校正,得到它的准确值。

  1. 舵机校正
    在树莓派中运行以下代码:
#!/usr/bin/env python3
import RPi.GPIO as GPIO
import time
GPIO.setmode(GPIO.BOARD) # GPIO引脚编号的两种方式之一,另一种是BCM。所用编号方式不同,pin也不同。
GPIO.setwarnings(False# 禁用警告。
GPIO.setup(pin,GPIO.OUT) # pin为你所接的数据输出GPIO引脚。
p = GPIO.PWM(pin,50) # 在pin脚上产生频率为50HZ的PWM信号。
p.start(0) # 在引脚上设置一个初始PWM信号。
p.ChangeDutyCycle(3) # 通过输入不同的“占空比值”来观察舵机的位置变化,这里的“占空比”是3%。
time.sleep(1)
p.stop() # 停止PWM。
GPIO.cleanup() # 清理GPIO。

最终得到的角度和“占空比”的关系为:

角度 占空比
2%
90° 7%
180° 12%

进而,我们可以通过一组简单的二元一次方程,得到占空比和角度的关系表达式:
DutyCycle = angle/18 + 2

五、舵机控制代码

#!/usr/bin/env python3 
import RPi.GPIO as GPIO
import time
def setServoAngle(angle):
   GPIO.setmode(GPIO.BOARD)
   GPIO.setwarnings(False)
   GPIO.setup(32, GPIO.OUT)
   tilt = GPIO.PWM(32, 50)
   tilt.start(0)
   DutyCycle = angle/18 + 2
   tilt.ChangeDutyCycle(DutyCycle)
   time.sleep(1)
   tilt.stop()
c = input("If you want to continue, type 'c' please. Type 'e' to end.")
while c == 'c':
   angle = input('Please type an angle:')  # input输入的是字符串,需要用int()函数转化成数字。
   angle = int(angle)
   setServoAngle(angle)
   c = input("'c' or 'e'?") 
GPIO.cleanup()
exit()

如有问题,欢迎评论区交流啊!

你可能感兴趣的:(树莓派控制舵机)