MBC 掌控者 PS2/PS4 × Arduino

三個步驟用 Arduino 讀掌控者遙控接收器

寫 Arduino 程式照這個順序:先接好線、貼上小幫手,再在 setup() 開始通訊、等接收器準備好,最後在 loop() 用 mbcRead() 讀按鍵和搖桿。PS2 和 PS4 接收器的寫法完全一樣。左邊一步一步做,右邊的程式會跟著長出來;點模擬手把上的按鍵、拖動搖桿,就能看到序列埠監控視窗會印出什麼。

1

接線,貼上小幫手

Arduino 用 I2C(4 條線)跟感應器講話,不用安裝函式庫。程式最上面寫 2 行、最下面貼一段「小幫手」,之後就能用 mbcRead() 讀值、mbcWrite() 送命令。

你用哪一塊板子?(只差 SDA/SCL 接哪兩腳,程式完全一樣)

  1. 接線前先拔掉 USB 線。要用 通用 I2C 版(SPIKE 版、EV3 版的韌體不同,不能接 Arduino)。
  2. 感應器 VCC → 5V、GND → GND
  3. 感應器 SDA → A4、SCL → A5
  4. 接收器上印的是 TX、RX:通用 I2C 版的 RX 就是 SDA、TX 就是 SCL。接收器裡有電壓轉換,5 V 和 3.3 V 的板子都能直接接。
  5. PS2:手把開機就會連上;按手把中間的 ANALOG 鍵讓燈亮(類比模式),搖桿才有數字。PS4/PS5:第一次要配對:接收器開機(或按 Reset)後 30 秒內,PS4 手把長按 SHARE+PS、PS5 手把長按 建立+PS,燈條快閃就好;之後按 PS 鍵就會自動連上。
  6. 打開 Arduino IDE:檔案 → 新增,把原本的內容刪掉。
  7. 最上面寫第 1、2 行;最下面貼「小幫手」(右邊程式標 ① 的地方,按「複製程式」會一起拿到)。
2

開始通訊,等感應器準備好

setup() 是開機時只跑一次的地方:打開序列埠、開始 I2C、等感應器說「準備好了」。ADDR 是感應器的「門牌號碼」(I2C 位址),之後每次讀值都寫它。

感應器的 I2C 位址:

找不到感應器的時候:

3

使用功能

讀值寫「mbcRead(ADDR, 編號)」,送命令寫「mbcWrite(ADDR, 命令)」。點一個功能,程式和序列埠監控視窗會換成它的範例。

模擬手把:點按鍵、拖動搖桿,看右邊序列埠監控視窗怎麼變

模擬畫面是示意:點一下按鍵=按住,再點一下放開;拖動搖桿的圓點改變位置(放開滑鼠會停在那裡,按「全部放開」回到中間)。搖桿 −100 ~ +100,0 = 中間,往右、往上是正數。PS4 手把的電量固定示意為 80。PS 鍵只有 PS4 接收器有;L3、R3(把搖桿往下壓)這裡按不到。手把沒連線:接收器還在,0x06 = 0、按鍵和搖桿全部是 0;拔掉接收器:Arduino 讀到的每個值都是 -32768。

每個功能的範例

26 個功能(讀值、命令、每款 MBC 感應器都有的共用編號),每個都有一段範例。標「PS4 才有」的只有 PS4 接收器有作用,PS2 接收器收到會忽略或一直是 0。按「試試看」會切到第 3 步,右邊的程式和序列埠監控視窗會換成這個範例。

完整範例

按「複製」拿到的是完整程式(最下面已經接好小幫手),貼進 Arduino IDE 就能上傳。

坦克遙控車(L298N 馬達驅動板)

        

!左搖桿上下管左輪、右搖桿上下管右輪。手把斷線或讀不到接收器就立刻停車。第一次先把車子架高(輪子懸空)試:兩支搖桿一起往上推,哪個輪子轉反了就把那一顆的 REVERSE 改成 true;太快就把 MAX_SPEED 調小。L298N 的 GND 要跟 Arduino 的 GND 接在一起。PS2、PS4 接收器都能用。

按了哪一顆鍵?

        

!按下、放開任何一顆鍵,序列埠監控視窗都會說是哪一顆;可以同時按好幾顆。十六鍵用 mbcReadMany() 讀,因為只按 ■ 時值剛好是 -32768,用 mbcRead() 會分不出是不是讀不到。

震動和燈條(PS4/PS5 手把才有)

        

!按住 ✕ 手把就震動;推左搖桿改燈條顏色(左右 → 紅、上下 → 綠)。命令 E5 每送一次震 200 ms,所以按住時每一圈都再送一次;E6 要剛好給紅、綠、藍 3 個數字。接 PS2 接收器時程式照樣跑,只是手把不會震、也沒有燈條。

使用注意

  1. 拔掉接收器和手把沒開是兩回事。讀不到接收器時 mbcRead() 回傳 -32768(MBC_NONE)、mbcReadMany() 回傳 false;接收器有接好、但手把沒開(沒電、沒配對)時,0x06 已連線 = 0,按鍵、搖桿全部是 0。遙控車兩種情形都要停車(完整範例的坦克車就是這樣做)。在右邊勾「手把沒連線」「拔掉接收器」比較看看。
  2. 只按 ■ 時,0x01 十六鍵剛好是 -32768。■ 在最高位(bit15),16 個 bit 只有它是 1 時,數字跟「讀不到」的 MBC_NONE 一樣。要分辨就用 mbcReadMany() 讀(看它回 true 還是 false),或改讀 0x03 形狀鍵(■ = 8)。
  3. 兩款接收器的編號一樣,位址都是 0x42。只差在:0x07 電量、0x0A 系統鍵 PS2 一直是 0;0x0B 手把類型 3、4 只有 PS4 接收器會出現;E5 震動、E6 燈條只對 PS4/PS5 手把有作用,PS2 接收器收到會忽略(程式不會出錯)。同一條 I2C 線只能接其中一個;用 0xF0 的高 byte 分辨(1 = PS2、2 = PS4)。
  4. 搖桿 −100 ~ +100,0 = 中間。站在車後面往前看:往左、往下是負數,往右、往上是正數。中間附近輕輕晃會停在 0(死區),放開搖桿時車子才不會自己慢慢跑。連號的 0x10~0x13 用 mbcReadMany() 一次讀,保證是同一瞬間的資料。
  5. 小幫手裡的 delay(2) 不要刪。PS4/PS5 接收器是 ESP32 做的,寫完編號要等 2 ms 它才準備好資料;兩款位址一樣、程式分不出來,所以一律等。接收器開機要 1 秒多,第 2 步最多等 5 秒。序列埠監控視窗的速度要選 115200,不然會看到亂碼。