MG996R舵机180度与360度驱动,ULN2003A步进电机驱动,触控开关控制

16 篇文章 0 订阅
9 篇文章 1 订阅

  • 产品类型:MG996R舵机
  • 产品扭矩:9kg/cm(4.8V),11kg/cm(6V)
  • 产品速度:0.19秒/60°(4.8V),0.18秒/60°(6V)   #0.19/60=0.0032s/度
  • 转动角度:180°
  • 工作电压:4.8 ~ 6V
  • 齿轮形式:金属齿轮
  • 死区设定:5us (微秒)
  • 产品重量:55g
  • 产品尺寸:40.7mm × 19.7mm × 42.9mm

舵机的控制原理:
舵机是一种位置伺服的驱动器,与马达不同,我们需要马达提供的是旋转,控制的是转速和方向。而舵机不需要整圈的旋转,需要的是旋转角度并维持住。一般舵机旋转的角度范围是0 度到180 度。舵机引线为3线,分别用棕、红、橙三种颜色进行区分,舵机品牌和生产厂家不同,会有些许差异,使用之前需查看资料。我们使用的是最常见的舵机,棕、红、橙分别对应“电源负极,电源正极,控制信号”。
舵机的伺服系统由可变宽度的脉冲来进行控制,橙色的控制线是用来传送脉冲的。脉冲的参数有最小值,最大值,和频率。一般而言,PWM控制舵机的基准信号周期为20ms,基准脉宽为1.5ms(中位),理论上脉宽应在1ms到2ms 之间,但是,实际上脉宽可由0.5ms 到2.5ms 之间,脉宽和舵机的转角0°~180°相对应。这个基准脉宽信号1.5ms定义的位置为中间位置。不同舵机的最大转动角度可能不相同,但是其中间位置的脉冲宽度是一定的,那就是1.5ms。(以下为PWM控制信号:20ms/2.5ms=8位)

舵机的PWM控制一般需要一个20ms的时基脉冲,该脉冲的高电平部分一般为0.5ms~2.5ms范围内的角度控制脉冲部分。以180度角度舵机为例,对应的控制关系是这样的:
0.5ms--------------0度; 2.5% (0.5ms高电平+19.5低电平)
1.0ms------------45度; 5.0%  (1.0ms高电平+19.0低电平)
1.5ms------------90度; 7.5%  (1.5ms高电平+18.5低电平)
2.0ms-----------135度;10%   (2.0ms高电平+18.0低电平)
2.5ms-----------180度;12.5%(2.5ms高电平+17.5低电平)

角度转换占空比:2.5+角度/180*10 或 2.5+12.5/180*角度

#! /usr/bin/env python3
# encoding=utf-8   
 
import RPi.GPIO as GPIO
import time
import signal
import atexit
 
atexit.register(GPIO.cleanup)
 
servopin=4
GPIO.setmode(GPIO.BCM)
GPIO.setup(servopin,GPIO.OUT,initial=False)
p=GPIO.PWM(servopin,50)    #50HZ:频率就是周期脉冲的周期的倒数 1s/0.02s=50Hz
p.start(2.5)                 #start(initdutycycle):占空比0-100间,0表示暂不输出
time.sleep(2)
 
while(True):
	for i in range(0,181,10):
		p.ChangeDutyCycle(2.5+i/180*10)			#设置转动角度:占空比:2.5+10*角度/180
		time.sleep(0.04)					#等该20ms周期结束,防抖 
		p.ChangeDutyCycle(0)					#归零信号,防抖
		time.sleep(0.2)
 
	for i in range(181,0,-10):
		p.ChangeDutyCycle(2.5+i/180*10)
		time.sleep(0.04)
		p.ChangeDutyCycle(0)
		time.sleep(0.2)
 
GPIO.cleanup()

舵机转动的方向不是由占空比决定的,而是由脉冲长度 t 决定的。有的舵机使用的PWM频率为 fPWM=50HZ,其对应于的PWM周期 T=20 ms。脉冲长度 t 和转动方向之间的关系是线性的,但也取决于电机和齿轮的配合。

注意:以下代码中的a和b参数必须与您所使用的舵机类型相匹配。如下图,舵机的占空比:

