Ausprobiert: Raspberry Pico mit USB-HID als Tastatur oder Maus benutzen

Mithilfe eines Raspberry Pico und dem Python-Modul für USB-HID kann man eigene Tastaturen, Gamecontroller und Mäuse bauen.

In Pocket speichern vorlesen Druckansicht 31 Kommentare lesen
Picoboard und StreamDeck
Lesezeit: 6 Min.
Von
  • Carsten Wartmann
Inhaltsverzeichnis

Der Raspberry Pico und andere Boards mit dem Prozessor RP2040 sind recht erschwinglich und leistungsfähig. Der Chip unterstützt auch USB-HID, also Human Interface Devices, das sind Tastaturen, Mäuse und Gamepads. Das bedeutet in diesem Fall allerdings nicht, dass ein Gamepad an den Raspberry Pico angeschlossen wird, sondern dass sich der Pico als Maus, Tastatur und Gamepad ausgibt. Der Computer kann dabei nicht unterscheiden, woher diese Eingabe kommt. Dies ermöglicht einige interessante Hacks und Anwendungen, vom Scherz, um einen Kollegen zum Wahnsinn zu treiben, über neuartige oder behindertengerechte Eingabegeräte bis hin zu funktionalen Simulator-Cockpits.

Aus dem Make-Testlabor

Die Make-Redaktion probiert viel mehr aus, als ins alle zwei Monate erscheinende Heft passt. Deshalb veröffentlichen wir auf unserer Webseite in loser Folge weitere Testberichte.

Aktuell ist die Benutzung des Pico Boards als HID nur mittels C/C++ oder CircuitPython (ein Fork von MicroPython von Adafruit) möglich. MicroPython selbst wird unseres Wissens nach noch nicht unterstützt. Zum Glück ist die Installation einer neuen Firmware per Drag&Drop auf das Board sehr einfach und schnell ausprobiert. Laden Sie die Firmware von CircuitPython.org (wir verwenden die Stable Version 6.2.x), stecken Sie den Pico bei gehaltener BOOT-Taste an den Rechner und kopieren Sie die Firmware auf das Picodrive (CIRCUITPY).

Im folgenden verwenden wir Thonny als IDE, aber natürlich funktioniert auch das von Adafruit präferierte Mu. Das Python-Modul, das wir für HID brauchen, kann man im Adafruit-GitHub herunterladen. Dieses Zip-File enthält Module für alle von Adafruit unterstützen Sensoren und Geräte. Daher suchen wir dann die für das aktuelle Projekt gewünschten heraus, hier also adafruit_hid, und kopieren diesen Ordner den lib-Ordner auf dem Picodrive. Möchte man auch die Beispiele aus einem Modul studieren, sollte man über die Seite PyPi gehen und dort nach dem Modul suchen. In Thonny lauert noch eine Falle oder Bug: Wenn man das Modul per Plugins-Menü oder Manage-Packages installieren will, wird dies nicht auf dem Board gespeichert oder man bekommt eine Fehlermeldung, weil der Code auf dem lokalen Python ausgeführt wird.

Folgender Code macht den Pico zu einer externen USB-Tastatur:

import usb_hid
from adafruit_hid.keyboard import Keyboard
from adafruit_hid.keycode import Keycode

import board
import digitalio
import time

kbd = Keyboard(usb_hid.devices)

button = digitalio.DigitalInOut(board.GP13)
button.switch_to_input(pull=digitalio.Pull.DOWN)

while True:
    if button.value:
        kbd.send(Keycode.A)
    time.sleep(0.2)

Bei Druck auf den Taster zwischen 3.3V und GPIO 13 wird der Keycode für "A" an den PC gesendet. Dies kann dann – wie im Aufmacherbild oben zu sehen – bis zu einem Stream Deck ausgebaut werden, das eine Screencast-Software wie OBS Studio steuert. Um in diesem Fall aber nicht mit der Anwendung, die man per OBS Studio eigentlich präsentieren will, in die Quere zu kommen, sollte man dann aber Tastendrücke definieren, die keine Bedeutung für andere Programme haben; etwa Strg-Alt-Shift-F1 (kbd.send(Keycode.CONTROL, Keycode.ALT, Keycode.SHIFT, Keycode.F1)) oder ähnliches. Durch die Verwendung von kbd.press(KEYCODE), kbd.release(KEYCODE) und kbd.release_all() kann man noch komplexere Tastenmuster erzeugen um z.B. ein Spiel zu steuern, bei dem mehrere Tasten gleichzeitig gedrückt und dabei bestimmte Zeiten gehalten werden sollen.

