讓 Raspberry Pi 不接螢幕也能用 Pygame 讀取搖桿的值

Pygame 是個 Python 套件,除了可以用來做遊戲以外,還可以用來讀取搖桿的值。但是在樹莓派上沒接螢幕卻無法使用這個套件,這篇文章會說明怎麼解決。

TL; DR

先講解法。

/boot/config.txt 加上(原本就有這行了,取消註解就行):

hdmi_force_hotplug=1

Python 程式碼加上:

pygame.init()
pygame.display.set_mode((1, 1))

以下慢慢說明。

Pygame

Pygame 是個可以用來寫遊戲的套件,其中有個方法可以讀取手把的值,例如一開始這樣取得手把:

pygame.init()
joystick = pygame.joystick.Joystick(0)
joystick.init()

接著可以取得不同軸或按鈕的值,例如我這支手把的兩顆蘑菇頭的上下可以這樣拿:

L = joystick.get_axis(1)
R = joystick.get_axis(4)

如果我要一直監聽,可以用個迴圈去包:

while True:
    L = joystick.get_axis(1)
    R = joystick.get_axis(4)
    sleep(0.1)

Raspberry Pi

Raspberry Pi 這是一種可以輕巧、可以跑 Linux(就可以跑 Python)、只要行動電源就可以運作的迷你電腦,搭配 Pygame 用來做無人遙控車相當適合。在接螢幕測試的時候都沒問題,不過一旦拔掉螢幕執行程式就會出現:

Traceback (most recent call last):
  File "controller.py", line 34, in listen
    for event in joystick.get_axis():
pygame.error: video system not initialized

查了幾篇文章發現,Pygame 在套件初始化的時候會檢查視訊輸出,如果找不到螢幕就會噴錯。所以這邊先修改 Raspberry Pi 的啟動參數(/boot/config.txt),讓樹莓派以為有接螢幕,強制從 HDMI 輸出。

Setting hdmi_force_hotplug to 1 pretends that the HDMI hotplug signal is asserted, so it appears that a HDMI display is attached. In other words, HDMI output mode will be used, even if no HDMI monitor is detected.

同時,為了避免 Pygame 找不到螢幕大小,我們也把螢幕初始化為 1×1 的大小:

pygame.init()
pygame.display.set_mode((1, 1))

這樣就可以在沒有螢幕(Headless)的情況下取得搖桿的數值了。

參考資料