import RPi.GPIO as GPIO
import time

P_pin=4
P_fpwm=50
a=12.5    #最大值180度
b=2.5    #最小值0度

def setup():
	global pwm
	GPIO.setmode(GPIO.BCM)
	GPIO.setup(P_pin,GPIO.OUT)
	pwm=GPIO.PWM(P_pin,P_fpwm)
	pwm.start(0)
	
def  setDirection(direction):
	duty=b+a/180*float(direction)    #占空比:0度+每度占空*角度
	pwmChangeDutyCycle(duty)
	print"角度=",direction,"->占空比=",duty
	time.sleep(0.04)
	
print "starting"
setup()

while(True):
	for direction in range(0,180,1):
		setDirection(direction)
		time.sleep(0.02)

	for direction in range(180,1,-1):
		setDirection(direction)
		time.sleep(0.02)

direction=0
setDirection(0)
GPIO.cleanup()
print "ok"

360度舵机控制:

#! /usr/bin/env python3
# encoding=utf-8   
 
import RPi.GPIO as GPIO
import time
import signal
import atexit

atexit.register(GPIO.cleanup)

servopin=4
GPIO.setmode(GPIO.BCM)
GPIO.setup(servopin,GPIO.OUT,initial=False)
p=GPIO.PWM(servopin,50)	#50HZ:频率就是周期脉冲的周期的倒数
p.start(0)					#start(initdutycycle):占空比0-100间,0表示暂不输出
time.sleep(2)

while(True):
	p.ChangeDutyCycle(3) #正转2.5高速-6.5-7.5底速-12.5高速反转(调校以抖动稳定性为准)
	#time.sleep(1)
	print 'jiaodu=',3
	time.sleep(60)
	p.ChangeDutyCycle(12)
	#time.sleep(1)
	print 'jiaodu=',12
	time.sleep(60)


#p.ChangeDutyCycle(0)					#归零信号  
time.sleep(0.2)
GPIO.cleanup()

---------------------------------------

ULN2003A控制步进电机

步进电机能够被精确定位,正向或反向一次性转动“一步”,并且也能够连续转动。连接方式如下图:



 

#! /usr/bin/env python3
# encoding=utf-8   

import RPi.GPIO as GPIO
import time
 
IN1 = 11    # pin11
IN2 = 12
IN3 = 13
IN4 = 15
 
def setStep(w1, w2, w3, w4):  #启用pin
	GPIO.output(IN1, w1)
	GPIO.output(IN2, w2)
	GPIO.output(IN3, w3)
	GPIO.output(IN4, w4)
 
def stop():
	setStep(0, 0, 0, 0)
 
def forward(delay, steps):  #正向步进
	for i in range(0, steps):
		setStep(1, 0, 0, 0)
		time.sleep(delay)
		setStep(0, 1, 0, 0)
		time.sleep(delay)
		setStep(0, 0, 1, 0)
		time.sleep(delay)
		setStep(0, 0, 0, 1)
		time.sleep(delay)
 
def backward(delay, steps):  #反向步进
	for i in range(0, steps):
		setStep(0, 0, 0, 1)
		time.sleep(delay)
		setStep(0, 0, 1, 0)
		time.sleep(delay)
		setStep(0, 1, 0, 0)
		time.sleep(delay)
		setStep(1, 0, 0, 0)
		time.sleep(delay)
 
def setup():
	GPIO.setwarnings(False)
	GPIO.setmode(GPIO.BOARD)       # 引脚编码方式
	GPIO.setup(IN1, GPIO.OUT)      # 引脚模式
	GPIO.setup(IN2, GPIO.OUT)
	GPIO.setup(IN3, GPIO.OUT)
	GPIO.setup(IN4, GPIO.OUT)
 
def loop():
	while True:
		print "backward..."
		backward(0.003, 512)  # 512步--- 360 angle
		
		print "stop..."
		stop()                 # stop
		time.sleep(3)          # sleep 3s
		
		print "forward..."
		forward(0.005, 512)
		
		print "stop..."
		stop()
		time.sleep(3)
 
def destroy():
	GPIO.cleanup()             # 清除
 