Auch der Mauszeiger lässt sich steuern, was gut bei Hardware verwendbar ist, auf denen man keine Anwendungen installieren darf oder kann. Ein ganz simples Maus-Programm sieht wie folgt aus:

import usb_hid
from adafruit_hid.mouse import Mouse

import board
import digitalio
import time

m = Mouse(usb_hid.devices)

button = digitalio.DigitalInOut(board.GP13)
button.switch_to_input(pull=digitalio.Pull.DOWN)

while True:
    if button.value:
        m.move(-10, -10, 0)
    time.sleep(0.2) 

Wird der Taster betätigt, so verschiebt sich der Mauscursor etwas nach links oben. Wahrscheinlich kann man mit einem ähnlichen Programm, das zufallsgesteuert die Maus bewegt, jemanden zum Wahnsinn treiben. Hier sind auch Angriffsszenarien auf PCs möglich, vor allem, wenn auch die Tastatur mit Eingaben gefüttert wird, wie beim viel gescholtenen Digispark.

Bei der Recherche zu diesem Artikel habe ich gelernt, dass es sogenannte Mouse Wiggler gibt, die auf einem von der Firma überwachtem Computer eine Aktivität des Benutzers vorgaukeln. Ich warte noch mit dem Kauf, bis diese Geräte auch den Rest meiner Arbeit übernehmen können. Es gibt auch Dongles die am PC oder Mobiltelefon immer wieder einen Maus- oder Touch-Klick auslösen um in Spielen langweilige Routineaufgaben zu erledigen.

Für die Simulations-Fans jetzt noch ein Gamepad oder Joystick emulieren:

import usb_hid
from adafruit_hid.gamepad import Gamepad

import time
import board
import analogio

gp = Gamepad(usb_hid.devices)
potentiometer = analogio.AnalogIn(board.GP26)

def range_map(x, in_min, in_max, out_min, out_max):
    return (x - in_min) * (out_max - out_min) // (in_max - in_min) + out_min

while True:
    value = potentiometer.value
    print(value,range_map(value, 0, 65535, -127, 127))
    gp.move_joysticks(x=range_map(value, 0, 65535, -127, 127), y=0, z=0)
    time.sleep(.1)

Hier wird ein Potentiometer abgefragt, die Werte werden mittels range_map() auf den erlaubten Bereich von -127 bis 128 umgerechnet und als Parameter für das virtuelle Gamepad übergeben. In Windows kann man sich das dann z.B. mit USB-Gamecontroller einrichten (über Suche oder die Systemsteuerung) ansehen.

Die Möglichkeiten, die man durch das Python-HID-Modul erhält, sind vielfältig und spannend. Durch das standardisierte HID-System werden keine Treiber auf dem angeschlossenen PC oder Mobilgerät benötigt. Über die GPIOs lässt sich praktisch unbegrenzt weitere Hardware seriell (etwa über I2C, SPI, UART) oder analog anschließen, die dann einen Computer als Maus, Tastatur oder Gamepad steuert. Für die Wahl des Pico oder eines ähnlichen Boards für solche Anwendungen spricht der günstige Preis, der Support, die hohe Verbreitung des Boards und damit der großen Community, von der es im Zweifelsfall Hilfe gibt.

Selbst die Programmierung ist dank Python simpel und interaktiv. Neben den oben erwähnten Szenarien sind die Boards auch zur Konstruktion für persönlich angepasste, barrierefreie Eingabegeräte (sei es für die Arbeit oder das Gaming) sehr gut geeignet. Dies ist ein Gebiet, in dem Maker fast schon traditionell sehr aktiv und erfolgreich sind. Wir sind gespannt, welche Ideen in den Kommentaren zu dieser Meldung noch aufkommen. (caw)