第7章 用树莓派控制直流电机(L298N)
直流电机是机器人行走机构的理想选择之一,我们通常使用直流电机来驱动机器人行走。在第5章和第6章您已经了解到如何用树莓派控制一个LED灯,本章我们将进一步介绍如何用树莓派控制直流电机,主要内容如下。
- 直流电机的基本知识。
- L298N双H桥直流电机驱动模块相关知识。
- 如何控制直流电机的转向和转速。
本章我们将继续使用第5章搭建的多功能实验平台。此外,还需要以下材料:
- 一个小型直流电机。
- 一个可以为小型直流电机供电的电源,为便于后续的实验,我们这里使用一个3V-24V的直流可调电源。
- 一个L298N直流电机驱动模块。
7.1 直流电机
直流电机是一种将直流电能转换为机械能的装置,被广泛的用于驱动各种设备,如电风扇、遥控小车、电动车窗等,非常适合作为机器人的行走机构,您可以很容易的在网上购买到,价格也不是很贵。
小型直流电机的的电压范围通常是1.5V~30V,使用两根导线连接到直流电源上就能让电机转动起来,电压越高转得就越快。每个直流电机都有一个推荐电压,超出推荐电压太多容易导致电机被烧毁,而供电电压太低则转不起来。通过交换两根连接在电机上的导线顺序(实际上是改变电源的正负极),可以改变电机的转向。前面章节我们说过,直流电机属于高功耗元件,不可以直接使用树莓派进行驱动,因此我们需要使用一个外部电源。
小型直流电机通常输出很高的转速和较低的扭矩,在作为机器人的驱动装置时,一般需要连接一个变速器,将其转换为低转速、高扭矩,使之有足够的力量驱动机器人。图7.1是典型的带变速器的小型直流电机,建议变速器和电机一起购买。
7.2 双H桥直流电机驱动模块(L298N)
H桥(H-Bridge)是控制直流电机的常用电路,因其电路形状酷似字母H而得名,可以控制直流电机的转速和方向,典型的H桥芯片有L293D、L298N等,以下我们以L298N为例进行介绍。实际使用的时候,为提高芯片的安全性、可靠性和方便性,我们一般会给芯片外接一些保护电路,并把输入输出引脚引接到排针上,从而形成一个功能模块。图7.2是一款典型的L298N双H桥直流电机驱动模块,可以很容易从网上购买到,价格也便宜。该模块的主要特点如下:
- 采用L298N双桥直流电机驱动芯片
- 工作电压范围5V35V,如果需要从模块内取电,则供电范围为7V35V
- 峰值输出电流2A
- 每个通道有一个使能输入端
- 可以驱动两个直流电机或者一个四线步进电机
L298N双H桥直流电机驱动模块的引脚可以归纳成电源、控制和输出等三大类,下面是各类引脚的功能说明。
- 电压类引脚
+12V输入:L298N芯片的电源正极,模块上标称+12V,但实际范围可以是5V35V,如果需从模块内取电,则其范围为7V35V。
GND:L298N芯片的电源地,使用的时候应该把树莓派的GND接到这里,即两者需要共地。
+5V输出:L298N芯片输出的5V电源,可以给外部设备供电,使用的时候需要用跳线把5V输出使能端短接起来。
- 控制类引脚
ENA、ENB:A、B通道的使能端,高电平有效,可以用PWM来实现调速。使用时,可以接到树莓派的GPIO上,实现用程序进行控制。
IN1、IN2、IN3、IN4:IN1、IN2为A通道的控制输入,IN3、IN4为B通道的控制输入。
- 输出类引脚
OUT1、OUT2、OUT3、OUT4:OUT1、OUT2由A通道输出,OUT3、OUT4由B通道输出,可以用于连接直流电机等设备。
控制直流电机的转向和转速实际是通过给控制类引脚设置不同的值来实现的,表7.1是使用通道A的控制直流电机的真值表,通道B与此类似。
提示:
您购买到的L298N双H桥直流电机驱动模块可能与本章介绍的存在一定的差异,但这一类功能模块大同小异,请跟商家索要相应的技术资料了解更多的使用细节。
7.3 让直流电机动起来
下面进入实战环节,我们将用树莓派通过L298N双H桥直流电机驱动模块控制一个电机的转向和转速。为了能让读者更好的理解,我们首先演示如何控制电机的转向,然后再进一步介绍如何控制电机转速。
7.3.1 实验电路
图7.3所示的是树莓派、L298N双H桥直流电机驱动模块和电机间连接的电路图,最终实物连线图如图7.4所示。我们使用树莓派的GPIO13、GPIO19和GPIO26等3个引脚,分别连接到L298N双H桥直流电机驱动模块的ENA、IN1和IN2,通过输入表7.1所示的不同电平组合就可以实现对电机的操纵。控制电机的转向和转速都是使用该电路,向ENA输入不同占空比的PWM脉冲信号就可以控制电机的转速。
尽管L298N双H桥直流电机驱动模块能驱动两个直流电机,但我们只演示如何驱动一个。驱动两个电机使用的是相同的技术,如果在您的项目中需要用到两个,也可以很容易地扩展它。
7.3.2 程序思路
控制电机转向和转速可以使用同一个电路,但程序思路上我们分两个程序来演示,具体思路如下:
- 控制电机转向思路
BEGIN
引入GPIO库
将连接ENA的GPIO引脚设置为输出模式
将连接IN1的GPIO引脚设置为输出模式
将连接IN2的GPIO引脚设置为输出模式
DO FOREVER
将IN1设置为0,IN2设置为1,将电机设置为正向转动
将ENA设置为1,驱动A通道电机转动
等待5秒
将ENA设置为0,停止电机转动
等待2秒
将IN1设置为1,IN2设置为0,将电机设置为反向转动
将ENA设置为1,驱动A通道电机转动
等待5秒
将ENA设置为0,停止电机转动
等待2秒
ENDO
停止PWM
清理释放GPIO资源
END
提示:
除了采用将ENA置0的方法来让电机停止转动,将IN1和IN2同时设置为0或1也可以让电机停止下来。
- 控制电机转速思路
BEGIN
引入GPIO库
将连接ENA的GPIO引脚设置为输出模式
将连接IN1的GPIO引脚设置为输出模式
将连接IN2的GPIO引脚设置为输出模式
设置ENA输入一定频率的PWM脉冲信号,创建PWM对象
开始向ENA输入占空比为0的PWM脉冲信号
DO FOREVER
将IN1设置为0,IN2设置为1,将电机设置为正向转动
将ENA设置为1,驱动A通道电机转动
speed = 0
DOWHILE speed < 100
将输入ENA的PWM脉冲信号的占空比修改为speed
speed += 5
等待1秒
ENDDO
将IN1设置为1,IN2设置为0,将电机设置为反向转动
将ENA设置为1,驱动A通道电机转动
speed = 0
DOWHILE speed < 100
将输入ENA的PWM脉冲信号的占空比修改为speed
speed += 5
等待1秒
ENDDO
ENDO
停止PWM
清理释放GPIO资源
END
电机的转向控制和转速控制的程序思路的最大区别在于ENA输入信号的不同。控制电机转向的程序思路只是简单的通过将ENA设置为1或0来启动和停止电机。对于电机转速控制,ENA输入的PWM脉冲信号,通过改变PWM脉冲信号的占空比来改变电机转速,占空比越大速度就越快,占空比为100%时相当于输入1(高电平),占空比为0%时相当于输入0(低电平)。
7.3.3 程序代码
以下是直流电机转向和转速控制程序,程序的详细说明见注释。
- 控制电机转向程序
import RPi.GPIO as GPIO # 引入GPIO模块
import time # 引入time模块
ENA = 13
IN1 = 19
IN2 = 26
if __name__ == '__main__':
try:
# 初始化
GPIO.setmode(GPIO.BCM) # 使用BCM编号方式
GPIO.setup(ENA, GPIO.OUT) # 将连接ENA的GPIO引脚设置为输出模式
GPIO.setup(IN1, GPIO.OUT) # 将连接IN1的GPIO引脚设置为输出模式
GPIO.setup(IN2, GPIO.OUT) # 将连接IN2的GPIO引脚设置为输出模式
while True:
# 驱动电机正向旋转5秒
GPIO.output(IN1, False) # 将IN1设置为0
GPIO.output(IN2, True) # 将IN2设置为1
GPIO.output(ENA, True) # 将ENA设置为1,启动A通道电机
time.sleep(5) # 等待电机转动5秒
# 电机停止2秒
GPIO.output(ENA, False) # 将ENA设置为0
time.sleep(2) # 等待电机停止2秒
# 驱动电机反向旋转5秒
GPIO.output(IN1, True) # 将IN1设置为1
GPIO.output(IN2, False) # 将IN2设置为0
GPIO.output(ENA, True) # 将ENA设置为1,启动A通道电机
time.sleep(5) # 等待电机转动5秒
# 电机停止2秒
GPIO.output(ENA, False) # 将ENA设置为0
time.sleep(2) # 等待电机停止2秒
finally:
pwm.stop() # 停止PWM
GPIO.cleanup() # 清理释放GPIO资源,将GPIO复位
运行这个程序后,您将看到直流电机反复的正向转动5秒后,停止两秒,再反向转动5秒后,停止2秒。
- 控制电机转速程序
import RPi.GPIO as GPIO # 引入GPIO模块
import time # 引入time模块
ENA = 13
IN1 = 19
IN2 = 26
if __name__ == '__main__':
try:
# 初始化
GPIO.setmode(GPIO.BCM) # 使用BCM编号方式
GPIO.setup(ENA, GPIO.OUT) # 将ENA对应的GPIO引脚设置为输出模式
GPIO.setup(IN1, GPIO.OUT) # 将IN1对应的GPIO引脚设置为输出模式
GPIO.setup(IN2, GPIO.OUT) # 将IN2对应的GPIO引脚设置为输出模式
freq = 500
speed = 0
pwm = GPIO.PWM(ENA, freq) # 设置向ENA输入PWM脉冲信号,频率为freq并创建PWM对象
pwm.start(speed) # 以speed的初始占空比开始向ENA输入PWM脉冲信号
while True:
# 将电机设置为正向转动
GPIO.output(IN1, False) # 将IN1设置为0
GPIO.output(IN2, True) # 将IN2设置为1
# 通过改变PWM占空比,让电机转速不断加快
for speed in range(0, 100, 5):
pwm.ChangeDutyCycle(speed) # 改变PWM占空比
time.sleep(1)
# 将电机设置为反向转动
GPIO.output(IN1, True) # 将IN1设置为1
GPIO.output(IN2, False) # 将IN2设置为0
# 通过改变PWM占空比,让电机转速不断加快
for speed in range(0, 100, 5):
pwm.ChangeDutyCycle(speed) # 改变PWM占空比
time.sleep(1)
finally:
pwm.stop() # 停止PWM
GPIO.cleanup() # 清理释放GPIO资源,将GPIO复位
运行这个程序后,您将看到直流电机首先正向转动,转动速度不断增加,在达到最大转速后,直流电机短暂停止转动,然后反向转动,转动速度不断增加,如此反复运动。
7.4 本章小结
本章首先介绍了直流电机的基本知识,然后介绍了L298N双H桥直流电机驱动模块的相关基础知识,最后介绍了使用树莓派和L298N双H桥直流电机驱动模块来控制一个直流电机的转向和转速的电路、思路和程序等知识。
后记
最近工作太忙,项目在赶进度,几乎每周都有几天要跑现场,这两周又增加网络安全的事情,断断续续写了一个多月,乘着端午小长假陪完家人还有点时间,好不容易才把这篇给完成了。写这篇文章的成本算是较低,就烧坏了两个一块多钱的小直流电机。另外,把十几年没用过的烙铁又整了出来,居然还能焊得上,且没烧东西,算是对得起当年的老师哈!