那好吧!我们制造了一个机器人来照顾你的花园,我希望它能正常工作。是时候把事情提升到另一个层次了。
我们一直认为机器人就像 WALL-E 一样,四处移动,为我们做事。好吧,我的朋友,现在梦想已经不远了。事实上,在本章中,我们将继续并制作一个。让我们看看是怎么做的
我们将讨论以下主题:
每当我们谈论从一个地方移动到另一个地方时,我们都会想到轮子,同样地,每当我们想到移动机器人的轮子时,我们都会想到马达。存在各种不同类型的电机。让我们首先来看看最基本的电机类型,它被称为有刷直流电机。顾名思义,它是用直流电工作的。您可能会发现这样的电机:
相信我,这些东西无所不在,从你给邻居买的圣诞礼物到外面最大最坏的机器,你会发现这些马达藏在引擎盖下。这些电机之所以常见是因为它们非常非常简单。简单到只需要一个电池和两根电线就可以给它们通电。只需将正极连接到一个端子,负极连接到另一个端子,电机就会开始旋转。交换这些连接,旋转方向将改变。拿两个电池,电压加倍,马达就会转得更快。就这么简单。
现在你可以假设我们只需将这个马达连接到 RespberryPi 上,我们就可以开始了。但不幸的是,情况并非如此。正如你可能记得从前面的章节,覆盆子皮只能提供约 50 毫安,但一个电机的消耗可以高得多。因此,要运行一个,我们需要一个中间设备
你想到的第一件事就是使用继电器,为什么不呢?它们能输送大量电流,并能处理高电压。这应该是理想的选择。如果你这么认为的话,你是对的,但只是在某种程度上,这是因为继电器只是一个开关,我们可以用来打开或关闭电机。我们将无法控制电机的速度或旋转方向。现在,你会认为这个问题不是新问题,我们可以很容易地用脉宽调制(PWM来解决它,对吗?答案是否定的!由于这些继电器是机械装置,并且由于其机械性质,在一秒钟内打开或关闭继电器时存在一些最大限制。因此,它将无法处理 PWM 的频率。最后,我们仍将面临改变电机方向和速度的问题。那我们现在该怎么办?
正如我常说的,问题的美妙之处在于它总是有一个解决方案,这里的解决方案被称为马达驱动器。电机驱动器主要是一组电子继电器——一种可以允许高电流但不是机械式的开关。因此,我们可以每秒切换数百次。这些电子继电器要么由简单的晶体管制成,要么在大功率应用中,它们甚至可以使用 MOSFET 进行开关。我们可以简单地对这些电子开关进行 PWM,并在确保向电路输送足够电流的同时对电压进行调制。此外,正如我前面提到的,电机驱动器由一组电子继电器组成。最常见和可行的方式,他们被安排称为一个完整的桥梁或 H 桥。在我进一步解释之前,让我们看看这到底是什么:
在全桥中,我们在连接的电机上有四个开关电路;可根据需要单独打开或关闭这些开关。在关闭状态下,所有这些开关电路都处于打开状态,因此保持电机关闭。现在,无论何时我们想要启动电机,我们都必须打开两个开关,这样电路就完成了,电机开始工作。让我们看看它会是什么样子:
这里,我们打开了开关电路S2和S3;这反过来又完成了电路,并让电流在电机中流动。现在,为了控制速度,这些相同的开关电路可以在不同的占空比下以非常高的频率打开和关闭,以获得特定的平均电压。现在我们可以通过这两个开关电路改变电压来实现电机的特定速度,让我们看看如何改变电机的旋转方向:
在该电路中,我们关闭了先前连接的S2和S3,而打开了S1和S4,因此电机的极性颠倒。如前所述,无论何时直流刷电机的极性改变,方向也随之改变。市场上有各种类型的马达驱动器。我们在这里所了解的是所谓的刷直流 H 桥电机驱动器;还有其他类型的电机驱动器,以及控制其他类型的电机,但目前我们将坚持只刷电机。选择电机驱动器时,应仔细检查电机驱动器的规格表。将提及的一些关键规范如下:
现在,让我们看看我们有什么。在本书的学习过程中,我们将使用 L298N 电机驱动模块,它是目前市场上最常见的电机驱动模块之一。它有两个通道,你有两个 H 桥,因此你可以连接两个电机到它。此外,该电机驱动器的规格也符合价格要求。以下是规格:
一旦随身携带物理电机驱动器,您将注意到以下针脚:
好的,这是很多理论,现在让我们通过 Raspberry Pi 启动一个电机。要执行此操作,请继续连接电机和电机驱动器,如图所示:
现在,完成后,让我们上传代码,看看会发生什么:
import RPi.GPIO as GPIO
from time import sleep
GPIO.setmode(GPIO.BCM)
Motor1R = 20
Motor1L = 21
GPIO.setup(Motor1R,GPIO.OUT)
GPIO.setup(Motor1L,GPIO.OUT)
GPIO.output(Motor1R,GPIO.HIGH)
GPIO.output(Motor1L,GPIO.LOW)
sleep(5)
GPIO.output(Motor1R,GPIO.LOW)
GPIO.output(Motor1L,GPIO.HIGH)
sleep(5)
GPIO.cleanup()
现在,让我们稍微了解一下代码:
Motor1R = 20
Motor1L = 21
引脚编号20
连接到电机驱动器的 IN 1。为方便起见,我们将电机 1 右侧改为Motor1R
;事实上,马达可以朝任何方向旋转,但我们写这篇文章只是为了方便和理解。同样,我们也为Motor1L
做了这项工作。这与 IN 2 相连,因此这将导致电机朝另一个方向旋转:
GPIO.output(Motor1R,GPIO.HIGH)
GPIO.output(Motor1L,GPIO.LOW)
这里,我们将Motor1R
或引脚编号20
设为高,这意味着输入电机驱动器得到的是:
| 电机 | 引脚 | 输入 | 状态 |
| Motor 1R
| RespberryPi 的第 20 针 | 在 1 | HIGH
|
| Motor 1L
| RespberryPi 的 21 号插针 | 在 2 | LOW
|
现在,延迟 5 秒后,将运行以下代码,该代码将改变下表中所示的管脚状态:
GPIO.output(Motor1R,GPIO.LOW)
GPIO.output(Motor1L,GPIO.HIGH)
| 电机 | 引脚 | 输入 | 状态 |
| Motor 1R
| RespberryPi 的第 20 针 | 在 1 | LOW
|
| Motor 1L
| RespberryPi 的 21 号插针 | 在 2 | HIGH
|
现在,让我们看看一旦我们运行它会发生什么。电机将先朝一个方向旋转,然后再朝另一个方向旋转。代码非常简单,我认为不需要任何解释。我们在这里所做的只是打开和关闭连接到马达驱动器的两个 GPIO 中的任何一个。一旦电机驱动器的输入 1 被激活,H 桥的一部分被打开,导致电机朝一个方向旋转。每当电机驱动器的 IN 2 高时,H 桥的相反部分接通,导致电机驱动器输出端的极性改变,从而电机转向另一个方向。
现在,我们已经了解了如何使用电机驱动器改变电机的方向,是时候进一步使用电机驱动器控制电机的速度了。要做到这一点,我们真的不需要做太多。电机驱动器用于理解 PWM 信号。向电机驱动器提供 PWM 信号后,电机驱动器依次调整电机的输出电压,从而改变电机驱动器的速度。必须在电机 A 的 1 和 2 以及电机 B 的 3 和 4 的相同输入端口上提供 PWM。显然,提供 PWM 的引脚将决定电机的移动方向,PWM 的占空比将决定电机旋转的速度
现在我们已经了解了电机驱动器中的速度控制是如何工作的。是我们自己做这件事的时候了。为此,我们不需要对连接进行任何更改;我们只需上传以下代码:
import RPi.GPIO as GPIO
from time
import sleep
GPIO.setmode(GPIO.BCM)
Motor1R = 20
Motor1L = 21
GPIO.setup(Motor1R, GPIO.OUT)
GPIO.setup(Motor1L, GPIO.OUT)
pwm = GPIO.PWM(Motor1R, 100)
pwm.start(0)
try:
while True:
GPIO.output(Motor1L, GPIO.LOW)
for i in range(0, 101):
pwm.ChangeDutyCycle(i)
sleep(0.1)
except KeyboardInterrupt:
pwm.stop()
GPIO.cleanup()
运行此代码后发生了什么?我确信马达启动缓慢,然后开始加速,当达到最高速度时,它最终完全停止了我们想要它做的事情。如果您还记得,这段代码看起来非常熟悉。还记得在第一章中更改 LED 的亮度吗?这几乎是一样的;不过有一些区别,让我们看看它们是什么:
pwm = GPIO.PWM(Motor1R, 100)
在这一行中,我们只是简单地定义了我们必须在Motor1R
上提供 PWM 的管脚,它对应于管脚编号20
。此外,我们将 PWM 的频率定义为100
赫兹或每秒 100 次:
pwm.start(0)
如果您还记得,前面章节中的命令pwm.start()
主要用于定义信号的占空比。这里,我们给它的占空比为0
,即引脚将关闭:
GPIO.output(Motor1L,GPIO.LOW)
由于我们在一个特定方向上运行电机,这是1R
,因此 H 桥的另一半应该关闭。这可以通过上面的线将线1L
放低来完成。如果我们不这样做,那么引脚21
可以处于任意状态,因此它可以是开或关。这可能与电机的移动方向冲突,并且硬件无法正常工作:
for i in range(0,101):
真正的交易来了;此行for i in range(0,101):
将继续运行其中包含的程序,直到i
的值介于0
到101
之间。每次循环运行时,它也会增加i
的值。在这里,每次值都会增加 1:
pwm.ChangeDutyCycle(i)
现在,这是一个稍微新的命令。在此之前,我们使用线路pwm.start(0)
为 PWM 分配占空比。由于我们已经为 PWM 分配了一个占空比值,为了改变它,我们将使用前面提到的命令。占空比将与i
的值相同。
因此,每次代码通过for
循环时,值或占空比将增加 1。非常简单,不是吗?
如果你做对了,机器人学的一切都很容易。想法是把你的问题分解成小块,然后一个接一个地解决;相信我,一旦你这么做了,你就不会觉得有什么困难了
在本章中,我们研究了电机的各个方面。接下来,通过使用所有基础知识,我们将研究蓝牙与移动设备的交互,并构建一个蓝牙控制的机器人汽车。