Arduino Leonardo/Micro As Game Controller/Joystick

258,308

169

205

Introduction: Arduino Leonardo/Micro As Game Controller/Joystick

IMPORTANT NOTE: This article is for Arduino IDE version 1.6.6 (or above). To add a USB Game Controller to an Arduino Leonardo or Micro using Arduino IDE version 1.6.5 (or below) see the following Instructable: Add USB Game Controller to Arduino Leonardo/Micro.

Out of the box the Arduino Leonardo and the Arduino Micro appear to the host computer as a generic keyboard and mouse. This article discusses how the Arduino Leonardo and the Arduino Micro can also appear as a generic Game Controller or Joystick. This project will only work with Arduino products based on the ATmega32u4 microcontroller (i.e. the Arduino Leonardo and the Arduino Micro). It will not work with the Arduino UNO, because it is based on the ATmega328 microcontroller.

The Arduino Joystick Library (a.k.a. Game Controller library) used in the Instructable provides the following:

  • X, Y, and Z axis
  • 32 buttons
  • X, Y, and Z axis rotation
  • Rudder
  • Throttle
  • 2 Point of View Hat Switches

Step 1: Installing the Library

The latest version of the Arduino library that allows the Arduino Leonardo and Micro to appear as a Game Controller can be downloaded from the following GitHub repository:

https://github.com/MHeironimus/ArduinoJoystickLibrary/tree/version-1.0

This GitHub repository actually contains three different versions of the Arduino Joystick Library:

  • Joystick - Causes the Arduino to appear as single Game Controller
  • Joystick2 - Causes the Arduino to appear as two, simple Game Controllers
  • Joystick3 - Causes the Arduino to appear as three, simple Game Controllers

Copy the Joystick (and/or Joystick2 and/or Joystick3) folder from GitHub to the Arduino Libraries folder (typically located at %userprofile%\Documents\Arduino\libraries). The library (or libraries) should now appear in the Arduino IDE list of libraries.

Step 2: Running the Test Sketch

Included in the library is a test sketch, called UsbJoystickTest.ino (or UsbJoystick2Test.ino or UsbJoystick3Test.ino). This sketch should be loaded, compiled, and uploaded to the Arduino Leonardo or Micro using the Arduino IDE (version 1.6.6 or above).

The following steps are for Windows 7. If you have a different version of Windows or a different operating system, these steps may differ.

Step 3: Windows Control Panel - Hardware and Sound

Go to the Windows Control Panel and select “Hardware and Sound”.

Step 4: Devices and Printers

Then select “Devices and Printers”.

Step 5: Arduino Settings

  1. The Arduino Micro or Arduino Leonardo should appear in the list of devices.
  2. Right mouse click on the Arduino Leonardo or Arduino Micro to display the settings menu.
  3. Select “Game controller settings” to get to the “Game Controllers” dialog.

Step 6: Game Controller Settings

The Arduino Leonardo or Micro should appear in the list of installed game controllers. Select the Arduino Leonardo or Micro and click the Properties button to display the game controller test dialog.

Step 7: Test Using Game Controller Settings

While this dialog has focus, ground pin A0 on the Arduino to activate the test script. The test script will test the game controller functionality in the following order:

  • 32 buttons
  • throttle and rudder
  • X and Y Axis
  • Z Axis
  • 2 Hat Switches
  • X and Y Axis Rotation

Step 8: Another Simple Test

Once you have verified the Arduino Leonardo or Micro is working as a Game Controller, you can start creating your own Game Controller projects. The attached Arduino sketch file is a simple example that reads digital pins 9, 10, 11, and 12 and maps them to buttons 1, 2, 3, and 4 on the Game Controller.

Step 9: Joystick Library API

Now that the Joystick library is available to the Arduino IDE, an Arduino Leonardo or Arduino Micro can be used for custom game controller projects. The following describes the complete Arduino Joystick Library API.

Joystick.begin(bool initAutoSendState)

Starts emulating a game controller connected to a computer. By default all methods update the game controller state immediately. If initAutoSendState is set to false, the Joystick.sendState method must be called to update the game controller state.

Joystick.end()

Stops the game controller emulation to a connected computer.

Joystick.setXAxis(byte value)

Sets the X axis value. Range -127 to 127 (0 is center).

Joystick.setYAxis(byte value)

Sets the Y axis value. Range -127 to 127 (0 is center).

Joystick.setZAxis(byte value)

Sets the Z axis value. Range -127 to 127 (0 is center).

Joystick.setXAxisRotation(int value)

Sets the X axis rotation value. Range 0° to 360°.

Joystick.setyAxisRotation(int value)

Sets the Y axis rotation value. Range 0° to 360°.

Joystick.setZAxisRotation(int value)

Sets the Z axis rotation value. Range 0° to 360°.

Joystick.setButton(byte button, byte value)

