使用Raspberry Pi Pico來自行定義USB遊戲控制器|台灣STEAM教學團隊 oursteamtw
icon最新消息
2021 / 04 / 22

使用Raspberry Pi Pico來自行定義USB遊戲控制器

遊戲控制器(如:鍵盤)是非常私人的東西,即使適合某個人,卻可能不適合另一個人。那麼,為什麼我們都應該使用幾乎完全相同的現成控制器?在最新一期的《 HackSpace》雜誌中,我們介紹瞭如何使用Raspberry Pi Pico創建適合您的控制器。

自製復古遊戲操縱桿盒
像是一款1989年的遊戲

我們將使用CircuitPython,因為它對USB接口具有出色的支持。我們與之互動的USB設備稱為人機接口設備(HID),並且對於常見的HID有標準協議,包括鍵盤和滑鼠。例如,這就是為什麼您可以將幾乎所有USB鍵盤插入幾乎任何電腦,並且它可以正常工作而無需安裝驅動程序的原因。

我們將使用鍵盤型式,因為它最適合該作者喜歡玩的各種遊戲,但是您可以使用完全相同的技術來模擬滑鼠或遊戲手把。

不過,在開始討論之前,讓我們看一下按鈕以及如何將它們連接起來。

我們將使用八個按鈕:四個用於指示方向,另外四個用作其他"操作"按鈕。我們將這些連接在I / O引腳和接地之間。您可以使用任何您喜歡的I / O引腳。我們將在兩個不同的設置中使用略有不同的設置,因為它們對於硬體的實際布置很合理。讓我們看一下我們正在使用的硬體。請記住,這只是我們要使用的硬體。整個想法是創建適合您的設置,因此無需使用相同的設置。考慮一下您想如何與遊戲進行互動,並查看可用的輸入設備並創建所需的內容。

連接器應僅按在按鈕和操縱桿上
連接器應在按鈕和操縱桿上


我們要創建的第一個設置是遊戲機。這位作者真的很喜歡他家中的遊戲機。但由於空間有限,這在不久的將來可能不能實現。第一個設置是嘗試重新創建遊戲機的控制設置,但是將其用於在筆記型電腦而不是大尺寸的遊戲機檯上玩遊戲。

遊戲機的控制是非常標準的,您可以從各種來源獲得它們。我們使用了Pimoroni的遊戲零件,其中包括一個操縱桿和十個按鈕(我們只使用了其中的四個)。關於您選擇的操縱桿,重要的是它是基於按鈕的操縱桿,而不是模擬操縱桿(有時稱為雙軸操縱桿),因為後者無法與鍵盤界面一起使用。如果要使用模擬遊戲桿,則需要切換編碼以將滑鼠或遊戲板用作輸入設備。
您可以將排針直接焊接到Pico上
您可以將排針直接焊接到Pico上


除了電子設備外,您還需要一些安裝方法,我們是使用一個木製盒。這些可從一系列線上商店或實體店購買。您可以使用強度足以容納零件的任何物品。

我們使用的第二個設置是在麵包板兼容的觸覺按鈕和原型板上的按鈕的系統,該系統更加簡單、更小、更便宜,而且組裝起來更快。該原型板可將所有內容組合在一起,因此除非您另有考慮,否則無需添加其他內容。您可以透過選擇不同大小的按鈕,更改佈局或圍繞此按鈕構建更大的機箱來對其進行個性化設置。

插入硬幣以繼續
首先讓我們看一下遊戲機的設置。操縱桿有五個針腳,一個是共同點,另一個是上、下、左和右。向上推操縱桿時,一個開關閉合,將接地線連接到向上針腳。在我們的操縱桿上,最外面的針腳是接地的,但是值得用萬用表在操縱桿上檢查哪個針腳是哪個。選擇連續性模式,如果向上推操縱桿,則應該在向上插腳和接地之間找到連續的連接。進行一點實驗即可確定哪個引腳是哪個引腳。

為了讀取引腳,我們只需要將操縱桿的定向輸出連接到Pico上的I / O引腳即可。當未按下按鈕時,我們可以使用Pico的內部上拉電阻之一將引腳拉高。然後,當按下按鈕時,它將接地並讀取低電平。操縱桿應隨附有一條電纜,該電纜可插到操縱桿上。它應該有五個輸出,並且可以方便地插入到Pico的I / O輸出中,並在一端接地。

您可以將排針直接焊接到Pico上
您可以將排針直接焊接到Pico上

同樣地這些按鈕只需要連接在接地和I / O引腳之間即可。這些電纜帶有推入按鈕並插入相鄰引腳的電纜。由於Pico具有八個可用的接地,每個按鈕都有足夠的接地,因此您不必費心將電纜連接在一起。

一旦將所有電纜焊接在一起,僅是構建機箱的一種情況。為此,您需要五個大孔(一個用於操縱桿,四個用於按鈕)。我們沒有合適尺寸的鑽頭,並且考慮到這些盒子上的木材較柔軟,無論如何,大的鑽頭可能會將木頭鑽開。因此我們鑽了一個20毫米的孔,然後使用旋轉工具將孔擴大到合適的尺寸。使用鑽頭和工具都必須別太用力,以免將所有東西都弄碎了。然後用四個小孔將螺栓固定在操縱桿上(我們使用M5螺栓)。

通過一小部分電線和跳線的組合,您可以在原型板上創建所需的任何佈線方式
透過一小部分電線和跳線的組合,您可以在原型板上創建所需的任何佈線

剩下的唯一東西是一個12毫米的孔,用於將微型USB電纜傳遞到Pico。如果您沒有12毫米的鑽頭,兩個重疊的小孔可能會有用。只需將按鈕就位,就可以準備就緒。

