古月金真
1、直流电机
直流电机是一种将直流电能转换为机械能的装置,被广泛的用于驱动各种设备,如电风扇、遥控小车、电动车窗等,在控制设备运转领域中,它是不可或缺的一种设备。
小型直流电机的的电压范围通常是1.5V~30V,使用两根导线连接到直流电源上就能让电机转动起来,电压越高转得就越快。每个直流电机都有一个推荐电压,超出推荐电压太多容易导致电机被烧毁,而供电电压太低则转不起来。通过交换两根连接在电机上的导线顺序(实际上是改变电源的正负极),可以改变电机的转向。直流电机属于高功耗元件,不可以直接使用树莓派进行驱动,因此我们需要使用一个外部电源。
小型直流电机通常输出很高的转速和较低的扭矩,在作为机器人的驱动装置时,一般需要连接一个变速器,将其转换为低转速、高扭矩,使之有足够的力量驱动机器人。
下图为一个普通的直流电机图片。
2、双H桥直流电机驱动模块(L298N)
H桥(H-Bridge)是控制直流电机的常用电路,因其电路形状酷似字母H而得名,可以控制直流电机的转速和方向,典型的H桥芯片有L293D、L298N等,我们以L298N为例进行介绍,下图是一款典型的L298N双H桥直流电机驱动模块。
- 采用L298N双桥直流电机驱动芯片
- 工作电压范围5V~35V,如果需要从模块内取电,则供电范围为7V—35V。
- 峰值输出电流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与此类似。
3.电路
下图为树莓派、L298N双H桥直流电机驱动模块和电机间连接的电路图,最终实物连线图如图7.4所示。我们使用树莓派的GPIO13、GPIO19和GPIO26等3个引脚,分别连接到L298N双H桥直流电机驱动模块的ENA、IN1和IN2,通过输入表7.1所示的不同电平组合就可以实现对电机的操纵。控制电机的转向和转速都是使用该电路,向ENA输入不同占空比的PWM脉冲信号就可以控制电机的转速。
4、程序
- 一、控制电机转动
import RPi.GPIO as GPIO # 引入GPIO模块
ENA = 13 #定义对应的引脚变量(等一下用)
IN1 = 19
IN2 = 26
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: #循环
GPIO.output(IN1, False) # 将IN2设置为1
GPIO.output(IN2, True) # 将IN2设置为1
GPIO.output(ENA, True) # 将ENA设置为1,启动A通道电机
input()
GPIO.cleanup()
运行上面程序时,电机以L298N模块输出的最大电压正转。
二、控制电机转动并调速
import RPi.GPIO as GPIO # 引入GPIO模块
ENA = 13 #定义对应的引脚变量(等一下用)
IN1 = 19
IN2 = 26
hz = 500 #定义频率变量(等一下用)
speed = 0 #定义占空比变量(等下用)运行时默认的占空比为0
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引脚设置为输出模式
pwm = GPIO.PWM(ENA, hz) # 设置向ENA输入PWM脉冲信号,频率为hz并创建PWM对象
pwm.start(speed) # 以speed的初始占空比开始向ENA输入PWM脉冲信号
while True:
speed = int(input("Please input motor speed (1-100): ")) #程序运行时通过键盘输入占空比改变电机转速
pwm.ChangeDutyCycle(speed) # 改变PWM占空比
GPIO.output(IN1, GPIO.LOW) # 将IN1设置为0
GPIO.output(IN2, GPIO.HIGH) # 将IN2设置为1 ,电机正转
input()
GPIO.cleanup()
当程序运行时,电机不转动,当输入在0~100数值的占空比后电机转动,输入数值越大L298N模块输出的最大电压越大,当输入数值100时电机以L298N模块输出的最大电压正转,当输入数值0时,L298N模块输出电压为0v,电机不转动,运行操作如下图所示。
三、控制电机正转、反转和停止
import RPi.GPIO as GPIO # 引入GPIO模块
ENA = 13 #定义对应的引脚变量(等一下用)
IN1 = 19
IN2 = 26
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引脚设置为输出模式
a = int(input("zheng zhuan 0 ,fan zhuan 1, ting 2 : ")) #程序运行时通过键盘输入0、1、2分别控制电机正转、反转和停止
while True:
if a == 0: #如果键盘输入的数值为0,则电机正转
while 1:
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
GPIO.output(ENA, GPIO.HIGH)
a = int(input("zheng zhuan 0 ,fan zhuan 1, ting 2 : "))
if (a == 1 or a == 2):
break
if a == 1: #如果键盘输入的数值为1,则电机反转
while 1:
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(ENA, GPIO.HIGH)
a = int(input("zheng zhuan 0 ,fan zhuan 1, ting 2 : "))
if (a == 0 or a == 2):
break
if a == 2: #如果键盘输入的数值为2,则电机停止转动
while 1:
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(ENA, GPIO.LOW)
a = int(input("zheng zhuan 0 ,fan zhuan 1, ting 2 : "))
if (a == 0 or a == 1):
break
input()
GPIO.cleanup()
当程序运行时,如果键盘输入的数值为0,则电机正转。 如果键盘输入的数值为1,则电机反转。如果键盘输入的数值为2,则电机停止转动,运行参照如下图所示。
四、控制电机正转、反转和停止并现在速度的控制
import RPi.GPIO as GPIO # 引入GPIO模块
ENA = 13 #定义对应的引脚变量(等一下用)
IN1 = 19
IN2 = 26
hz = 500 #定义频率变量(等一下用)
speed = 0 #定义占空比变量(等下用)运行时默认的占空比为0
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引脚设置为输出模式
pwm = GPIO.PWM(ENA, hz) # 设置向ENA输入PWM脉冲信号,频率为hz并创建PWM对象
pwm.start(speed) # 以speed的初始占空比开始向ENA输入PWM脉冲信号
a = int(input("Positive : 0 , Reversal:1, Stop: 2, speed:3 :")) #键盘输入0、1、2、3可控制电机正、反、停和改变速度。
speed = int(input("Please input the motor speed (0-100): ")) #键盘输入电机开始运行的速度
while True:
if a == 0: #如果键盘输入的数值为0,则电机正转
while 1:
if a == 3: #如果键盘输入的数值为3,输入数值0~100可改变占空比来改变电机转速
speed = int(input("Please input the motor speed (0-100): "))
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.HIGH)
pwm.ChangeDutyCycle(speed) # 改变PWM占空比
a = int(input("Positive : 0 , Reversal:1, Stop: 2, speed: 3 :"))
if (a == 1 or a == 2):
break
if a == 1: #如果键盘输入的数值为1,则电机反转
while 1:
if a == 3:
speed = int(input("Please input the motor speed (0-100): "))
GPIO.output(IN1, GPIO.HIGH)
GPIO.output(IN2, GPIO.LOW)
pwm.ChangeDutyCycle(speed)
a = int(input("Positive : 0 , Reversal:1, Stop: 2, speed: 3 :"))
if (a == 0 or a == 2):
break
if a == 2: #如果键盘输入的数值为2,则电机停止转动
while 1:
if a == 3:
speed = int(input("Please input the motor speed (0-100): "))
GPIO.output(IN1, GPIO.LOW)
GPIO.output(IN2, GPIO.LOW)
GPIO.output(ENA, GPIO.LOW)
a = int(input("Positive : 0 , Reversal:1, Stop: 2, speed: 3 :"))
if (a == 0 or a == 1):
break
input()
GPIO.cleanup()
当程序运行时,如果键盘输入的数值为0,则电机正转。 如果键盘输入的数值为1,则电机反转。如果键盘输入的数值为2,则电机停止转动。如果键盘输入的数值为3,可以输入数值0~100可改变占空比来改变电机转速,输入数值越大L298N模块输出的最大电压越大,当输入数值100时电机以L298N模块输出的最大电压正转,当输入数值0时,L298N模块输出电压为0v,电机不转动,运行操作如下图所示。