├── .gitattributes ├── .gitignore ├── Joystick ├── README.adoc ├── examples │ └── JSTest │ │ └── JSTest.ino ├── keywords.txt ├── library.properties └── src │ ├── Joystick.cpp │ └── Joystick.h └── README.md /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | 4 | # Custom for Visual Studio 5 | *.cs diff=csharp 6 | 7 | # Standard to msysgit 8 | *.doc diff=astextplain 9 | *.DOC diff=astextplain 10 | *.docx diff=astextplain 11 | *.DOCX diff=astextplain 12 | *.dot diff=astextplain 13 | *.DOT diff=astextplain 14 | *.pdf diff=astextplain 15 | *.PDF diff=astextplain 16 | *.rtf diff=astextplain 17 | *.RTF diff=astextplain 18 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Windows image file caches 2 | Thumbs.db 3 | ehthumbs.db 4 | 5 | # Folder config file 6 | Desktop.ini 7 | 8 | # Recycle Bin used on file shares 9 | $RECYCLE.BIN/ 10 | 11 | # Windows Installer files 12 | *.cab 13 | *.msi 14 | *.msm 15 | *.msp 16 | 17 | # Windows shortcuts 18 | *.lnk 19 | 20 | # ========================= 21 | # Operating System Files 22 | # ========================= 23 | 24 | # OSX 25 | # ========================= 26 | 27 | .DS_Store 28 | .AppleDouble 29 | .LSOverride 30 | 31 | # Thumbnails 32 | ._* 33 | 34 | # Files that might appear in the root of a volume 35 | .DocumentRevisions-V100 36 | .fseventsd 37 | .Spotlight-V100 38 | .TemporaryItems 39 | .Trashes 40 | .VolumeIcon.icns 41 | 42 | # Directories potentially created on remote AFP share 43 | .AppleDB 44 | .AppleDesktop 45 | Network Trash Folder 46 | Temporary Items 47 | .apdisk 48 | -------------------------------------------------------------------------------- /Joystick/README.adoc: -------------------------------------------------------------------------------- 1 | = Joystick Library for Arduino = 2 | 3 | This library allows an Arduino board with USB capabilites to act as a Joystick. 4 | 5 | == License == 6 | 7 | This is free and unencumbered software released into the public domain. 8 | 9 | Anyone is free to copy, modify, publish, use, compile, sell, or 10 | distribute this software, either in source code form or as a compiled 11 | binary, for any purpose, commercial or non-commercial, and by any 12 | means. 13 | 14 | In jurisdictions that recognize copyright laws, the author or authors 15 | of this software dedicate any and all copyright interest in the 16 | software to the public domain. We make this dedication for the benefit 17 | of the public at large and to the detriment of our heirs and 18 | successors. We intend this dedication to be an overt act of 19 | relinquishment in perpetuity of all present and future rights to this 20 | software under copyright law. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 25 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 26 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 27 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 28 | OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | For more information, please refer to 31 | -------------------------------------------------------------------------------- /Joystick/examples/JSTest/JSTest.ino: -------------------------------------------------------------------------------- 1 | //#include "HID.h" //uncomment for arduino due 2 | //note that for the due the hid controller only works through the native port 3 | #include "Joystick.h" 4 | 5 | void setup() { 6 | //zero out the joystick state 7 | Joystick.clearState(); 8 | //set pins as input (sparkfun joystick shield config) 9 | pinMode(2, INPUT); 10 | pinMode(3, INPUT); 11 | pinMode(4, INPUT); 12 | pinMode(5, INPUT); 13 | pinMode(6, INPUT); 14 | //enable pullups 15 | digitalWrite(2, HIGH); 16 | digitalWrite(3, HIGH); 17 | digitalWrite(4, HIGH); 18 | digitalWrite(5, HIGH); 19 | digitalWrite(6, HIGH); 20 | } 21 | 22 | void loop() { 23 | //clear 24 | Joystick.clearState(); 25 | //tweak the joystick state (see joystick.h for all possible fields) 26 | Joystick.state.x.axis = analogRead(0)-512; 27 | Joystick.state.y.axis = 511-analogRead(1); 28 | Joystick.state.buttons.b00 = !digitalRead(2); 29 | Joystick.state.buttons.b01 = !digitalRead(3); 30 | Joystick.state.buttons.b02 = !digitalRead(4); 31 | Joystick.state.buttons.b03 = !digitalRead(5); 32 | Joystick.state.buttons.b04 = !digitalRead(6); 33 | Joystick.state.hats.switch1 = HAT_LEFT; 34 | Joystick.state.hats.switch2 = HAT_UP; 35 | //call send state to pack and send the current state over usb 36 | Joystick.sendState(); 37 | delay(50); 38 | } 39 | -------------------------------------------------------------------------------- /Joystick/keywords.txt: -------------------------------------------------------------------------------- 1 | ####################################### 2 | # Syntax Coloring Map For Joystick 3 | ####################################### 4 | 5 | ####################################### 6 | # Datatypes (KEYWORD1) 7 | ####################################### 8 | 9 | Joystick KEYWORD1 10 | axis16_t KEYWORD1 11 | hats8_t KEYWORD1 12 | button32_t KEYWORD1 13 | JoyState_t KEYWORD1 14 | state KEYWORD1 15 | x KEYWORD1 16 | y KEYWORD1 17 | z KEYWORD1 18 | xRot KEYWORD1 19 | yRot KEYWORD1 20 | zRot KEYWORD1 21 | slider KEYWORD1 22 | dial KEYWORD1 23 | axis KEYWORD1 24 | hats KEYWORD1 25 | buttons KEYWORD1 26 | switch1 KEYWORD1 27 | switch2 KEYWORD1 28 | b00 KEYWORD1 29 | b01 KEYWORD1 30 | b02 KEYWORD1 31 | b03 KEYWORD1 32 | b04 KEYWORD1 33 | b05 KEYWORD1 34 | b06 KEYWORD1 35 | b07 KEYWORD1 36 | b08 KEYWORD1 37 | b09 KEYWORD1 38 | b10 KEYWORD1 39 | b11 KEYWORD1 40 | b12 KEYWORD1 41 | b13 KEYWORD1 42 | b14 KEYWORD1 43 | b15 KEYWORD1 44 | b16 KEYWORD1 45 | b17 KEYWORD1 46 | b18 KEYWORD1 47 | b19 KEYWORD1 48 | b20 KEYWORD1 49 | b21 KEYWORD1 50 | b22 KEYWORD1 51 | b23 KEYWORD1 52 | b24 KEYWORD1 53 | b25 KEYWORD1 54 | b26 KEYWORD1 55 | b27 KEYWORD1 56 | b28 KEYWORD1 57 | b29 KEYWORD1 58 | b30 KEYWORD1 59 | b31 KEYWORD1 60 | bitfield KEYWORD1 61 | HAT_UP KEYWORD1 62 | HAT_UPRIGHT KEYWORD1 63 | HAT_RIGHT KEYWORD1 64 | HAT_DOWNRIGHT KEYWORD1 65 | HAT_DOWN KEYWORD1 66 | HAT_DOWNLEFT KEYWORD1 67 | HAT_LEFT KEYWORD1 68 | HAT_UPLEFT KEYWORD1 69 | HAT_CENTER KEYWORD1 70 | AXIS_CENTER KEYWORD1 71 | AXIS_MIN KEYWORD1 72 | AXIS_MAX KEYWORD1 73 | 74 | ####################################### 75 | # Methods and Functions (KEYWORD2) 76 | ####################################### 77 | 78 | clearState KEYWORD2 79 | sendState KEYWORD2 80 | 81 | ####################################### 82 | # Constants (LITERAL1) 83 | ####################################### 84 | -------------------------------------------------------------------------------- /Joystick/library.properties: -------------------------------------------------------------------------------- 1 | name=Joystick 2 | version=1.0.0 3 | author=Lord Nothing 4 | maintainer=Lord Nothing 5 | sentence=Allows an Arduino board with USB capabilites to act as a Joystick. Supports Due and Leonardo. 6 | paragraph=This library plugs on the HID library. Can be used with or without other HID-based libraries (Keyboard, Gamepad etc) 7 | category=Device Control 8 | url=https://github.com/LordNuke/ArduinoLibs 9 | architectures=* 10 | -------------------------------------------------------------------------------- /Joystick/src/Joystick.cpp: -------------------------------------------------------------------------------- 1 | #include "joystick.h" 2 | 3 | #if defined(_USING_HID) 4 | 5 | static const uint8_t _hidReportDescriptorJoystick[] PROGMEM = { 6 | //32 buttons, 2 8-way hats, and 8 axes. 7 | 0x05, 0x01, //USAGE_PAGE (Generic Desktop) 8 | 0x09, 0x05, //USAGE (Game Pad) 9 | 0xa1, 0x01, //COLLECTION (Application) 10 | 0x85, 0x03, // REPORT_ID (3) 11 | 0xa1, 0x00, // COLLECTION (Physical) 12 | //32 buttons 13 | 0x05, 0x09, // USAGE_PAGE (Button) 14 | 0x19, 0x01, // USAGE_MINIMUM (Button 1) 15 | 0x29, 0x20, // USAGE_MAXIMUM (Button 32) 16 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 17 | 0x25, 0x01, // LOGICAL_MAXIMUM (1) 18 | 0x95, 0x20, // REPORT_COUNT (32) 19 | 0x75, 0x01, // REPORT_SIZE (1) 20 | 0x81, 0x02, // INPUT (Data,Var,Abs) 21 | //2 8-way hat switches 22 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 23 | 0x09, 0x39, // USAGE (Hat switch) 24 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 25 | 0x25, 0x07, // LOGICAL_MAXIMUM (7) 26 | 0x35, 0x00, // PHYSICAL_MINIMUM (0) 27 | 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315) 28 | 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) 29 | 0x75, 0x04, // REPORT_SIZE (4) 30 | 0x95, 0x01, // REPORT_COUNT (1) 31 | 0x81, 0x02, // INPUT (Data,Var,Abs) 32 | 0x09, 0x39, // USAGE (Hat switch) 33 | 0x15, 0x00, // LOGICAL_MINIMUM (0) 34 | 0x25, 0x07, // LOGICAL_MAXIMUM (7) 35 | 0x35, 0x00, // PHYSICAL_MINIMUM (0) 36 | 0x46, 0x3B, 0x01, // PHYSICAL_MAXIMUM (315) 37 | 0x65, 0x14, // UNIT (Eng Rot:Angular Pos) 38 | 0x75, 0x04, // REPORT_SIZE (4) 39 | 0x95, 0x01, // REPORT_COUNT (1) 40 | 0x81, 0x02, // INPUT (Data,Var,Abs) 41 | //8 16-bit axes 42 | 0xA1, 0x00, // COLLECTION (Physical) 43 | 0x05, 0x01, // USAGE_PAGE (Generic Desktop) 44 | 0x09, 0x30, // USAGE (X) 45 | 0x09, 0x31, // USAGE (Y) 46 | 0x09, 0x32, // USAGE (Z) 47 | 0x09, 0x33, // USAGE (Rx) 48 | 0x09, 0x34, // USAGE (Ry) 49 | 0x09, 0x35, // USAGE (Rz) 50 | 0x09, 0x36, // USAGE (Slider) 51 | 0x09, 0x37, // USAGE (Dial) 52 | 0x16, 0x00, 0x80, // LOGICAL_MINIMUM (-32768) 53 | 0x26, 0xff, 0x7f, // LOGICAL_MAXIMUM (32767) 54 | 0x75, 0x10, // REPORT_SIZE (16) 55 | 0x95, 0x08, // REPORT_COUNT (8) 56 | 0x81, 0x02, // INPUT (Data,Var,Abs) 57 | 0xc0, // END_COLLECTION 58 | 0xc0, // END_COLLECTION 59 | 0xc0 //END_COLLECTION 60 | }; 61 | 62 | //constructor that does nothing 63 | Joystick_::Joystick_(void){ 64 | clearState(); 65 | //append the discriptor to a thing idk 66 | static HIDSubDescriptor node(_hidReportDescriptorJoystick, sizeof(_hidReportDescriptorJoystick)); 67 | HID().AppendDescriptor(&node); 68 | } 69 | 70 | //reset joy state to defaults 71 | void Joystick_::clearState(void){ 72 | state.x.axis = AXIS_CENTER; 73 | state.y.axis = AXIS_CENTER; 74 | state.z.axis = AXIS_CENTER; 75 | state.xRot.axis = AXIS_CENTER; 76 | state.yRot.axis = AXIS_CENTER; 77 | state.zRot.axis = AXIS_CENTER; 78 | state.slider.axis = AXIS_CENTER; 79 | state.dial.axis = AXIS_CENTER; 80 | state.hats.switch1 = HAT_CENTER; 81 | state.hats.switch2 = HAT_CENTER; 82 | state.buttons.bitfield = 0; 83 | } 84 | //format and send state report. The report data format must match the one defined in the descriptor exactly 85 | //or it either won't work, or the pc will make a mess of unpacking the data 86 | #define JOY_DATA_SIZE 21 87 | void Joystick_::sendState(void){ 88 | uint8_t data[]{ 89 | //buttons 90 | state.buttons.data1, 91 | state.buttons.data2, 92 | state.buttons.data3, 93 | state.buttons.data4, 94 | //hats 95 | state.hats.data, 96 | //axes 97 | state.x.dataHi, 98 | state.x.dataLo, 99 | state.y.dataHi, 100 | state.y.dataLo, 101 | state.z.dataHi, 102 | state.z.dataLo, 103 | state.xRot.dataHi, 104 | state.xRot.dataLo, 105 | state.yRot.dataHi, 106 | state.yRot.dataLo, 107 | state.zRot.dataHi, 108 | state.zRot.dataLo, 109 | state.slider.dataHi, 110 | state.slider.dataLo, 111 | state.dial.dataHi, 112 | state.dial.dataLo 113 | }; 114 | //HID_SendReport(Report number, array of values in same order as HID descriptor, length) 115 | //HID_SendReport(3, data, JOY_DATA_SIZE); 116 | HID().SendReport(3,data,sizeof(data)); 117 | // The joystick is specified as using report 3 in the descriptor. That's where the "3" comes from 118 | } 119 | 120 | Joystick_ Joystick; 121 | 122 | 123 | #endif -------------------------------------------------------------------------------- /Joystick/src/Joystick.h: -------------------------------------------------------------------------------- 1 | #ifndef JOYSTICK_H 2 | #define JOYSTICK_H 3 | 4 | #include "HID.h" 5 | 6 | #if !defined(_USING_HID) 7 | 8 | #warning "Using legacy HID core (non pluggable)" 9 | 10 | #else 11 | 12 | typedef union button32{ 13 | uint32_t bitfield; 14 | struct{ 15 | uint8_t data1; 16 | uint8_t data2; 17 | uint8_t data3; 18 | uint8_t data4; 19 | }; 20 | struct{ 21 | uint8_t b00:1; uint8_t b01:1; uint8_t b02:1; uint8_t b03:1; 22 | uint8_t b04:1; uint8_t b05:1; uint8_t b06:1; uint8_t b07:1; 23 | uint8_t b08:1; uint8_t b09:1; uint8_t b10:1; uint8_t b11:1; 24 | uint8_t b12:1; uint8_t b13:1; uint8_t b14:1; uint8_t b15:1; 25 | uint8_t b16:1; uint8_t b17:1; uint8_t b18:1; uint8_t b19:1; 26 | uint8_t b20:1; uint8_t b21:1; uint8_t b22:1; uint8_t b23:1; 27 | uint8_t b24:1; uint8_t b25:1; uint8_t b26:1; uint8_t b27:1; 28 | uint8_t b28:1; uint8_t b29:1; uint8_t b30:1; uint8_t b31:1; 29 | }; 30 | }button32_t; 31 | 32 | #define HAT_UP 0 33 | #define HAT_UPRIGHT 1 34 | #define HAT_RIGHT 2 35 | #define HAT_DOWNRIGHT 3 36 | #define HAT_DOWN 4 37 | #define HAT_DOWNLEFT 5 38 | #define HAT_LEFT 6 39 | #define HAT_UPLEFT 7 40 | #define HAT_CENTER 8 41 | 42 | typedef union hats8{ 43 | uint8_t data; 44 | struct{ 45 | uint8_t switch1:4; 46 | uint8_t switch2:4; 47 | }; 48 | }hats8_t; 49 | 50 | #define AXIS_CENTER 0 51 | #define AXIS_MIN -32768 52 | #define AXIS_MAX 32767 53 | 54 | typedef union axis16{ 55 | int16_t axis; 56 | struct{ 57 | uint8_t dataHi; 58 | uint8_t dataLo; 59 | }; 60 | }axis16_t; 61 | 62 | typedef struct JoyState{ // Pretty self explanitory. Simple state to store all the joystick parameters 63 | //8 signed 16-bit axes 64 | axis16_t x; 65 | axis16_t y; 66 | axis16_t z; 67 | axis16_t xRot; 68 | axis16_t yRot; 69 | axis16_t zRot; 70 | axis16_t slider; 71 | axis16_t dial; 72 | //2 4-bit hat switches 73 | hats8_t hats; 74 | //uint8_t hatSw1; 75 | //uint8_t hatSw2; 76 | //32 buttons 77 | //uint32_t buttons; 78 | button32_t buttons; 79 | } JoyState_t; 80 | 81 | class Joystick_ 82 | { 83 | public: 84 | JoyState_t state; 85 | Joystick_(void); 86 | void clearState(void); 87 | void sendState(void); 88 | }; 89 | extern Joystick_ Joystick; 90 | 91 | #endif 92 | #endif -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | = Joystick Library for Arduino = 2 | 3 | This library allows an Arduino board with USB capabilites to act as a Joystick. 4 | Currently supports Due and Leonardo. 5 | 6 | currently supports: 7 | 8 16-bit axes 8 | 32 buttons 9 | 2 8-way hat switches 10 | 11 | in the future i may add additional controller configurations, like more buttons/hats or different axis resolutions. 12 | perhaps some debounce functions, axis filtering and scaling code as well. we will see. 13 | 14 | == License == 15 | 16 | This is free and unencumbered software released into the public domain. 17 | 18 | Anyone is free to copy, modify, publish, use, compile, sell, or 19 | distribute this software, either in source code form or as a compiled 20 | binary, for any purpose, commercial or non-commercial, and by any 21 | means. 22 | 23 | In jurisdictions that recognize copyright laws, the author or authors 24 | of this software dedicate any and all copyright interest in the 25 | software to the public domain. We make this dedication for the benefit 26 | of the public at large and to the detriment of our heirs and 27 | successors. We intend this dedication to be an overt act of 28 | relinquishment in perpetuity of all present and future rights to this 29 | software under copyright law. 30 | 31 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 32 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 33 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 34 | IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR 35 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 36 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 37 | OTHER DEALINGS IN THE SOFTWARE. 38 | 39 | For more information, please refer to 40 | --------------------------------------------------------------------------------