if __name__ == '__main__':     # 程序入口
	setup()
	try:
		loop()
	except KeyboardInterrupt:  # 当'Ctrl+C' 中断
		destroy()
 

加了个触控开关:

#! /usr/bin/env python3
# encoding=utf-8   

import RPi.GPIO as GPIO  
import time  
  
IN1 = 17 #电机
IN2 = 18
IN3 = 27
IN4 = 22

IN5 = 23 #触控
IN6 = 13
IN7 = 26
IN8 = 19

IN9 = 4 #舵机

def setStep(w1, w2, w3, w4):  #迈步函数
    GPIO.output(IN1, w1)  
    GPIO.output(IN2, w2)  
    GPIO.output(IN3, w3)  
    GPIO.output(IN4, w4)  
  
def stop():  
    setStep(0, 0, 0, 0) 
  
def forward(delay, steps):    #正向延迟,迈步循环
    for i in range(0, steps):  
        setStep(1, 0, 0, 0)  
        time.sleep(delay)  
        setStep(0, 1, 0, 0)  
        time.sleep(delay)  
        setStep(0, 0, 1, 0)  
        time.sleep(delay)  
        setStep(0, 0, 0, 1)  
        time.sleep(delay)  
  
def backward(delay, steps):    #反向延迟,迈步循环
    for i in range(0, steps):  
        setStep(0, 0, 0, 1)  
        time.sleep(delay)  
        setStep(0, 0, 1, 0)  
        time.sleep(delay)  
        setStep(0, 1, 0, 0)  
        time.sleep(delay)  
        setStep(1, 0, 0, 0)  
        time.sleep(delay)  
  
def setup():  #gpio加载
    GPIO.setwarnings(False)  
    GPIO.setmode(GPIO.BCM)       # Numbers GPIOs by physical location  
    GPIO.setup(IN1, GPIO.OUT)      #电机
    GPIO.setup(IN2, GPIO.OUT)  
    GPIO.setup(IN3, GPIO.OUT)  
    GPIO.setup(IN4, GPIO.OUT)
    
    GPIO.setup(IN5, GPIO.IN) #触摸开关
    GPIO.setup(IN6, GPIO.IN) 
    GPIO.setup(IN7, GPIO.IN) 
    GPIO.setup(IN8, GPIO.IN) 
    
    GPIO.setup(IN9, GPIO.OUT)  #舵机

def duoji360():
    p=GPIO.PWM(IN9,50)  #50HZ:频率就是周期脉冲的周期的倒数
    p.start(0)  #start(initdutycycle):占空比0-100间,0表示暂不输出
    p.ChangeDutyCycle(3.5) #正转2.5高速-7.5底速-12.5高速反转
    print 'jiaodu=',3.5
    time.sleep(1)
  
def loop():  
    while 1:  
        if(GPIO.input(IN5)==1):
            print "backward..."  
            if(GPIO.input(IN8)==0):
                i=1
                i=i+1
                backward(0.002, i)  # 延迟0.002,迈512步- 360 angle
          
        if(GPIO.input(IN8)==1):
            print "stop..."  
            stop()                 # stop  
            time.sleep(1)         
          
        if(GPIO.input(IN6)==1):
            print "forward..." 
            if(GPIO.input(IN8)==0):
                i=1
                i=i+1
                forward(0.003, i)
          
        if(GPIO.input(IN7)==1):
            print "duoji360..."  
            duoji360()  
            time.sleep(1)  
  
def destroy():  
    GPIO.cleanup()            
  
if __name__ == '__main__':  
    setup()  
    try:  
        loop()  
    except KeyboardInterrupt:  # When 'Ctrl+C' is pressed, the child function destroy() will be  executed.  
        destroy()  

------------------------------------------------------------------------------------------------------------------

时基脉冲:一般舵机的控制需要一个20ms左右的时基脉冲
频率:1s/0.020s=50Hz,也就是说最多1秒钟内可以转动50次
脉宽:周期20ms,脉宽0.5ms-2.5ms,当脉宽1.5ms时舵机在中立点(0度)
占空比:脉宽0.5ms-2.5ms 对应的占空比为2.5% - 12.5% (脉宽/周期=0.5/20-2.5/20)

  • 21
    点赞
  • 141
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值