較小的方法
我們較小的選擇是在Pico的背面使用protoboard。由於我們不想阻塞BOOTSEL按鈕,因此我們僅將其焊接在Pico的一部分上。但是,在完全焊接之前,我們已將按鈕焊接到位。

觸覺開關通常具有四個連接。實際上他們有兩個連接,但是每個連接都有兩個適合原型板的選項卡。這意味著您必須正確地調整它們的方向。萬用表的連續性功能將確認連接了哪些引腳以及切換了哪些引腳。

Protoboard是一種PCB,其中包含很多洞和其他東西。您將零件焊接到孔中後,必須在它們之間建立連結。

在擔心接線之前,我們將按鈕放在原型板上的所需位置。首先,我們希望將每個開關的一側接地。為了最大程度地減少佈線,我們分兩組進行了此操作。我們將每個方向按鈕的一側連接在一起,然後將它們接地。然後,我們對所有操作按鈕進行了相同的操作。

有兩種方法可以在Protoboard上進行連接。一種是使用跳線。如果這些點相距兩個以上的孔,效果會很好。對於彼此相鄰或非常靠近的孔,您可以橋接它們。在某些原型板上(沒有阻焊層),您可能只需將一團焊錫與烙鐵一起拖出,以便將其連接到兩個孔中。在帶有阻焊膜的原型板上,這種方法效果不佳,因此您需要在兩點之間的表面安裝位置添加一小束電線並將其焊接。在焊接時將電線固定在適當的位置,會比較容易。

對於更長的連接,您需要使用跳線。有時您可以通過原型板戳戳它,並使用支腿將其聯接。其他時候,您必須將其表面貼裝。這聽起來有點複雜,但是一旦將焊料放到鐵上,一切都非常簡單。

編程
我們已經準備好硬體,現在讓我們對其進行編碼。
您首先需要將CircuitPython下載到您的Pico上。您可以從circuitpython.org下載最新版本。將Pico插入USB端口時,按BOOTSEL按鈕,然後將下載的UF2文件拖放到應該出現的RP2 USB驅動器上。

我們將使用Mu編寫Pico。如果您以前沒有使用過CircuitPython,那麼您值得快速瀏覽一下"入門指南"。

運作我們的遊戲控制器的編碼如下:


import board
import digitalio
import gamepad
import time
import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

kbd = Keyboard(usb_hid.devices)

keycodes = [Keycode.UP_ARROW, Keycode.DOWN_ARROW, Keycode.LEFT_ARROW, Keycode.RIGHT_ARROW,                   Keycode.X, Keycode.Z, Keycode.SPACE, Keycode.ENTER]

pad = gamepad.GamePad(
    digitalio.DigitalInOut(board.GP12),
    digitalio.DigitalInOut(board.GP14),
    digitalio.DigitalInOut(board.GP9),
    digitalio.DigitalInOut(board.GP15),
    digitalio.DigitalInOut(board.GP16),
    digitalio.DigitalInOut(board.GP17),
    digitalio.DigitalInOut(board.GP18),
    digitalio.DigitalInOut(board.GP20),
)
last_pressed = 0
while True:
    this_pressed = pad.get_pressed()
    if (this_pressed != last_pressed):
        for i in range(8):
            if (this_pressed & 1<
                kbd.press(keycodes[i])
            if (last_pressed & 1<
                kbd.release(keycodes[i])
        last_pressed = this_pressed
    time.sleep(0.01)


這使用HID鍵盤對象(稱為kbd)傳送不同按鍵代碼的按鍵按下和釋放事件,具體取決於按下或釋放了哪些按鈕。我們使用了遊戲手把模組,該模組可追蹤多達八個按鈕。初始化時,它將自動添加上拉電阻並將I / O引腳設置為輸入。然後,它將追蹤按下了哪些按鈕。當您調用get_pressed()時,它將回傳一個位元組的數據,其中每個數字對應一個I / O引腳。因此,以下數字(二進制)表示已按下第一個和第三個按鈕:00000101。這有點令人困惑,因為這與初始化GamePad對象時傳遞I / O的順序相反。



while循環可能看起來有點不尋常,因為它不是特別常見使用這種在Python代碼二進制比較,但在本質上,它只是在同一時間尋找一個bit:它現在按壓,但沒有上一次已運行的循環(在這種情況下,這是一個新的按鈕按下,我們應該將其傳送到電腦),或者沒有按下此循環,而是上一個循環(在這種情況下,它是新釋放的,因此我們可以將其稱為釋放方法)。


<< operator藉由一些bits的數字將數值移動往左。因此1<<2是100,而1<<3是1000。& operator是按位元運算的,因此它查找二進制數並依次對每個位元進行邏輯 AND。由於右手邊的&除一位元以外全為零(在不同的位置,取決於i的值),因此結果將取決於在位置i處this_pressed或last_pressed的值是1還是0。如果if條件為數字,則該數字為0以外的其他情況為真。因此,如果this_pressed的二進制形式的位置2處為1 ,則(this_pressed&1 <<2)的計算結果為true。在我們的情況下,這意味著將操縱桿向左推。

您可以從這個連結 hsmag.cc/USBKeyboard獲取此編碼。在初始化GamePad時,您需要將GPIO值更新為正確的設置。
我們已經研究了兩種構建遊戲手柄的方法,但是如何設計遊戲手柄則取決於您。   
  • icon
  • icon
  • icon
  • icon
  • icon
  • icon電話:04-2337-1605
  • icon傳真:04-2256-9949
  • icon統編:13438259
  • iconE-mail:oursteamtw@gmail.com
  • iconLINE ID:@oursteam