Loading...
Pages: [1]   Go Down
Author Topic: FAST HID Joystick converter for 2 digital joysticks  (Read 1549 times)
0 Members and 1 Guest are viewing this topic.
Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

Hi,
if you want to connect some oldshool digital joysticks like the competition pro to your pc, ps3, raspberry pi or whatever here's a simple and fast solution. It's also perfect to build your retro commodore amiga/c64/atari/sega...

This code transforms the arduino leonardo board into a HID joystick converter for two digital joysticks.


put this into your HID.cpp to create 2 HID Gamepads:
Code:
//   Commodore /  Atari Joystick 1

   0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
   0x09, 0x05,                    // USAGE (Game Pad)
   0xa1, 0x01,                    // COLLECTION (Application)
   0x85, 0x03,                    //   REPORT_ID (3)
   0x09, 0x01,                    //   USAGE (Pointer)
   0xa1, 0x00,                    //   COLLECTION (Physical)
   0x09, 0x30,                    //     USAGE (X)
   0x09, 0x31,                    //     USAGE (Y)
   0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
   0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
   0x95, 0x02,                    //     REPORT_COUNT (2)
   0x75, 0x02,                    //     REPORT_SIZE (2) ; two bits to represent each axis
   0x81, 0x02,                    //     INPUT (Data,Var,Abs)
   0xc0,                          //   END_COLLECTION
   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)
   0x95, 0x01,                    //   REPORT_COUNT (1) ; 1 button
   0x75, 0x01,                    //   REPORT_SIZE (1)
   0x81, 0x02,                    //   INPUT (Data,Var,Abs)
   0x95, 0x02,                    //   REPORT_COUNT (2) ; to pad out the bits into a number divisible by 8
   0x81, 0x03,                    //   INPUT (Const,Var,Abs)
    0x05, 0x09,                    //   USAGE_PAGE (Button)
   0x19, 0x02,                    //   USAGE_MINIMUM (Button 2)
   0x29, 0x02,                    //   USAGE_MAXIMUM (Button 2)
   0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
   0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
   0x95, 0x01,                    //   REPORT_COUNT (1) ; 1 button
   0x75, 0x01,                    //   REPORT_SIZE (1)
   0x81, 0x02,                    //   INPUT (Data,Var,Abs)
   0xc0,                          // END_COLLECTION
 
//   Commodore /  Atari Joystick 2

   0x05, 0x01,                    // USAGE_PAGE (Generic Desktop)
   0x09, 0x05,                    // USAGE (Game Pad)
   0xa1, 0x01,                    // COLLECTION (Application)
   0x85, 0x04,                    //   REPORT_ID (4)
    0xa1, 0x00,                    //   COLLECTION (Physical)  
   0x05, 0x09,                    //   USAGE_PAGE (Button)
   0x19, 0x01,                    //   USAGE_MINIMUM (Button 1)
   0x29, 0x02,                    //   USAGE_MAXIMUM (Button 2)
   0x15, 0x00,                    //   LOGICAL_MINIMUM (0)
   0x25, 0x01,                    //   LOGICAL_MAXIMUM (1)
   0x95, 0x02,                    //   REPORT_COUNT (2) ; 2 buttons
   0x75, 0x01,                    //   REPORT_SIZE (1)
   0x81, 0x02,                    //   INPUT (Data,Var,Abs)
    0x95, 0x02,                    //   REPORT_COUNT (2) ; to pad out the bits into a number divisible by 8
   0x81, 0x03,                    //   INPUT (Const,Var,Abs)
    0x05, 0x01,                    //     USAGE_PAGE (Generic Desktop)
   0x09, 0x30,                    //     USAGE (X)
   0x09, 0x31,                    //     USAGE (Y)
   0x15, 0xff,                    //     LOGICAL_MINIMUM (-1)
   0x25, 0x01,                    //     LOGICAL_MAXIMUM (1)
   0x95, 0x02,                    //     REPORT_COUNT (2)
   0x75, 0x02,                    //     REPORT_SIZE (2) ; two bits to represent each axis
   0x81, 0x02,                    //     INPUT (Data,Var,Abs)
   0xc0,                          //   END_COLLECTION
   0xc0                           // END_COLLECTION    


merge this into your existing sketch or use it as a standalone solution:

Code:

    uint8_t Joy;
    uint8_t MemoJoy1 ;
    uint8_t MemoJoy2 ;

    void setup() {

      // Joystick 1
      pinMode(0, INPUT_PULLUP);                  // configure as DigIn  with pull up
      pinMode(1, INPUT_PULLUP);
      pinMode(2, INPUT_PULLUP);
      pinMode(3, INPUT_PULLUP);
      pinMode(4, INPUT_PULLUP);
      pinMode(5, INPUT_PULLUP);
    
      // Joystick 2
      pinMode(A0, INPUT_PULLUP);
      pinMode(A1, INPUT_PULLUP);
      pinMode(A2, INPUT_PULLUP);
      pinMode(A3, INPUT_PULLUP);
      pinMode(A4, INPUT_PULLUP);
      pinMode(A5, INPUT_PULLUP);

    }

    void loop()
    {         // Joystick 1
          Joy = ~PIND & 0b10011111;     // read Port D, invert logic, mask relevant bits
          if (Joy != MemoJoy1) {        // state changed?
            HID_SendReport(3, &Joy, 1); // send HID report
            MemoJoy1 = Joy;             // save last state
          }
         // Joystick 2
          Joy = ~PINF & 0b11110011;
          if (Joy != MemoJoy2) {
            HID_SendReport(4, &Joy, 1);
            MemoJoy2 = Joy;
          }
       }

Joystick 1 must be hooked up to digital inputs 0...5, joystck 2 to analog inputs A0...A5.
This is the pin assignment:

Code:
   Joystick 1

    IO DB9  Function

    1   1   Forward
    0   2   Back
    2   3   Left
    3   4   Right
        5   not connected
    4   6   Button1
    5V  7   +5V  ( only needed if the joystick contains circuits like autofire,.. )
    GND 8   Ground
    6   9   Button2 (optional)

    Joystick 2

    IO DB9  Function

    A0  1   Forward
    A1  2   Back
    A2  3   Left
    A3  4   Right
        5   not connected
    A5  6   Button1
    5V  7   +5V
    GND 8   Ground
    A4  9   Button2 (optional)

Together with the arduino keyboard interface http://www.raspberrypi.org/phpBB3/viewtopic.php?f=40&t=10990
made by thradtke you have the complete keyrah functionality.

Olaf



« Last Edit: February 09, 2013, 07:20:30 am by olaf » Logged

Dipl. Ing. (FH) Olaf Berthold
Hardware- und Softwareentwicklung

Germany
Offline Offline
Newbie
*
Karma: 0
Posts: 10
View Profile
WWW
 Bigger Bigger  Smaller Smaller  Reset Reset

update: 2nd button added
Logged

Dipl. Ing. (FH) Olaf Berthold
Hardware- und Softwareentwicklung

Pages: [1]   Go Up
Print
 
Jump to: