Kürzlich bin ich auf ein Projekt gestoßen, das mittels Adafruit_TinyUSB-Library mit einem Raspberry Pi Pico Tastatureingaben simuliert hat. Hier werde ich mir die Technik dafür erarbeiten. Deshalb befindet sich diese Seite z.Z. noch im Entstehungsmodus.

Die Entwicklungsbasis ist das Pico Restouch LCD 3,5″ Display von Waveshare. Bestückt mit einen Pico, der im Lieferumfang von azdelivery.de enthalten war. Außerdem gibt dazu einen Projektvorschlag für einen Tastatursimulator. Als IDE kommt die Arduino-IDE zum Einsatz.

Die Adafruit_TinyUSB Library stellt verschiedene HID’s (Human Interface Device) zur Verfügung. Mich interessiert hier nur die Keyboard HID. Ein Beispiel für deren Anwendung befindet sich hier. Ich habe aus diesem Beispiel nur die Teile heraus gesucht, die für das Keyboard-HID erforderlich sind:

Zuerst muss die Headerdatei eingebunden werden.

#include "Adafruit_TinyUSB.h"

Dann wird das Keyboard eingerichtet:

// -------- USB HID KEYBOARD -----------
enum { RID_KEYBOARD = 1 };
uint8_t const desc_hid_report[] = { TUD_HID_REPORT_DESC_KEYBOARD(HID_REPORT_ID(RID_KEYBOARD)) };
uint8_t keycode[6] = { HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE, HID_KEY_NONE };
Adafruit_USBD_HID usb_hid;

keycode[] ist ein Array in dem der zu übertragende Text aufbereitet und an usb_hid übergeben wird. Dafür stehen Konstanten in hid.h zur Verfügung.

Ob keycode[] nur 6 Elemente enthalten darf werde ich später noch klären.

Die Anwendung ist dann ganz einfach:

keycode[0] = HID_KEY_C;
usb_hid.keyboardReport(RID_KEYBOARD, KEYBOARD_MODIFIER_LEFTCTRL, keycode);
delay(10);
usb_hid.keyboardRelease(RID_KEYBOARD);
  • In keycode[] werden die Werte eingetragen.
  • Der KEYBOARD_MODIFIER ist normalerweise 0.
  • Mit usb_hid.keyboardReport() werden die Daten zum PC geschickt.
  • Dann wird kurz gewartet (wahrscheinlich hier 10mS).
  • Und schließlich mit usb_hid.keyboardRelease() dem PC mitgeteilt, dass die Übertragung beendet ist.

Die Übertragung ist sehr zeitkritisch! Zwei gleiche Zeichen direkt hintereinander (Hallo) funktioniert meistens nicht. Hier das Ergebnis zur zuverlässigen Übertragung von „Hallo\n“:

// ----- btn_12 action
void btn_12_pressAction(void) {
  if (btn_12.justPressed()) {
    keycode[0] = HID_KEY_H;
    keycode[1] = HID_KEY_NONE;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, KEYBOARD_MODIFIER_LEFTSHIFT, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    delay(25);
    keycode[0] = HID_KEY_A;
    keycode[1] = HID_KEY_L;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    delay(25);
    keycode[0] = HID_KEY_L;
    keycode[1] = HID_KEY_O;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    delay(25);
    keycode[0] = HID_KEY_ENTER;
    keycode[1] = HID_KEY_ENTER;
    keycode[2] = HID_KEY_NONE;
    keycode[3] = HID_KEY_NONE;
    keycode[4] = HID_KEY_NONE;
    keycode[5] = HID_KEY_NONE;
    usb_hid.keyboardReport(RID_KEYBOARD, 0, keycode);
    delay(10);
    usb_hid.keyboardRelease(RID_KEYBOARD);
    btn_12.drawSmoothButton(true);
  }
}
void btn_12_releaseAction(void) {
  if (btn_12.justReleased()) {
    usb_hid.keyboardRelease(RID_KEYBOARD);
    btn_12.drawSmoothButton(false);
  }
}

Sonderbarer Weise wird Enter nur zuverlässig übergeben, wenn es zweimal gesendet wird! Es kommt zu keiner doppelten Erkennung! Es funktioniert auch, wenn Enter im ersten und im letzten Element übergeben werden.

Mysterium

Wenn schon vorher Text eingegeben wurde wird meistens 2x \n ausgegeben?!