| Byte | Type | Description |
|---|---|---|
| 0,1 | int16_t | Analog Axis 0 (X) value. -32768 to 32787 |
| 2,3 | int16_t | Analog Axis 1 (Y) value. -32768 to 32787 |
| 4,5 | int16_t | Analog Axis 2 value. -32768 to 32787 |
| 6,7 | int16_t | Analog Axis 3 value. -32768 to 32787 |
| 8,9 | int16_t | Analog Axis 4 value. -32768 to 32787 |
| 10,11 | int16_t | Analog Axis 5 value. -32768 to 32787 |
| 12,13 | int16_t | Analog Axis 6 value. -32768 to 32787 |
| 14,15 | int16_t | Analog Axis 7 value. -32768 to 32787 |
| 16 | uint8_t | Buttons 0-7. Bit 0 = button 0, bit 7 = button 7 |
| 17 | uint8_t | Buttons 8-15. Bit 0 = button 8, bit 7 = button 15 |
| 18 | uint8_t | Buttons 16-23. Bit 0 = button 16, bit 7 = button 23 |
| 19 | uint8_t | Buttons 24-31. Bit 0 = button 24, bit 7 = button 31 |
| 20 | uint8_t | Buttons 32-39. Bit 0 = button 32, bit 7 = button 40 |
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x04, /* Usage (Joystick) */
0xa1, 0x01, /* Collection (Application) */
0x09, 0x01, /* Usage (Pointer) */
/* 8 axes, signed 16 bit resolution, range -32768 to 32767 (16 bytes) */
0xa1, 0x00, /* Collection (Physical) */
0x05, 0x01, /* Usage Page (Generic Desktop) */
0x09, 0x30, /* Usage (X) */
0x09, 0x31, /* Usage (Y) */
0x09, 0x32, /* Usage (Analog1) */
0x09, 0x33, /* Usage (Analog2) */
0x09, 0x34, /* Usage (Analog3) */
0x09, 0x35, /* Usage (Analog4) */
0x09, 0x36, /* Usage (Analog5) */
0x09, 0x37, /* Usage (Analog6) */
0x16, 0x00, 0x80, /* Logical Minimum (-32768) */
0x26, 0xff, 0x7f, /* Logical Maximum (32767) */
0x75, 16, /* Report Size (16) */
0x95, 8, /* Report Count (8) */
0x81, 0x82, /* Input (Data, Variable, Absolute, Volatile) */
0xc0, /* End Collection */
/* 40 buttons, value 0=off, 1=on (5 bytes) */
0x05, 0x09, /* Usage Page (Button) */
0x19, 1, /* Usage Minimum (Button 1) */
0x29, 40, /* Usage Maximum (Button 40) */
0x15, 0x00, /* Logical Minimum (0) */
0x25, 0x01, /* Logical Maximum (1) */
0x75, 1, /* Report Size (1) */
0x95, 40, /* Report Count (40) */
0x81, 0x02, /* Input (Data, Variable, Absolute) */
0xc0 /* End Collection */
/* Arduino USB Joystick HID demo */
/* Author: Darran Hunt
* Released into the public domain.
*/
#define NUM_BUTTONS 40
#define NUM_AXES 8 // 8 axes, X, Y, Z, etc
typedef struct joyReport_t {
int16_t axis[NUM_AXES];
uint8_t button[(NUM_BUTTONS+7)/8]; // 8 buttons per byte
} joyReport_t;
joyReport_t joyReport;
void setup()
{
Serial.begin(115200);
delay(200);
for (uint8_t ind=0; ind<8; ind++) {
joyReport.axis[ind] = ind*1000;
}
for (uint8_t ind=0; ind<sizeof(joyReport.button); ind++) {
joyReport.button[ind] = 0;
}
}
// Send an HID report to the USB interface
void sendJoyReport(struct joyReport_t *report)
{
Serial.write((uint8_t *)report, sizeof(joyReport_t));
}
// turn a button on
void setButton(joyReport_t *joy, uint8_t button)
{
uint8_t index = button/8;
uint8_t bit = button - 8*index;
joy->button[index] |= 1 << bit;
}
// turn a button off
void clearButton(joyReport_t *joy, uint8_t button)
{
uint8_t index = button/8;
uint8_t bit = button - 8*index;
joy->button[index] &= ~(1 << bit);
}
uint8_t button=0; // current button
bool press = true; // turn buttons on?/* Turn each button on in sequence 1 - 40, then off 1 - 40
* add values to each axis each loop
*/
void loop()
{
// Turn on a different button each time
if (press) {
setButton(&joyReport, button);
} else {
clearButton(&joyReport, button);
}
/* Move all of the axes */ for (uint8_t ind=0; ind<8; ind++) { joyReport.axis[ind] += 10 * (ind+1); } sendJoyReport(&joyReport); button++; if (button >= 40) { button = 0; press = !press; } delay(100); }
Upload the sketch to the Arduino first, then flash Arduino-big-joystick.hex to the 8U2/16U2. Unplug the Arduino and plug it back in, and will look like a joystick to the host and the host will receive the joystick updates from the sketch.
If you want to upload another sketch, flash Arduino-usbserial.hex to the 8U2/16U2 first, unplug the Arduino and plug it back in. You can now upload the sketch.




