Raspberry Pi GPIO 教程(6)直流电机控制

如果您打算组装新的机器人,您最终会想要学习如何控制直流电机。控制直流电机最简单、最便宜的方法是使用 L293D 电机驱动器 IC 。它可以控制两个直流电机的速度和旋转方向。

要完全控制直流电机,我们必须控制其速度和旋转方向。这可以通过结合这两种技术来实现。

PWM — 控制速度

H-Bridge — 控制旋转方向

PWM 是一种通过发送一系列 ON-OFF 脉冲来调整输入电压平均值的技术。平均电压与脉冲宽度(称为占空比)成正比。占空比越高,施加到直流电机的平均电压就越高(导致速度越高);占空比越短,施加到直流电机的平均电压就越低(导致速度越低)。

下图显示了具有不同占空比和平均电压的PWM技术。

Image

H 桥 — 控制旋转方向

直流电机的旋转方向可以通过改变其输入电压的极性来控制。一种常用的技术是使用 H 桥。

H 桥电路由四个开关组成,电机位于中心,形成 H 形排列。同时关闭两个特定开关可反转施加到电机上的电压极性。这会导致电机旋转方向发生变化。

L293D 电机驱动器 IC

L293D 是一款双通道 H 桥电机驱动器,能够驱动一对直流电机或单个步进电机。这意味着它可以单独驱动最多两个电机,非常适合构建两轮机器人平台。

Image

L293D 最常用于驱动电机,但也可用于驱动任何电感负载,如电磁阀或大型开关功率晶体管。它能够驱动四个电磁阀、四个单向直流电机、两个双向直流电机或一个步进电机。L293D IC 的供电范围为 4.5V 至 36V,每通道峰值输出电流为 1.2A,因此可与我们的大多数电机完美配合。该 IC 还包括内置反冲二极管,以防止电机断电时造成损坏。

技术规格

马达输出电压4.5V – 36V
逻辑输入电压5V
单通道输出电流600mA
单通道峰值电流1.2A

L293D 电机驱动器 IC 引脚排列

L293D IC 共有 16 个引脚,用于将其连接到外部世界。引脚排列如下:

Image

让我们逐一认识所有引脚。电源引脚:

Image

L293D 电机驱动器 IC 实际上有两个输入电源引脚 – VS 和 VSS。

VS (Vcc2) 引脚为 IC 的内部 H 桥供电以驱动电机。您可以将 4.5 至 36V 之间的任何输入电压连接到此引脚。

VSS (Vcc1) 用于驱动内部逻辑电路,电压应为 5V。

GND 引脚是公共接地引脚。所有 4 个 GND 引脚均内部连接,用于散发高负载条件下产生的热量。输出引脚:

Image

L293D 电机驱动器的电机 A 和 B 输出通道分别连接到引脚 OUT1、OUT2 和 OUT3、OUT4。您可以将两个 5-36V 直流电机连接到这些引脚。

IC 上的每个通道都可以为直流电机提供高达 600mA 的电流。但是,提供给电机的电流量取决于系统的电源。

方向控制引脚:

通过使用方向控制引脚,您可以控制电机是向前还是向后旋转。这些引脚实际上控制 L293D IC 内部 H 桥电路的开关。

Image

该 IC 的每个通道都有两个方向控制引脚。IN1 和 IN2 引脚控制电机 A 的旋转方向;而 IN3 和 IN4 控制电机 B 的旋转方向。

可以通过向这些输入施加逻辑高电平 (5V) 或逻辑低电平 (接地) 来控制电机的旋转方向。下图显示了如何做到这一点。

IN1IN2旋转方向
低(0)低(0)关闭
高(1)低(0)向前
低(0)高(1)向后
高(1)高(1)关闭

速度控制引脚:

Image

速度控制引脚 ENA 和 ENB 用于打开/关闭电机并控制其速度。

将这些引脚拉高将导致电机旋转,而将其拉低将使电机停止。但是,使用脉冲宽度调制 (PWM),您实际上可以控制电机的速度。电路模拟在Proteus中新建一个Raspberry4的项目,添加L293D芯片和直流电机。

Image

引脚接线如下:IN1 –> GPIO17IN2 –> GPIO27EN1 –> GPIO22VSS –> 12V,给电机供电。VS –>5V,给L293D芯片供电。Out1, Out2分别接电机两条引线。编写以下代码:

import RPi.GPIO as GPIO
import time

# Pin configuration
IN1 = 17  # Input pin 1 for motor direction
IN2 = 27  # Input pin 2 for motor direction
ENABLE = 22  # Enable pin for motor speed control

# GPIO setup
GPIO.setmode(GPIO.BCM)  # Use BCM numbering
GPIO.setup(IN1, GPIO.OUT)
GPIO.setup(IN2, GPIO.OUT)
GPIO.setup(ENABLE, GPIO.OUT)

# Initialize PWM on the ENABLE pin
pwm = GPIO.PWM(ENABLE, 100)  # 100Hz frequency
pwm.start(0)  # Start with motor off

def motor_forward(speed):
    """Run the motor forward at a given speed (0-100)."""
    GPIO.output(IN1, GPIO.HIGH)
    GPIO.output(IN2, GPIO.LOW)
    pwm.ChangeDutyCycle(speed)

def motor_backward(speed):
    """Run the motor backward at a given speed (0-100)."""
    GPIO.output(IN1, GPIO.LOW)
    GPIO.output(IN2, GPIO.HIGH)
    pwm.ChangeDutyCycle(speed)

def motor_stop():
    """Stop the motor."""
    GPIO.output(IN1, GPIO.LOW)
    GPIO.output(IN2, GPIO.LOW)
    pwm.ChangeDutyCycle(0)

try:
    while True:
        # Example usage
        print("Motor running forward")
        motor_forward(50)  # Run forward at 50% speed
        time.sleep(5)

        print("Motor running backward")
        motor_backward(50)  # Run backward at 50% speed
        time.sleep(5)

        print("Motor stopping")
        motor_stop()  # Stop the motor
        time.sleep(5)

except KeyboardInterrupt:
    print("Program terminated by user")

finally:
    pwm.stop()
    GPIO.cleanup()

运行结果:

将电机速度调为100%

motor_forward(100)

再次运行结果:

可以看到电机旋转速度明显加快。