diff --git a/Db9_zu_USB.ino b/Db9_zu_USB.ino new file mode 100644 index 0000000..e92dd8e --- /dev/null +++ b/Db9_zu_USB.ino @@ -0,0 +1,88 @@ +#include + +int up = 10; +int down = 11; +int left = 12; +int right = 13; +int button = 14; + +uint8_t const desc_hid_report[] = +{ + 0x05, 0x01, // Usage Page (Generic Desktop) + 0x09, 0x05, // Usage (Game Pad) + 0xA1, 0x01, // Collection (Application) + + // X und Y Achsen + 0x09, 0x30, // Usage (X) + 0x09, 0x31, // Usage (Y) + 0x15, 0x81, // Logical Minimum (-127) + 0x25, 0x7F, // Logical Maximum (127) + 0x75, 0x08, // Report Size (8) + 0x95, 0x02, // Report Count (2) + 0x81, 0x02, // Input (Data,Var,Abs) + + // Buttons (nur 1 Button) + 0x05, 0x09, // Usage Page (Button) + 0x19, 0x01, // Usage Minimum (Button 1) + 0x29, 0x01, // Usage Maximum (Button 1) + 0x15, 0x00, // Logical Minimum (0) + 0x25, 0x01, // Logical Maximum (1) + 0x75, 0x01, // Report Size (1) + 0x95, 0x01, // Report Count (1) + 0x81, 0x02, // Input (Data,Var,Abs) + + // Padding auf Bytegröße + 0x75, 0x07, // Report Size (7) + 0x95, 0x01, // Report Count (1) + 0x81, 0x03, // Input (Const,Var,Abs) + + 0xC0 // End Collection +}; + +Adafruit_USBD_HID usb_hid; + +typedef struct +{ + int8_t x; + int8_t y; + uint8_t buttons; +} gamepad_report_t; + +gamepad_report_t gp; + +void setup() +{ + pinMode(up, INPUT_PULLUP); + pinMode(down, INPUT_PULLUP); + pinMode(left, INPUT_PULLUP); + pinMode(right, INPUT_PULLUP); + pinMode(button, INPUT_PULLUP); + + if(!TinyUSBDevice.isInitialized()) TinyUSBDevice.begin(0); + + usb_hid.setPollInterval(2); + usb_hid.setReportDescriptor(desc_hid_report, sizeof(desc_hid_report)); + usb_hid.begin(); +} + +void loop() +{ + if(!TinyUSBDevice.mounted()) + { + return; + } + + gp.x = 0; + gp.y = 0; + gp.buttons = 0; + + if(digitalRead(up) == LOW) gp.y = -127; + if(digitalRead(down) == LOW) gp.y = 127; + if(digitalRead(left) == LOW) gp.x = -127; + if(digitalRead(right) == LOW) gp.x = 127; + if(digitalRead(button) == LOW) gp.buttons = 1; + + usb_hid.sendReport(0, &gp, sizeof(gp)); + + delay(10); +} diff --git a/README.md b/README.md index a91c356..b03a2d6 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,74 @@ -# Db9_zu_USB -DB9 zu USB Adapter +# DB9 zu USB Adapter + +Dieses Projekt ermöglicht es, alte **DB9-Joysticks** (wie den Amiga-Joystick oder andere Retro-Joysticks) mit modernen Computern über **USB** zu verbinden. Mithilfe eines **Raspberry Pi Pico** und eines **DB9-Anschlusses** werden die Joystick-Eingaben ausgelesen und als USB-Gamepad-Signale ausgegeben, sodass der Joystick mit modernen Systemen und Emulatoren verwendet werden kann. + +## Funktionen + +- Unterstützt **DB9-Joysticks** (z. B. Amiga, C64, Atari) +- Erfasst **2 Achsen** (X und Y) und **1 Feuertaste** +- Wandelt Joystick-Eingaben in **USB HID**-Gamepad-Signale um +- Plug-and-Play auf modernen Betriebssystemen (Windows, Linux, macOS) +- Geschrieben in **C++** mit der **TinyUSB**-Bibliothek zur USB-HID-Unterstützung + +## Hardwareanforderungen + +- **Raspberry Pi Pico** (empfohlen wegen der einfachen USB-HID-Unterstützung) +- **DB9-Buchse** für den Joystick-Eingang +- **Kabel** für die Verbindungen + +## Softwareanforderungen + +- **Arduino IDE** mit Unterstützung für den Raspberry Pi Pico (RP2040 Boards) +- **Adafruit TinyUSB Library** +- **TinyUSB Library** (in der Adafruit-Bibliothek enthalten) + +Stelle sicher, dass du diese Bibliotheken über den Bibliotheksmanager der Arduino IDE installierst. + +## Schaltplan + +Die Pins des DB9-Anschlusses müssen mit den entsprechenden GPIO-Pins des Raspberry Pi Pico verbunden werden: + +| DB9-Pin | Signal | Pico-Pin | +|---------|------------|---------------| +| 1 | Hoch | GPIO 10 | +| 2 | Runter | GPIO 11 | +| 3 | Links | GPIO 12 | +| 4 | Rechts | GPIO 13 | +| 6 | Feuer | GPIO 14 | +| 8 | Masse | GND | + +## Code-Erklärung + +Die Firmware liest die Joystick-Eingaben aus und sendet die Daten als USB-Gamepad-Bericht. Die **TinyUSB-Bibliothek** übernimmt die USB-Kommunikation. Der Joystick hat zwei Achsen (X und Y) und eine Taste für den Feuerknopf. + +Hier eine Zusammenfassung des verwendeten HID-Berichtsdeskriptors: + +- **X- und Y-Achsen**: 8-Bit-Werte, Bereich von -127 bis +127 +- **1 Taste**: 1-Bit-Wert (an/aus) +- **USB HID-Deskriptor-Format**: Benutzerdefinierter Berichtsdeskriptor für minimale Joystick-Eingaben + +### Wichtige Funktionen + +- `setup()`: Initialisiert das USB-Gerät und konfiguriert die GPIO-Pins als Eingänge. +- `loop()`: Liest den Status des Joysticks und sendet einen USB-Gamepad-Bericht an den Host. +- `usb_hid.sendReport()`: Sendet den HID-Bericht mit dem aktuellen Joystick-Zustand. + +## Verwendung + +1. **Firmware auf den Raspberry Pi Pico hochladen** über die Arduino IDE. +2. **DB9-Joystick an den Pico anschließen** über die Buchse. +3. **Pico mit dem PC verbinden**. Der Adapter wird als USB-Gamepad erkannt. +4. Funktionalität des Joysticks mit Tools wie `jstest` (Linux) oder den **Gamepad-Einstellungen** unter Windows testen. + +## Testen + +### Linux (`jstest`) +Um sicherzustellen, dass der Joystick korrekt funktioniert, kannst du das Tool **jstest** unter Linux verwenden: + +### Windows +Öffne die **Systemsteuerung > Geräte und Drucker** und prüfe die **Gamecontroller-Einstellungen**, um die Joystick-Eingaben zu testen. + +## Zukünftige Erweiterungen + +- Gehäuse (z. B. 3D-gedrucktes Gehäuse)