使用樹莓派控制步進電機是常見的機器人專案應用。本文說明如何使用 Adafruit Stepper Motor HAT 和 RasPiRobot Board 兩種方式控制雙極步進電機,並提供 Python 程式碼範例與電路連線圖。此外,更進一步示範如何結合馬達控制與鍵盤輸入,打造簡易遙控車,並探討 RRB4 函式庫的應用,讓讀者快速上手樹莓派機器人開發。對於 I2C 匯流排的設定與潛在衝突也提供說明,避免讀者遭遇常見問題。

使用Stepper Motor HAT控制雙極步進電機

問題描述

您想要使用單一介面板控制多個雙極步進電機。

解決方案

使用Adafruit Stepper Motor HAT。這個板子可以控制兩個雙極步進電機。圖11-14顯示了板子與一個雙極步進電機的連線,電機的一個線圈連線到M1端子,另一個線圈連線到M2端子。電機的電源透過右側的螺絲端子單獨供應。

I2C匯流排

如果您按照Recipe 9.20的方法製作自己的HAT並啟用了I2C匯流排0,如描述所述,您需要在 /boot/config.txt 中刪除或註解掉以下行(在行首新增 # ):

dtparam=i2c_vc=on

然後重新啟動您的Raspberry Pi。

討論

當您執行Adafruit教程中提供的程式時,電機開始轉動,程式迴圈執行四種不同的步進模式。

參考資料

關於HAT標準和如何製作自己的HAT的討論,請參閱Recipe 9.20。 關於使用這個HAT及其配套函式庫的更多資訊,請參閱raspberry-pi。 使用L293D控制步進電機,請參閱Recipe 11.7;使用RasPiRobot Board,請參閱Recipe 11.9。

使用RasPiRobot Board控制雙極步進電機

注意

請務必檢視此配方的附件影片。

問題描述

您想要使用玄貓控制雙極步進電機。

內容解密:

import RPi.GPIO as GPIO
import time

# 設定GPIO模式
GPIO.setmode(GPIO.BCM)

# 定義步進電機的引腳
M1 = 17
M2 = 23

# 設定引腳為輸出模式
GPIO.setup(M1, GPIO.OUT)
GPIO.setup(M2, GPIO.OUT)

# 定義步進模式
def step(mode):
    if mode == 0:
        GPIO.output(M1, GPIO.HIGH)
        GPIO.output(M2, GPIO.LOW)
    elif mode == 1:
        GPIO.output(M1, GPIO.LOW)
        GPIO.output(M2, GPIO.HIGH)
    elif mode == 2:
        GPIO.output(M1, GPIO.HIGH)
        GPIO.output(M2, GPIO.HIGH)
    elif mode == 3:
        GPIO.output(M1, GPIO.LOW)
        GPIO.output(M2, GPIO.LOW)

# 執行步進模式
for i in range(4):
    step(i)
    time.sleep(1)

# 清除GPIO設定
GPIO.cleanup()

圖表翻譯:

  flowchart TD
    A[開始] --> B[設定GPIO模式]
    B --> C[定義步進電機的引腳]
    C --> D[設定引腳為輸出模式]
    D --> E[定義步進模式]
    E --> F[執行步進模式]
    F --> G[清除GPIO設定]
    G --> H[結束]

此圖表顯示了控制雙極步進電機的流程,從設定GPIO模式開始,到執行步進模式,最後清除GPIO設定。

解決方案:使用RasPiRobot板版本4

為了驅動12V的雙極步進電機,我們可以使用RasPiRobot板版本4。這個板子可以直接從螺絲端子取得電源,並將其調節為5V以驅動樹莓派。因此,在這種情況下,12V的電源將同時供應12V的步進電機和樹莓派。

警告 如果您使用的是RasPiRobot板的早期版本(版本1或2),請勿在同時透過USB連線供應樹莓派電源,因為您已經透過RasPiRobot板供應電源。然而,在版本3或4的板子中,這不是一個問題。

將步進電機和電源連線到RasPiRobot板,如圖11-15所示。Adafruit 12V步進電機的線色,從最下面的線開始,分別是:黃色和紅色(線圈1),灰色和綠色(線圈2)。

在執行程式之前,您需要使用以下命令安裝RasPiRobot板v4的函式庫:

$ cd rrb4/python
$ sudo python3 setup.py install

然後,開啟編輯器並貼入以下程式碼(ch_11_stepper_rrb.py)。這個程式使用命令列,因此您可以從SSH執行它:

from rrb4 import *
import time

rr = RRB4(12.0, 12.0)  # 電池,電機
try:
    while True:
        delay = input("延遲時間(毫秒)?")
        steps = input("向前移動多少步?")
        rr.step_forward(int(delay) / 1000.0, int(steps))
        steps = input("向後移動多少步?")
        rr.step_reverse(int(delay) / 1000.0, int(steps))
finally:
    GPIO.cleanup()

如同本文中的所有程式範例,您也可以下載這個程式碼(見配方3.22)。

討論 您會發現有一個最小的“延遲時間”值,如果低於這個值,電機將會顫抖而不是轉動。

參考 … (其他內容)

建立簡單的機器人遙控車

問題描述

您想要使用Raspberry Pi作為控制器,建立一個簡單的機器人遙控車。

解決方案

使用RasPiRobot Board v4或其他馬達控制器板作為Raspberry Pi的介面板,控制兩個馬達和機器人底盤套件。要完成這個食譜,您需要以下元件:

  • RasPiRobot板v4(見「模組」)
  • 底盤和齒輪馬達套件(見「雜項」)
  • 四節AA電池盒(見「雜項」)

首先,按照圖11-16的連線指示組裝底盤。

圖11-16. 連線遙控車

電池包將為RasPiRobot板供電,然後RasPiRobot板將為Raspberry Pi供應5V電源。因此,只需要一個電源。

完成的遙控車應該看起來像圖11-17,前面還有一個測距儀。

圖11-17. 完成的機器人

要控制機器人,您將使用一個控制程式,允許您使用連線到Raspberry Pi的筆記型電腦或其他電腦上的鍵盤來控制遙控車。如果您尚未這樣做,請使用配方2.5和配方2.7分別設定您的Raspberry Pi使用WiFi和SSH。

開啟編輯器並貼入以下程式碼(ch_11_rover.py):

from rrb4 import *
import sys
import tty
import termios

rr = RRB4(6.0, 6.0)  # 電池,馬達

UP = 0
DOWN = 1
RIGHT = 2
LEFT = 3

內容解密:

上述程式碼定義了一個簡單的機器人遙控車控制程式。它首先匯入必要的模組,包括rrb4systtytermios。然後,它建立了一個RRB4物件,代表RasPiRobot板,指定電池和馬達的引數。最後,它定義了四個常數,代表不同的方向:向上、向下、向右和向左。

圖表翻譯:

  flowchart TD
    A[開始] --> B[初始化RasPiRobot板]
    B --> C[定義方向常數]
    C --> D[等待使用者輸入]
    D --> E[控制機器人]
    E --> F[結束]

上述流程圖展示了控制程式的邏輯流程。它首先初始化RasPiRobot板,然後定義方向常數。接下來,它等待使用者輸入,並根據使用者的輸入控制機器人。最後,它結束程式。

使用鍵盤控制機器人移動

要控制機器人的移動,您可以使用鍵盤的箭頭鍵。以下是基本的控制指令:

  • 向上箭頭鍵:向前移動
  • 向下箭頭鍵:向後移動
  • 向左箭頭鍵:向左轉
  • 向右箭頭鍵:向右轉

程式碼實作

import sys
import termios
import tty

print("使用箭頭鍵控制機器人移動")
print("按Ctrl-C離開程式")

def 讀取單個字元():
    # 取得標準輸入的檔案描述符
    fd = sys.stdin.fileno()
    
    # 儲存當前的終端設定
    old_settings = termios.tcgetattr(fd)
    try:
        # 設定終端為原始模式
        tty.setraw(sys.stdin.fileno())
        
        # 讀取一個字元
        ch = sys.stdin.read(1)
    finally:
        # 還原原始的終端設定
        termios.tcsetattr(fd, termios.TCSADRAIN, old_settings)
    
    # 如果按下Ctrl-C,則引發KeyboardInterrupt異常
    if ch == '\x03':
        raise KeyboardInterrupt
    return ch

def 讀取鍵盤輸入(getchar_fn=None):
    # 如果沒有提供getchar函式,則使用預設的讀取單個字元函式
    getchar = getchar_fn or 讀取單個字元
    
    # 讀取第一個字元
    c1 = getchar()
    
    # 如果第一個字元不是ESC(\x1b),則直接傳回
    if ord(c1)!= 0x1b:
        return c1
    
    # 如果是ESC,則繼續讀取第二個字元
    c2 = getchar()

內容解密:

上述程式碼提供了基本的鍵盤控制功能,允許使用者使用箭頭鍵控制機器人的移動。其中,讀取單個字元函式用於讀取鍵盤輸入的單個字元,而讀取鍵盤輸入函式則根據讀取到的字元進行相應的動作。

  flowchart TD
    A[開始] --> B[讀取鍵盤輸入]
    B --> C{是否為ESC}
    C -->|是| D[讀取第二個字元]
    C -->|否| E[傳回字元]
    D --> F[執行相應動作]
    E --> F

圖表翻譯:

此流程圖描述了程式碼的邏輯流程。首先,程式開始執行,然後讀取鍵盤輸入。若讀取到的字元是ESC(\x1b),則繼續讀取第二個字元;否則,直接傳回讀取到的字元。根據讀取到的字元,程式執行相應的動作。

控制機器人運動的程式碼

import RPi.GPIO as GPIO
import time

# 初始化GPIO模式
GPIO.setmode(GPIO.BCM)

# 定義引腳
LEFT_MOTOR_FORWARD = 17
LEFT_MOTOR_BACKWARD = 23
RIGHT_MOTOR_FORWARD = 24
RIGHT_MOTOR_BACKWARD = 25

# 設定引腳為輸出模式
GPIO.setup(LEFT_MOTOR_FORWARD, GPIO.OUT)
GPIO.setup(LEFT_MOTOR_BACKWARD, GPIO.OUT)
GPIO.setup(RIGHT_MOTOR_FORWARD, GPIO.OUT)
GPIO.setup(RIGHT_MOTOR_BACKWARD, GPIO.OUT)

# 定義機器人運動函式
def forward():
    GPIO.output(LEFT_MOTOR_FORWARD, GPIO.HIGH)
    GPIO.output(RIGHT_MOTOR_FORWARD, GPIO.HIGH)
    GPIO.output(LEFT_MOTOR_BACKWARD, GPIO.LOW)
    GPIO.output(RIGHT_MOTOR_BACKWARD, GPIO.LOW)

def backward():
    GPIO.output(LEFT_MOTOR_FORWARD, GPIO.LOW)
    GPIO.output(RIGHT_MOTOR_FORWARD, GPIO.LOW)
    GPIO.output(LEFT_MOTOR_BACKWARD, GPIO.HIGH)
    GPIO.output(RIGHT_MOTOR_BACKWARD, GPIO.HIGH)

def right():
    GPIO.output(LEFT_MOTOR_FORWARD, GPIO.HIGH)
    GPIO.output(RIGHT_MOTOR_BACKWARD, GPIO.HIGH)
    GPIO.output(LEFT_MOTOR_BACKWARD, GPIO.LOW)
    GPIO.output(RIGHT_MOTOR_FORWARD, GPIO.LOW)

def left():
    GPIO.output(LEFT_MOTOR_BACKWARD, GPIO.HIGH)
    GPIO.output(RIGHT_MOTOR_FORWARD, GPIO.HIGH)
    GPIO.output(LEFT_MOTOR_FORWARD, GPIO.LOW)
    GPIO.output(RIGHT_MOTOR_BACKWARD, GPIO.LOW)

# 定義按鍵對應的機器人運動
UP = 0
DOWN = 1
RIGHT = 2
LEFT = 3

# 主迴圈
try:
    while True:
        keyp = readkey()
        
        if keyp == UP:
            forward()
            print('向前')
        elif keyp == DOWN:
            backward()
            print('向後')
        elif keyp == RIGHT:
            right()
            print('向右')
        elif keyp == LEFT:
            left()
            print('向左')

內容解密:

上述程式碼使用Python語言控制機器人的運動。首先,初始化GPIO模式並定義引腳。然後,設定引腳為輸出模式。接下來,定義機器人運動函式,包括向前、向後、向右和向左。最後,在主迴圈中,根據按鍵的輸入,呼叫對應的機器人運動函式。

圖表翻譯:

  flowchart TD
    A[開始] --> B[讀取按鍵]
    B --> C{按鍵判斷}
    C -->|UP| D[向前]
    C -->|DOWN| E[向後]
    C -->|RIGHT| F[向右]
    C -->|LEFT| G[向左]
    D --> H[執行向前動作]
    E --> I[執行向後動作]
    F --> J[執行向右動作]
    G --> K[執行向左動作]

圖表翻譯:

上述Mermaid圖表展示了程式碼的邏輯流程。首先,開始讀取按鍵。然後,根據按鍵的輸入,判斷要執行哪個動作。最後,根據判斷結果,執行對應的動作。

使用 Raspberry Pi 和 RRB4 函式庫建立遙控機器人

介紹

在本文中,我們將探討如何使用 Raspberry Pi 和 RRB4 函式庫建立一個簡單的遙控機器人。RRB4 函式庫是一個強大的工具,允許您輕鬆控制 Raspberry Pi 的 GPIO 引腳,並建立複雜的機器人專案。

程式碼

import RRB4

# 建立 RRB4 例項
rr = RRB4.RRB4(battery_voltage=6, motor_voltage=6)

while True:
    try:
        # 讀取按鍵輸入
        keyp = input("按鍵:")

        # 處理按鍵輸入
        if keyp == "w":
            rr.forward(1)
            print("前進")
        elif keyp == "s":
            rr.reverse(1)
            print("後退")
        elif keyp == "a":
            rr.left(1)
            print("左轉")
        elif keyp == "d":
            rr.right(1)
            print("右轉")
        elif ord(keyp) == 3:
            break
    except KeyboardInterrupt:
        # 清理 GPIO 引腳
        GPIO.cleanup()

內容解密:

上述程式碼使用 RRB4 函式庫建立了一個簡單的遙控機器人。程式碼首先匯入 RRB4 函式庫,然後建立一個 RRB4 例項,指定電池電壓和馬達電壓。接下來,程式碼進入一個無限迴圈,讀取按鍵輸入並根據按鍵輸入控制機器人的運動。

Mermaid 圖表

  flowchart TD
    A[開始] --> B[讀取按鍵輸入]
    B --> C[處理按鍵輸入]
    C --> D[控制機器人運動]
    D --> E[重複迴圈]

圖表翻譯:

上述 Mermaid 圖表展示了程式碼的流程。程式碼首先開始,然後讀取按鍵輸入,接下來處理按鍵輸入並控制機器人的運動,最後重複迴圈。

討論

您可以透過新增 webcam 和設定網路直播來使機器人更加有趣。RRB4 函式庫還支援 HC-SR04 距離感測器,可以用於檢測障礙物。

參考

您可以在 GitHub 上找到更多關於 RasPiRobot 板和 RRB4 函式庫的資訊。

從使用者經驗視角來看,建構一個可操控的機器人,涉及到硬體組裝、軟體程式設計和控制介面設計等多個環節。本文介紹了使用Stepper Motor HAT和RasPiRobot Board兩種方案控制雙極步進電機,並進一步延伸至建構遙控機器人的應用。分析比較兩種方案,Stepper Motor HAT更適用於需要精確控制多個電機的場景,而RasPiRobot Board則更簡潔易用,適合入門級的機器人專案。兩種方案的程式碼範例都清晰易懂,降低了開發者的學習曲線,但對於初學者而言,更詳細的電路連線圖和程式碼註解將更有助於理解。技術限制方面,兩種方案都依賴於特定的硬體平臺,限制了其通用性。此外,程式碼範例中對於錯誤處理和異常情況的考慮不夠完善,例如在鍵盤控制程式碼中缺少對於非預期輸入的處理。展望未來,整合更多感測器,例如超音波感測器、陀螺儀等,並結合機器學習演算法,可以賦予機器人更智慧化的自主導航和避障能力。對於進階使用者,可以考慮使用ROS(Robot Operating System)等機器人作業系統,構建更複雜的機器人應用。玄貓認為,根據Raspberry Pi的機器人開發平臺,因其低成本、易上手和豐富的社群資源,將持續吸引更多創客和開發者加入,推動機器人技術的普及和發展。建議開發者在選擇方案時,充分考慮專案需求和自身技術水平,並積極探索新的技術和工具,不斷提升機器人的功能和效能。