Sets the state (0 or 1) of the specified button (0 - 31). The button is the 0-based button number (i.e. button #1 is 0, button #2 is 1, etc.). The value is 1 if the button is pressed and 0 if the button is released.

Joystick.pressButton(byte button)

Press the indicated button (0 - 31). The button is the 0-based button number (i.e. button #1 is 0, button #2 is 1, etc.).

Joystick.releaseButton(byte button)

Release the indicated button (0 - 31). The button is the 0-based button number (i.e. button #1 is 0, button #2 is 1, etc.).

Joystick.setThrottle(byte value)

Sets the throttle value. Range 0 to 255.

Joystick.setRudder(byte value)

Sets the rudder value. Range 0 to 255.

Joystick.setHatSwitch(byte hatSwitch, int value)

Sets the value of the specified hat switch. The hatSwitch is 0-based (i.e. hat switch #1 is 0 and hat switch #2 is 1). The value is from 0° to 360°, but in 45° increments. Any value less than 45° will be rounded down (i.e. 44° is rounded down to 0°, 89° is rounded down to 45°, etc.). Set the value to -1 to release the hat switch.

Joystick.sendState()

Sends the updated joystick state to the host computer. Only needs to be called if AutoSendState is false (see Joystick.begin for more details).

Step 10: Additional Information

Additional information about this Arduino Joystick Library can be found on the following websites:

Arduino Joystick Library - http://mheironimus.blogspot.com/2015/11/arduino-joystick-library.html

GitHub [MHeironimus/ArduinoJoystickLibrary] - https://github.com/MHeironimus/ArduinoJoystickLibrary

Tech Contest

Participated in the
Tech Contest

Be the First to Share

    Recommendations

    • Recycled Speed Challenge

      Recycled Speed Challenge
    • Make it Move Contest 2020

      Make it Move Contest 2020
    • Build a Tool Contest

      Build a Tool Contest

    205 Discussions

    0
    DaleReitz
    DaleReitz

    1 day ago

    Is their anyway to add a LED light on one of the pins?
    Thanks :)

    1
    clabit73
    clabit73

    Question 4 months ago

    Hi,
    can i use arduino pro micro?
    where can I find a connection scheme?
    I have to connect 13 botton
    2 potentiometers for x y rotation
    Thanks

    0
    Zokss
    Zokss

    Answer 22 days ago

    Its pretty simple. You can use pro mico exactly as leonardo, its same chip, just smaller size, potentiometers one side goes to 5V(VCC) and other side goes to GND, middle points goes to Analog Pins (A0,A1) . Buttons you can find schematic on internet, they go to digital Pins which are labeled just with numbers.

    0
    carlosdesedas
    carlosdesedas

    Reply 17 days ago

    Hi Zokss. I also have an arduino pro micro.. I connect the x axis to A0 and the y axis to A1 of the board. The ground and 5V go to the board also... but since I have exactly 2/10 programming knowledge, I'd love to see if you could help me program something that I can copy/paste to the Arduino tool, compile and upload to the pro micro.. :-)

    I only need to be able to use the 2 axis on the mini joystick... in order for this I need the arduino pro micro to be recognized as a Game Controller by windows as a 2 axis controller. as a bonus, if you could also program the click on the thumbstick as a button, it'd be great... I really appreciate any help as I have searched all over the internet and what I have found is that when most people help, they assume you know some of the steps needed.... and i haven't been able to get this going for a couple of days now... I guess this SHOULD be a simple program, but as I told you before, I'm a newbie in this...

    Thanks!

    0
    Zokss
    Zokss

    Reply 17 days ago

    #include
    Joystick_ Joystick;
    int xAxis_ = 0;
    int yAxis_ = 0;
    int lastButtonState = 0;


    const int pinToButtonMap = 3; // button goes to digital pin 3


    const bool initAutoSendState = true;
    void setup()
    {
    Joystick.begin();
    pinMode(pinToButtonMap, INPUT_PULLUP);
    }
    void loop(){
    xAxis_ = analogRead(A0);
    yAxis_ = analogRead(A1);

    xAxis_ = map(xAxis_,0,1023,0,255);
    Joystick.setXAxis(xAxis_);

    yAxis_ = map(yAxis_,0,1023,0,255);
    Joystick.setYAxis(yAxis_);

    int currentButtonState = !digitalRead(pinToButtonMap);
    if (currentButtonState != lastButtonState)

    {

    Joystick.setButton(0, currentButtonState);
    }

    delay (50);
    }

    // i never used a button before, but i think thats is it.
    // hope this helps :)

    1
    carlosdesedas
    carlosdesedas

    Reply 16 days ago

    dude.. you rock! I really appreciate it... thank you very much

    0
    HyejunY
    HyejunY

    Question 6 weeks ago on Step 6

    I've
    followed the Step 5_1 but when I clicked the right mouse the Arduino Leonardo,
    there is no "game controller settings' on my list. So I could not set Game
    Controller Settings.

    0
    mohd8khd88
    mohd8khd88

    2 months ago

    hi .....i load the library of joystick with 32 buttons and
    • 32 buttons
    • throttle and rudder
    • X and Y Axis
    • Z Axis
    • 2 Hat Switches
    • X and Y Axis Rotation.......
    but it just make test i need to be operate as gamepad i need to wire it to leonardo...the code jus make test ....i dont know wahat i have to do to make it work on full function not test function
    0
    Pietrogramma
    Pietrogramma

    3 months ago

    Hi, thanks for sharing your project...in your article you wrote "While this dialog has focus, ground pin A0 on the Arduino to activate the test script", how I must ground PIN 0? I uploaded your sketch in the Micro Arduino, I see the peripheric "Arduino Micro" in the "control Panel", but the axis and buttons don't work. Thanks and ciao

    0
    clabit73
    clabit73

    Question 4 months ago

    Hi,

    I built a joystick with 16 buttons and 4 axes
    everything works in the windows control panel, buttons, axis x, axis y, throttle and rudder
    in the game does not see axis (configuration does not associate).
    can you help me?

    [code]
    #include <Keypad.h>
    #include <Joystick.h>

    #define ENABLE_PULLUPS

    #define NUMBUTTONS 16
    #define NUMROWS 4
    #define NUMCOLS 4

    int X1 = A0;
    int Y1 = A1;
    int rudder = A2;
    int throttle = A3;

    byte buttons[NUMROWS][NUMCOLS] = {
    {0, 1, 2, 3},
    {4, 5, 6, 7},
    {8, 9, 10, 11},
    {12, 13, 14, 15},
    };

    byte rowPins[NUMROWS] = {6, 7, 8, 9};
    byte colPins[NUMCOLS] = {2, 3, 4, 5};

    Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);

    Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 16, 0,
    true, true, false, false, false, false, true, true, false, false, false);

    void setup() {
    Joystick.begin();
    Joystick.setXAxisRange(-512, 512);
    Joystick.setYAxisRange(-512, 512);
    Joystick.setRudderRange(0, 1023);
    Joystick.setThrottleRange(0, 1023);
    }

    void JButtonStates() {
    Joystick.setXAxis(analogRead(X1) - 512);
    Joystick.setYAxis(analogRead(Y1) - 512);
    Joystick.setRudder(analogRead(rudder));
    Joystick.setThrottle(analogRead(throttle));
    }

    void loop() {
    JButtonStates();
    delay(50);
    CheckAllButtons();
    }

    void CheckAllButtons(void)
    {
    if (buttbx.getKeys())
    {
    for (int i = 0; i < LIST_MAX; i++)
    {
    if ( buttbx.key[i].stateChanged )
    {
    switch (buttbx.key[i].kstate)
    {
    case PRESSED:
    case HOLD:
    Joystick.setButton(buttbx.key[i].kchar, 1);
    break;
    case RELEASED:
    case IDLE:
    Joystick.setButton(buttbx.key[i].kchar, 0);
    break;
    }
    }
    }
    }
    }

    [/code]

    0
    j4ck4
    j4ck4

    Question 11 months ago on Introduction

    I continue to get an error upon trying to compile
    I’m trying to replace pro micro atmega32u4 for an 18 speed shifter with jake brake for ats.

    image.jpg
    0
    LIVEY3
    LIVEY3

    3 years ago

    32button hardware mappings Leonardo schematic?

    0
    costajules1
    costajules1

    Reply 1 year ago

    Good question, and conspicuously absent in the above article. You have a maximum of 14 digital pins on the Leonardo / Micro and a few analog pins which can naturally also be used as digital pins, providing a total of about 20 individual pins. 2 of the digital pins are also SDA and SCK of the I2C bus, which you can use to communicate to a port expander IC such as the MCP23017 (http://ww1.microchip.com/downloads/en/devicedoc/20001952c.pdf) which will add 16 more I/O's (also with pullup capability) so you end up with about 34 pins which you can read. The port expanders have individual addresses so you can add up to 8 of them, each giving 16 more inputs.

    0
    LIVEY3
    LIVEY3

    Reply 1 year ago

    I just saw the comments.
    Thank you so much.
    Let's try. Thank you.

    0
    minecraft0
    minecraft0

    1 year ago

    I would like to add an analogue signal from a steering potentiometer but I do not know how to do it you could help me

    0
    ChrisW425
    ChrisW425

    Reply 1 year ago

    next to the axises you mean? That would require chaning the library a bit i quess...

    0
    ChrisW425
    ChrisW425

    1 year ago

    I've edited the source files so that there are 4 joysticks with only buttons working (lightweight), I'm currently doing a project in which I make 4 wireless arcade controllers that will be send to a host node which creates 4 joysticks. The thing is that I wanted each controller recognized seperately and that I needed 16 buttons per controller. Your instructions helped a lot for this project. Thank you