維基少年:樹莓派/樹莓派電機控制
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)