吐槽一下:本人还是个小白,CSDN文章分类不知道选哪个
如果你手上的材料是五线四相步进电机驱动板ULN2003+五线四相步进电机28BYJ-48-5V,那么应该算是非常幸运,因为这两样是配套的,一个驱动板可以接一个步进电机,实现正转、反转、加速、减速的功能(个人猜测)。很多人因为在购置树莓派外围设备时,没有考虑清楚,随随便便就买了电机和驱动板,导致无法正常驱动电机,譬如我买的是带4个直流电机的四驱车,其中的电机只有两条线接正极和负极,以及ULN2003五线四相步进电机驱动板,这两样是不配套的,不配套也没关系,仍然可以实现简单的逻辑比如一个电机的单向运转。
两路电机驱动H桥L9110电机驱动模块则是为了直接驱动直流电机,它可以同时驱动2个直流电机正转或反转,或者1个4线2相步进电机。如果准备买自带4个直流电机的小车,可以考虑买这块驱动板。
L298N电机驱动板模块也是2路H桥,可以同时驱动两个直流电机,并且ENA、ENB使能后,可以对两个电机进行调速,功能上比L9110要全面。
下面对比一下这三种驱动:
型号 模式 电机数量 输入 输出 逻辑电压 逻辑电流 驱动电压 驱动电流 说明
L298N H桥双路直流 2 IN1~IN4, ENDA, ENDB OUT1~OUT4 5V <36mA 5V-35V 单桥<2A 可变速
ULN2003 5线4相步进 1 或 2 IN1-IN4(7) OUT1-OUT5(7) 5V 直流电机不能变向
L9110 H桥双路直流 2 IA1,IB1,IA2,IB2 OA1,OB1,OA2,OB2 2.5-12V <0.8A 可变向不可变速
综上,如果用直流电机,则推荐使用L298N作为驱动,如果是5线4相步进电机,则推荐使用ULN2003,如果是4线2相则推荐使用L9110。根据推荐来组合电机和驱动板,都是比较配套的,通过树莓派GPIO控制起来也比较方便,按照驱动板说明即可。下面主要介绍如何用ULN2003驱动4驱车前进后退。
因为ULN2003和直流电机并不是很搭,只能驱动直流电机正转或者反转,不能直接进行反向操作,如果想要反向,需要接上拉电阻(这个我不懂啊。。。),对于我们这些小白来说有点难度,但我们又非要用ULN2003实现直流4驱小车的前进和后退,怎么办呢?
我也是在没什么便捷办法的情况下,想到了从4驱降成2驱这个方案,什么意思呢?就是小车前进和后退时都只有2个直流电机工作,也就是说由一块ULN2003驱动2个直流电机正转实现前进,另一块驱动另外2个直流电机反转实现后退,电机的正转反转只需要把它的正负极颠倒即可,我们把正转的2个电机的正极接到电源正极,负极由ULN2003控制,反转的2个电机的负极接到电源正极,电机正极由另一块ULN2003控制。。这样就解决了不能反向的问题,唯一的缺点是,驱动力太小,车上的重物太重的话有可能跑不起来。
把思路变成线路,徒手画的树莓派+LLN2003驱动板+面包板+直流电机的连线图如下:
上图中,树莓派GPIO标号为BOARD模式,即引脚编号1~40。用11 13 15 29接前进驱动版的IN1~IN4,驱动板电源接口接5V电源,OUT1 OUT2分别接两个正转电机的负极,正转电机的正极接在外接5V电源上。当树莓派11引脚输出HIGH、13引脚输出LOW时,电机M1正向转动;当树莓派15引脚输出HIGH、29引脚输出LOW时,电机M2正向转动;小车前进就让两个电机都正向转动1秒,小车转弯就让其中一个电机正向转动0.3秒,连续操作就可以不停地走。注意到,每次操作前GPIO的电平都reset成LOW,操作完毕后还要reset成LOW,否则会一直转(容易出现原地打转的情况)。同理,31
33 35 37接后退驱动板,其他都和前进的差不多,区别是后退的电机负极接在电源的正极上。
这里扯个了两个小技巧:1)可以把一条母对母杜邦线中间剪断分成两份,最为电机连接线,这样电机的正负极就有了方便连接的接口;2)电机在小车上固定好以后,先测好电机的正负极,统一以小车前进方向为基准,接在电源正极的就认为是电机正极,在纸上写明“+”、“-”,并用胶带固定在电机两条线上,这样在连接控制电路时,直接就可以知道是正转还是反转。
用fritzing画的线路图,这里面的ULN2003并不是完整的驱动板,当然直接使用这个也是完全可以的,连接好对应的引脚即可:
我的ULN2003驱动板如下:
用RPi.GPIO库实现的前进、后退、左转、右转的python3(注意版本,python2.7的需要手动修改一下下) 代码如下:
import RPi.GPIO as GPIO
import time
def init():
GPIO.setmode(GPIO.BOARD)
GPIO.setup(11, GPIO.OUT)
GPIO.setup(13, GPIO.OUT)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(29, GPIO.OUT)
GPIO.setup(31, GPIO.OUT)
GPIO.setup(33, GPIO.OUT)
GPIO.setup(35, GPIO.OUT)
GPIO.setup(37, GPIO.OUT)
def reset_back():
GPIO.output(11, GPIO.LOW)
GPIO.output(13, GPIO.LOW)
GPIO.output(15, GPIO.LOW)
GPIO.output(29, GPIO.LOW)
def reset_forward():
GPIO.output(31, GPIO.LOW)
GPIO.output(33, GPIO.LOW)
GPIO.output(35, GPIO.LOW)
GPIO.output(37, GPIO.LOW)
def set_back():
GPIO.output(11, GPIO.HIGH)
GPIO.output(15, GPIO.HIGH)
def set_forward():
GPIO.output(31, GPIO.HIGH)
GPIO.output(35, GPIO.HIGH)
def set_left():
GPIO.output(35, GPIO.HIGH)
time.sleep(0.3)
GPIO.output(35, GPIO.LOW)
def set_right():
GPIO.output(31, GPIO.HIGH)
time.sleep(0.3)
GPIO.output(31, GPIO.LOW)
def back():
reset_forward()
reset_back()
set_back()
time.sleep(1)
reset_forward()
reset_back()
def forward():
reset_back()
reset_forward()
set_forward()
time.sleep(1)
reset_back()
reset_forward()
def left():
reset_back()
reset_forward()
set_left()
def right():
reset_back()
reset_forward()
set_right()
if __name__ == "__main__":
try:
init()
forward()
back()
left()
time.sleep(1)
right()
except KeyboardInterrupt as e:
print(e)
except Exception as e:
print(e)
finally:
GPIO.cleanup()
老规矩,最后附送一张实物图:
PS:我的移动电源是20000mAh的,双输出口,5V 1A和5V 2.1A,可以同时给树莓派和面包板供电,但是太重了!!我把这一坨东西放在小车上,想着可以摆脱充电器的束缚,没想到小车马力不足,跑不动。。。。。情何以堪