维基少年:树莓派/树莓派电机控制
Mark Cantrill @AstroDesignsLtd 的教程
2017 年 6 月 24 日
cotswoldjam.org
在本教程中,我们将了解使用树莓派控制电机需要做些什么,电机驱动器的工作原理,以及使用树莓派的 PiZ-Moto 电机驱动器来控制两个电机。 我们还将了解如何编程一个小型双轮机器人。 本工作表重点介绍 PiZ-Moto 电机驱动器板的使用。
PiZ-Moto 板上有两个连接器,一个用于电机“A”,一个用于电机“B”。 连接器是螺丝端子,只需将电机的导线推入端子中,然后将连接器顶部的螺丝拧紧即可。 左边的连接器用于电机“A”,右边的连接器用于电机“B”。
在本教程中,我们只使用一个电机,但第二个电机连接器连接了几根 LED,用于显示方向变化,以及通过 LED 亮度显示电机速度变化。 LED 连接到电机“A”连接器,电机连接到电机“B”连接器。
PiZ-Moto 设计为使用 6V 4 节 AA 电池组供电。 我们在本教程中包含了其中一个电池组以及连接到 PiZ-Moto 的导线。
但为了本教程的目的,为了避免我们购买大量电池,我们暂时将一根导线从树莓派的 5V 引脚连接到 PiZ-Moto 上的 VIN (+) 连接,这使我们能够使用连接到树莓派的 5V USB 电源来运行本教程。
这对于本教程来说是可以的,因为我们只使用了一个像这样的小型电机,但我们强烈建议您剪断这条导线并使用电池组为 PiZ-Moto 供电。
在连接电池组之前,请务必取下导线,否则将永久损坏您的树莓派。 树莓派需要 5V,将 6V 电池连接到它将损坏树莓派。 |
另外请注意,当使用电池组为 PiZ-Moto 供电时,PiZ-Moto 上的 5V 稳压器将为树莓派提供 5V。 使用 PiZ-Moto 时,无需将 USB 电源连接到树莓派,事实上,如果您这样做,可能会损坏电源。
import piz_moto
piz_moto.MotorA(speed,duration)
- 其中,速度为:-100 到 +100
- 最大速度 = 100 或 -100
- 使用正速度表示前进(例如 100)
- 使用负速度表示后退(例如 -100)
- 使用较小的数字来降低电机速度(例如 50 表示半速)
- 使用 0 使电机停止
- 持续时间为:您希望电机运行的秒数。
- 例如 20 将使电机运行 20 秒。
- 例如 0.5 将使电机运行半秒
- 如果时间 = 0,则电机将一直运行,直到您通过将速度设置为 0 来告诉它停止。
电机 A 前进 10 秒
piz-moto.MotorA(100, 10)
电机 B 后退 10 秒
Piz_moto.MotorB(-100,10)
假设您在一个双轮机器人上有两个电机。 编写一个程序,让它前进 5 秒,然后后退 5 秒。
在您上一个程序中添加一个程序,以便您的机器人向左(或向右)转动 1 秒,然后改变从前进到后退的方向。
修改您的程序,以便它不是以全速前进,而是在 5 秒的时间内逐渐提高速度。
PiZ-Moto 的组装说明(如果您有套件)在 GitHub 上,其中还有一些示例。 我们已经将 GitHub 的 piz_moto
存储库克隆到教程附带的 SD 卡上,因此您已经可以开始使用了! 但请注意更新。
如何将 piz-moto
存储库克隆到您的树莓派上(如果它不在那里)。 或者,如果您只是想将一个新的副本放在一个新的文件夹中。
要将 piz_moto
克隆到您的主文件夹(/home/pi),请运行以下命令。 这将在您的主文件夹中创建一个名为 piz-moto 的文件夹,该文件夹包含简单的 piz_moto
包、说明和示例。
cd /home/pi
git clone https://github.com/astro-designs/piz-moto.git
如果您只是想检查更新,只需导航到 piz-moto 文件夹并运行 git pull
cd /home/pi/piz-moto
git pull
要获取最新的 PiZ Moto 代码,请从终端执行以下操作
mkdir -p ~/python/
cd ~/python
git clone https://github.com/astro-designs/piz-moto.git
mv piz-moto-master motors
请注意,为了运行本教程,SD 卡已准备好将 piz_moto 文件克隆到以下文件夹。 您可以在该文件夹中继续使用它,并在该文件夹中运行 git pull 函数来更新文件:/home/pi/python/motors/piz-moto
在 piz-moto 文件夹中找到的说明值得一读,因为它们解释了有关 PiZ-Moto 的所有内容。 有一点,它不仅仅是一个电机驱动器......PiZ-Moto 包含简单的接口,允许您连接超声波测距传感器和红外光电传感器。
它还包含一个 5V 稳压器,您可以使用它为树莓派供电。 此外,还有两个通用输出,包括一个板载串联 100 欧姆电阻,因此您可以将几根 LED 直接连接到这些引脚。
使用您的树莓派的 PiZ-Moto 电机驱动器板玩得开心!
import RPi.GPIO as GPIO # Import the GPIO Library
import time
from .motors import Motor1
from .motors import Motor2
from .motors import Stop
from .motors import Forwards
from .motors import Backwards
from .motors import SpinLeft
from .motors import SpinRight
from .motors import FLeft
from .motors import FRight
from .motors import BLeft
from .motors import BRight
__all__ = ['Stop', 'Forwards', 'Backwards', 'SpinLeft', 'SpinRight', 'FLeft', 'FRight', 'BLeft', 'BRight']
global pinMotorAForwards, pinMotorABackwards
# Set variables for the GPIO motor pins
pinMotorAForwards = 10
pinMotorABackwards = 9
pinMotorBForwards = 7
pinMotorBBackwards = 8
# Set variables for the line detector GPIO pin
pinLineFollower = 25
# Define GPIO pins to use on the Pi
pinTrigger = 17
pinEcho = 18
# Set variable for the LED pin
pinLED1 = 5
pinLED2 = 6
# How many times to turn the pin on and off each second
Frequency = 50
# How long the pin stays on each cycle, as a percent
DCA = 100
DCB = 100
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.setup(pinMotorAForwards, GPIO.OUT)
GPIO.setup(pinMotorABackwards, GPIO.OUT)
GPIO.setup(pinMotorBForwards, GPIO.OUT)
GPIO.setup(pinMotorBBackwards, GPIO.OUT)
pwmMotorAForwards = GPIO.PWM(pinMotorAForwards, Frequency)
pwmMotorABackwards = GPIO.PWM(pinMotorABackwards, Frequency)
pwmMotorBForwards = GPIO.PWM(pinMotorBForwards, Frequency)
pwmMotorBBackwards = GPIO.PWM(pinMotorBBackwards, Frequency)
pwmMotorAForwards.start(0)
pwmMotorABackwards.start(0)
pwmMotorBForwards.start(0)
pwmMotorBBackwards.start(0)
def Motor1(SpeedAndDirection, duration=0):
motors.Motor1(SpeedAndDirection, pwmMotorAForwards, pwmMotorABackwards)
if duration > 0:
time.sleep(duration)
motors.Motor1(0, pwmMotorAForwards, pwmMotorABackwards)
def Motor2(SpeedAndDirection, duration=0):
motors.Motor2(SpeedAndDirection, pwmMotorBForwards, pwmMotorBBackwards)
if duration > 0:
time.sleep(duration)
motors.Motor2(0, pwmMotorBForwards, pwmMotorBBackwards)
def Stop():
motors.Stop(pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards)
def Backwards(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.Backwards(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.Backwards(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def Forwards(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.Forwards(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.Forwards(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def SRight(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.SpinRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.SpinRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def BLeft(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.BLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.BLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def FLeft(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.FLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.FLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def SLeft(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.SpinLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.SpinLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def BRight(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.BRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.BRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
def FRight(Speed, duration):
if Speed > 1: Speed = 1
elif Speed < 0: Speed = 0
motors.FRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed)
if duration > 0:
time.sleep(duration)
motors.FRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, 0)
#!/usr/bin/env python2.7
# PiZ-Moto Motor Control Functions
# First some basic motor control functions to control each motor separately
# SpeedAndDirection can be a number between +100 & -100
# +100 or any value greater than zero spins the motor forwards
# -100 or any value less than zero spins the motor backwards
# 100 or -100 (100% duty-cycle) spins the motor at full speed
# 50 or -50 (50% duty-cycle) spins the motor at half speed
#Motor 1
def Motor1(SpeedAndDirection, pwmMotorAForwards, pwmMotorABackwards):
if SpeedAndDirection > 100:
SpeedAndDirection = 100
if SpeedAndDirection < -100:
SpeedAndDirection = -100
if(SpeedAndDirection < 0):
SpeedAndDirection = SpeedAndDirection * -1
pwmMotorAForwards.ChangeDutyCycle(0)
pwmMotorABackwards.ChangeDutyCycle(SpeedAndDirection)
else: # Forwards...
pwmMotorAForwards.ChangeDutyCycle(SpeedAndDirection)
pwmMotorABackwards.ChangeDutyCycle(0)
#Motor 2
def Motor2(SpeedAndDirection, pwmMotorBForwards, pwmMotorBBackwards):
if SpeedAndDirection > 100:
SpeedAndDirection = 100
if SpeedAndDirection < -100:
SpeedAndDirection = -100
if(SpeedAndDirection < 0): # Backwards...
SpeedAndDirection = SpeedAndDirection * -1
pwmMotorBForwards.ChangeDutyCycle(0)
pwmMotorBBackwards.ChangeDutyCycle(SpeedAndDirection)
else: # Forwards...
pwmMotorBForwards.ChangeDutyCycle(SpeedAndDirection)
pwmMotorBBackwards.ChangeDutyCycle(0)
# Next, some functions to control both motors for driving a two motor, two-wheeled robot...
# Function to turn all motors off
def Stop(pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards):
#print("Stop")
pwmMotorAForwards.ChangeDutyCycle(0)
pwmMotorABackwards.ChangeDutyCycle(0)
pwmMotorBForwards.ChangeDutyCycle(0)
pwmMotorBBackwards.ChangeDutyCycle(0)
# Turn both motors backwards
def Backwards(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Backwards")
pwmMotorAForwards.ChangeDutyCycle(DCA * Speed)
pwmMotorABackwards.ChangeDutyCycle(0)
pwmMotorBForwards.ChangeDutyCycle(DCB * Speed)
pwmMotorBBackwards.ChangeDutyCycle(0)
# Turn both motors forwards
def Forwards(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Forwards")
pwmMotorAForwards.ChangeDutyCycle(0)
pwmMotorABackwards.ChangeDutyCycle(DCA * Speed)
pwmMotorBForwards.ChangeDutyCycle(0)
pwmMotorBBackwards.ChangeDutyCycle(DCB * Speed)
# Spin Right
def SpinRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Spin Right")
pwmMotorAForwards.ChangeDutyCycle(0)
pwmMotorABackwards.ChangeDutyCycle(DCA * Speed)
pwmMotorBForwards.ChangeDutyCycle(DCB * Speed)
pwmMotorBBackwards.ChangeDutyCycle(0)
def BLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Back Left")
pwmMotorAForwards.ChangeDutyCycle(DCA * Speed * 0.5)
pwmMotorABackwards.ChangeDutyCycle(0)
pwmMotorBForwards.ChangeDutyCycle(DCB * Speed)
pwmMotorBBackwards.ChangeDutyCycle(0)
def FLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Forwards Left")
pwmMotorAForwards.ChangeDutyCycle(0)
pwmMotorABackwards.ChangeDutyCycle(DCA * Speed * 0.5)
pwmMotorBForwards.ChangeDutyCycle(0)
pwmMotorBBackwards.ChangeDutyCycle(DCB * Speed)
# Spin left
def SpinLeft(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Spin Left")
pwmMotorAForwards.ChangeDutyCycle(DCA * Speed)
pwmMotorABackwards.ChangeDutyCycle(0)
pwmMotorBForwards.ChangeDutyCycle(0)
pwmMotorBBackwards.ChangeDutyCycle(DCB * Speed)
def BRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Back Right")
pwmMotorAForwards.ChangeDutyCycle(DCA * Speed)
pwmMotorABackwards.ChangeDutyCycle(0)
pwmMotorBForwards.ChangeDutyCycle(DCB * Speed * 0.5)
pwmMotorBBackwards.ChangeDutyCycle(0)
def FRight(DCA, DCB, pwmMotorAForwards, pwmMotorABackwards, pwmMotorBForwards, pwmMotorBBackwards, Speed):
#print("Forwards Right")
pwmMotorAForwards.ChangeDutyCycle(0)
pwmMotorABackwards.ChangeDutyCycle(DCA * Speed)
pwmMotorBForwards.ChangeDutyCycle(0)
pwmMotorBBackwards.ChangeDutyCycle(DCB * Speed * 0.5)
#!/usr/bin/env python2.7
# PiZ-Moto tutorial task #1
# A program to make a two wheeled robot travel forwards for 5 seconds
# and then travel backwards for 5 seconds
# Import the piz-moto package
import piz_moto
import time
# Move forwards...
# Note that one motor must spin in the opposite direction to the other
# because it's on the opposite side of the robot
print("First we're moving forwards...")
piz_moto.Motor1(100)
piz_moto.Motor2(-100)
# wait 5 seconds
time.sleep(5)
# Move backwards...
# Note that one motor must spin in the opposite direction to the other
# because it's on the opposite side of the robot
print("Now we're moving backwards...")
piz_moto.Motor1(-100)
piz_moto.Motor2(100)
# wait 5 seconds
time.sleep(5)
# This is the really important bit - we need to stop the motors when finished...
piz_moto.Motor1(0)
piz_moto.Motor2(0)
# Important delay - for some reason if this delay isn't here
# the motors don't stop.
# I suspect the program needs a cleaner exit
time.sleep(1)
#!/usr/bin/env python2.7
# PiZ-Moto tutorial task #1
# A program to make a two wheeled robot travel forwards for 5 seconds
# and then travel backwards for 5 seconds
# Import the piz-moto package
import piz_moto
import time
# Move forwards...
# Note that one motor must spin in the opposite direction to the other
# because it's on the opposite side of the robot
print("First we're moving forwards...")
piz_moto.Motor1(100)
piz_moto.Motor2(-100)
# wait 5 seconds
time.sleep(5)
# Turn left...
# Here we make one wheel turn one way as if the robot was moving forwards and
# make the other wheel turn the opposite way as if the robot was moving backwards.
# Make the left wheel run backwards and the right wheel run forwards should
# make the robot spin to the left (or anti-clockwise)
# But don't forget that the motors are on opposite sides...
print("Now we're turning left...")
piz_moto.Motor1(100)
piz_moto.Motor2(100)
# wait 1 seconds
time.sleep(1)
# Move backwards...
# Note that one motor must spin in the opposite direction to the other
# because it's on the opposite side of the robot
print("Now we're moving backwards...")
piz_moto.Motor1(-100)
piz_moto.Motor2(100)
# wait 5 seconds
time.sleep(5)
# This is the really important bit - we need to stop the motors when finished...
piz_moto.Motor1(0)
piz_moto.Motor2(0)
# Important delay - for some reason if this delay isn't here
# the motors don't stop.
# I suspect the program needs a cleaner exit
time.sleep(1)
#!/usr/bin/env python2.7
# PiZ-Moto tutorial task #1
# A program to make a two wheeled robot travel forwards for 5 seconds
# and then travel backwards for 5 seconds
# Import the piz-moto package
import piz_moto
import time
# Initialise the speed, setting it to zero for the acceleration function
speed = 0
# Move forwards...
# Note that one motor must spin in the opposite direction to the other
# because it's on the opposite side of the robot
print("First we're accelerating forwards over 5 seconds...")
while speed <100:
piz_moto.Motor1(speed)
piz_moto.Motor2(speed * -1)
speed = speed + 20
time.sleep(1)
# wait 5 seconds
time.sleep(5)
# Turn left...
# Here we make one wheel turn one way as if the robot was moving forwards and
# make the other wheel turn the opposite way as if the robot was moving backwards.
# Make the left wheel run backwards and the right wheel run forwards should
# make the robot spin to the left (or anti-clockwise)
# But don't forget that the motors are on opposite sides...
print("Now we're turning left...")
piz_moto.Motor1(100)
piz_moto.Motor2(100)
# wait 1 seconds
time.sleep(1)
# Move backwards...
# Note that one motor must spin in the opposite direction to the other
# because it's on the opposite side of the robot
print("Now we're moving backwards...")
piz_moto.Motor1(-100)
piz_moto.Motor2(100)
# wait 5 seconds
time.sleep(5)
# This is the really important bit - we need to stop the motors when finished...
piz_moto.Motor1(0)
piz_moto.Motor2(0)
# Important delay - for some reason if this delay isn't here
# the motors don't stop.
# I suspect the program needs a cleaner exit
time.sleep(1)