Comments
<a|g> (unauthenticated)
Jan 31, 2013
Darran,
Is the source available for this? I could not find it on the Github link that you posted.
Thanks
darran
Jan 31, 2013
Here's a browse link to the big joystick source: https://github.com/harlequin-tech/arduino-usb/tree/master/firmwares/arduino-big-joystick.
Alex (unauthenticated)
Feb 26, 2013
Hi Darran,
Thanks for such useful project! What need to be modified in order to add another 40 buttons and have 80 in total?
Thanks!
Dom (unauthenticated)
Feb 27, 2013
Hi Darren
I've made a custom keyboard interface and wanting to add two joystick interfaces now. How possible (and easy) is it to make multple devices run from one Arduino 2560?
Alex (unauthenticated)
Feb 27, 2013
Hey Dom, you may want to check this: https://code.google.com/p/unojoy/downloads/list
Dom (unauthenticated)
Feb 28, 2013
I've seen the double joystick but haven't figured out which part of the code handles the usb device part. Admittedly I don't have a full handle on the USB HID bootstrap. So fare I've found nobody who has created code that allows more than one type of device running from an Arduino UNO. I'm thinking the 4kb limit may have something to do with it but it would be awesome to have a hex file which included a keyboard, joysticks and midi (and mouse I guess) all controlled through one Arduino Mega through one usb port. I have a feeling the 16mhz is also a limiting factor here.
darran
Mar 3, 2013
Hi Alex,
you can increase the number of buttons by modifying the descriptor called JoystickReport in Descriptors.c to add more buttons, and modifying the USB_JoystickReport_Data_t structure in Arduino-joystick.h to make room for the additional buttons.
darran
Mar 3, 2013
Hi Dom,
if you have a newer Arduino 2560 with the 16u2 then you can fit in additional devices in the descriptor and add code to send data for them. With the older 8u2 its unlikely it will have the code space to support them.
Andy (unauthenticated)
Mar 8, 2013
Hi Darran, thanks for your hard work! I am using your firmware on Sparkfun's 32U4 breakout board (not an Arduino). After some minor modifications to the makefile (changed MCU) I got my board to enumerate in Windows and show up as a game controller. I am using the Big Joystick demo and my question is, how can I write to the joystick axes? I have several potentiometers hooked up to various ADC ports and I would like each of them to control a joystick axis.
Thank you!
Ender117 (unauthenticated)
Mar 24, 2013
Hello Darran,
Thank you for all of these great resources. I have flashed the firmware successfully, but I am confused about how to assign pins to the potentiometers and buttons that I have. I don't see any pin assignments in your Arduino BigJoystick sketch. Should I be writing those myself? If you have time, could you point me in the right direction on how to do that? Thank you so much.
Gyom (unauthenticated)
Mar 25, 2013
Hi Darran, great work!
I have a question tho. If you use the Arduino as a joystick, can you still send back data to it via a serial connection? I mean, would you still be able to make the Arduino light up led and other device from commands sent from the PC at the sametime it "emulate" a joystick in Windows?
Thanks!
darran
Apr 21, 2013
Hi Gyom,
the 8u2/16u2 firmware replaces the serial function with the new function. This mean when you flash the joystick or keyboard firmware, the Arduino appears to be a joystick or keyboard and not a serial port.
i-make-robots (unauthenticated)
Apr 22, 2013
Thank you for this excellent How To. I've just build a 6DOF joystick for Kerbal Space Program and Minecraft. Maybe even Descent? I really hope with this I can get it to work. I'll let you know!
Ender117 (unauthenticated)
Apr 24, 2013
Hello again Darran. Can you provide some indication on how to assign pins using your code?
Dan (unauthenticated)
Apr 25, 2013
Hi, Darran. Great tutorial. Thank you for writing it and doing all that hard work on your own. I'm trying to follow your example to flash my MEGA 2560 from OSX Lion. All I get is "dfu-programmer: no device present." Any idea what I'm doing wrong?
darran
Yesterday at 9:16 PM
Dan, try the latest version of dfu-programmer (http://dfu-programmer.sourceforge.net). It might also be that your mega is not in DFU mode, this page may help http://arduino.cc/en/Hacking/DFUProgramming8U2 (its the same two pins on the 2560).