树莓派操控SG90舵机
Posted learn-program
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了树莓派操控SG90舵机相关的知识,希望对你有一定的参考价值。
这里使用树莓派来操作sg90的舵机。先看一下这个舵机的样子:
这就是传说中的SG90舵机啦,转角是0~180.
SG90舵机接线:
SG90舵机有三条线:黄线,红线和灰(还是黑?)线。
这三条线的作用是:红线VCC,灰线GND,黄线控制线。所以我们这里主要是操控黄线来控制舵机。
然后这里有个非常非常坑的地方,就是这个舵机是需要5V电压输入的。所以你在把VCC接到树莓派上时你得接5V的引脚而不是3.3V的。这个情况我当时在stm32也遇到过:明明程序写的是对的,但是舵机就是转不起来。。。因为stm32的GPIO一般都是3.3V的,我也就没能幸免??(谁让我是硬件白痴呢??)。所以一开始接线要接对了。
PWM介绍
我们如何通过一根操作线来操作舵机呢?答案就是使用PWM脉冲宽度调制技术。那么啥叫PWM呢?这里我简单的说一下我的理解:
我们树莓派或者是其他单片机一个引脚只能输出两个特定的电平——高电平和低电平。在树莓派上大多的GPIO都是高电平3.3V,低电平0V。但是如果我想要输出3.3~0V之间的电压怎么办呢?比如输出一个2V?树莓派(以及stm32,C51之类的)是没有办法直接设置引脚的电平来达到输出2V的。因为通过树莓派来说,你的GPIO.setup(channel,state)里的state只能是GPIO.HIGH和GPIO.LOW,没有什么GPIO.twoV之类的东西。那么我们就要使用PWM来输出介于低电平和高电平之间的电压。
那么PWM是怎么做到的呢?很简单:我们不能直接输出2V,那我们换一种方式——通过给引脚一个周期脉冲,然后看这个脉冲的高电平部分占整个脉冲的比例,从而计算这个输出的电平。举个栗子??:比如我给出一个周期为20s的周期脉冲,然后让其中的高电平为12s,这样的话输出的电平就是(12/20)*3.3V≈2V,那么2V就输出了??。
也就是说,PWM是根据周期脉冲中高电平所占的比例来确定GPIO输出的电压的。这里,高电平所占周期电平周期的比例称为占空比。这是个很重要的概念,要记住了。
下面这个GIF就说明了PWM产生的结果。代码如下(待会会说这个代码):
1 import RPi.GPIO as GPIO
2 import time
3
4 if __name__==‘__main__‘:
5 GPIO.setmode(GPIO.BOARD)
6 GPIO.setup(33,GPIO.OUT,initial=GPIO.LOW)
7 GPIO.setup(35,GPIO.OUT)
8 GPIO.setup(37,GPIO.OUT,initial=GPIO.HIGH)
9 p=GPIO.PWM(35,150)
10 p.start(0)
11 try:
12 while True:
13 for dc in range(0,101,1):
14 p.ChangeDutyCycle(dc)
15 time.sleep(0.1)
16 for dc in range(100,-1,-1):
17 p.ChangeDutyCycle(dc)
18 time.sleep(0.1)
19 except KeyboardInterrupt:
20 pass
21 p.stop()
22 GPIO.cleanup()
这个本来是我做PWM呼吸灯的代码,是循环输出0~3.3V的程序,这里我用电表测量了35(PWM输出)脚。通过电表的示数可明显看到引脚输出的电压的确在变化。
接下来说说树莓派里面如何实现PWM。主要就是在第9,10,14,21行:
- 首先只要想使用GPIO,就一定要初始化GPIO,这里的第7行先初始化35脚的GPIO为输出
- 然后要说明哪个引脚使用PWM功能。第9行的GPIO.PWM(channel,frequency)指定channel脚使用PWM功能,这个PWM的频率为frequency。所谓频率就是周期的倒数嘛,也就是你的周期脉冲的周期的倒数啦。然后这个函数返回一个PWM对象,这里为p
- 然后开始PWM,第10行p.start(initdutycycle)说明现在开始PWM输出啦,这里的initdutycycle是在开始时指定的占空比。这里为0也就是说0/frequency*5V为0V,暂时不输出电平。由于是指定占空比,所以initdutycycle在[0,100]区间之内。超出这个区间Python会报错。
- 那么如何更改占空比呢?使用第14行的p.ChangeDutyCycle(dutycycle)来改变占空比。
- 最后你用完PWM了需要将PWM释放掉,也就是第21行的p.stop()
如何使用PWM操控舵机?
我们查看SG90的文档可以看见其占空比与转动角度的关系:
在周期20ms下:
角度 占空比
0.5ms-------------0度; 2.5%
1.0ms------------45度; 5.0%
1.5ms------------90度; 7.5%
2.0ms-----------135度; 10.0%
2.5ms-----------180度; 12.5%
这里直接给出了占空比与角度的关系,我们就不用关系电压的大小了。
这里SG90舵机的参考周期是20ms,也就是50KHZ。那么按照这个方法我们可以写出如下代码:
import RPi.GPIO as GPIO import time GPIO.setmode(GPIO.BOARD) Vcc_Pin=37 In_Pin=35 #操控线(黄线) GPIO.setup(Vcc_Pin,GPIO.OUT,initial=GPIO.HIGH) GPIO.setup(In_Pin,GPIO.OUT,initial=GPIO.LOW) p=GPIO.PWM(In_Pin,50) #设置频率为50KHz p.start(0) str1="please input the degree(0<=a<=120) or press q to quit " r=input(str1) try: while not r=="q": if r.isdigit(): #判断输入的字符串是不是数字 r=int(r) #是数字转换成数字 else: print("please input a number(0<=num<=120)") continue if r<0 or r>180: #越界提示 print("a must be [0,120]") continue p.ChangeDutyCycle(2.5+r/360*20) #通过用户输入的角度来改变舵机的角度 time.sleep(0.02) r=str(input(str1)) except KeyboardInterrupt: pass p.stop() GPIO.cleanup()
这个程序让用户输入舵机转动的角度,从而转动舵机到相应的角度。
这里的p.ChangeDutyCycle(2.5+r/360*20)中的2.5+r/360*20是我推导的公式,用于转动舵机到指定的角度。这个公式使用比例来推导,很简单的。
最后的成果如下:
以上是关于树莓派操控SG90舵机的主要内容,如果未能解决你的问题,请参考以下文章