Arduino Leonardo/Micro As Game Controller/Joystick

158,330

128

182

Intro: 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

Share

    Recommendations

    • Electronics Tips & Tricks Challenge

      Electronics Tips & Tricks Challenge
    • Plastics Contest

      Plastics Contest
    • Audio Contest 2018

      Audio Contest 2018

    182 Discussions

    0
    None
    shearder

    Question 2 months ago on Step 10

    what code is required to enable or use a button matrix? which are the input pins for the matrix?

    Thanks in advance.

    0
    None
    glascocka2019

    Question 7 months ago on Step 10

    How id the Joystick hooked up to an Arduino Leonardo I can t get it to work I don't know which ports to plug the serial joystick into

    1 more answer
    0
    None
    jarwik

    9 months ago

    Hello, i am very new to arduino and i am building a buttonbox based on this youtube tutorial :

    The only difference i want to use a analog joystick with it and i will use the Arduino micro instead of the pro micro.

    The parts i have is a analog joystick, 4 rotary encoders EC11, and 16 momentary push buttons.

    would anyone be so kind to take a look if my wiring diagram is correct??

    Also i could need some help with the sketch, i have zero knowledge how to do this. I can build a lot of stuf with my hands, but programming goes far beyond my knowledge unfortunately.

    If anyone would make a sketch for me i'd be very happy.......

    Thnx in advance!

    Buttonbox V3.0_bb.jpg
    1 reply
    0
    None
    Álvaro1jarwik

    Reply 7 months ago

    Hi,

    I am new as well. I am trying to do the same, but without the encoders. Did you manage to fix the code? If you can post it it will be so helpful.

    Thanks.

    0
    None
    Frau Muster

    11 months ago

    Hello, I’m also using MHeironimous JoystickLibrary and got all my old "Gameport"-Joysticks working again at USB very successful using your tutorial. Many thanks!

    Now I’ve built another Arduino sketch using this library for my ProMicro to run it as Gamecontroller to control my flight simulator. Especially I want to use optical rotary encoders to simulate joystick buttons: each detent on the encoder should send a Joystick.pressButton(byte button).

    That works perfectly in the Serial Monitor and with LED flashes for each detent but as soon as I connect the ProMicro to my PC and choose Game Controller/Settings in Windows 10, not every „button press" is recognized in the Game Controller - sometimes only about one in two, sometimes only about one in more. That is not only when I’m rotating the encoder fast, it also appears by turning the encoder slowly detent by detent.

    Baud rate is 9600. Is it possible that the detent duration is too short? Or the pressButton rate is too high for the Game Controller? Don’t know how to solve the problem.

    Thank you in advance.
    Ed

    1 reply
    0
    None
    MatthewHFrau Muster

    Reply 7 months ago

    How often are you sampling your optical rotary encoders? I would recommend doing it every 50ms (i.e. 200 times a second).

    You may need to disable (comment out) your serial communication (or increase your baud rate to 57600).

    Hope you can get it working,
    Matt

    0
    None
    PabloH46

    Question 7 months ago

    Hi! nice job, I try to build a joy with Arduino UNO, and have a problem with the calibration, when xplane run popup message appear saying "new usb joystick and need to calibrate.." allways :(. In this proyect the calibration data is stored? It would not work for me if the calibration can not be saved. Thanks!!!

    1 more answer
    0
    None
    MatthewHPabloH46

    Answer 7 months ago

    What Operating System is running on the computer you are using?

    Joystick calibration is something the OS is doing (or maybe the program that is using the joystick), not something the Arduino is doing.

    0
    None
    unisev

    9 months ago

    Hello,

    Thank for this great library, working like a charm on Windows system.

    Unfortunately, my "homemade" gamepad is not recognised on RecalBox (Linux)...

    ...maybe should I update some code, or tweak the bootloader ??

    0
    None
    JasonG255

    1 year ago

    Thank you so much for this Instructable. How ever. Is there a
    tutorial that you know of that finishes it off with the coding and
    button schematics to full fill the 32 buttons and axes?.

    When I
    saw this I was looking for a DIY button controller. When I saw this it
    had enough buttons and axes for exactly what I wanted. I went and bought
    the Leo and a kit and a bunch of buttons. Got the Leo to work on
    Windows but now I am stuck and trying to find a way to wire 32 button
    and all the axes.

    Thanks for any replay you can provide. Thanks

    8 replies
    0
    None
    compactrhoneJasonG255

    Reply 1 year ago

    would making a switch matrix and using the keypad register work?

    0
    None
    itsGreyspotcompactrhone

    Reply 10 months ago

    I was able to use the keypad library with some modifications.

    When creating the key map use byte, instead of char:

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

    Then in the switch of the pressed keyes section pass the selected key to the joystick button:

    Joystick.setButton(kpd.key[i].kchar , 1);

    0
    None
    FrancescoG58itsGreyspot

    Reply 10 months ago

    Could you elaborate on that last part? About passing the selected key to the joystick button? That's the part I'm stuck on...

    0
    None
    itsGreyspotFrancescoG58

    Reply 10 months ago

    I mashed examples together and came up with this. The keypad library figures out what's being pressed, then iterates through the array of pressed buttons. I am on my phone so I can't see line numbers. Hopefully it helps.


    https://github.com/itsGreyspot/ButtonBox/blob/master/ButtonBox.ino

    0
    None
    StarcitizenModderMatthewH

    Reply 1 year ago

    is buying a teensy board easier? lol i would have to lean more on shift registers. i only know a little.

    0
    None
    MatthewHStarcitizenModder

    Reply 1 year ago

    Any Arduino compatible board based on the ATmega32u4 should work. That being said, I personally have only tested using the Arduino Micro and Arduino Leonardo. I try to keep the list of "supported" board up to date on the GitHub repository (https://github.com/MHeironimus/ArduinoJoystickLibrary). Based on the Teensy website (https://www.pjrc.com/teensy/), it seems like the Teensy 2.0 should work, but I am not sure about the others (Teensy++ 2.0, Teensy 3.0, Teensy 3.1, etc.) since they have different microprocessors. If you do try the library with a Teensy, let me know if it works or not. Thanks.

    0
    None
    StarcitizenModderJasonG255

    Reply 1 year ago

    cracked it? its not beyond you trust me. if you haven't just take an hour out your day to look over the code that Matthew wrote and you'll be able to work out where to squeeze your buttons. ill be doing arduino tutorials on my channel soon sub

    0
    None
    charleslinquist

    12 months ago

    Matthew,

    I downloaded the "Multiple Joystick Test" from GitHub and installed the Joystick library. It shows up in my list of libraries. When I try to compile for Leonardo, I get the messages:

    "MultipleJoystickTest:14: error: 'Joystick_' does not name a type

    Joystick_ Joystick[JOYSTICK_COUNT] = {

    C:\Users\Charles\Documents\ArduinoJoystick\MultipleJoystickTest\MultipleJoystickTest.ino: In function 'void testSingleButtonPush(int, unsigned int)':

    MultipleJoystickTest:36: error: 'Joystick' was not declared in this scope

    Joystick[joystickId].releaseButton(button - 1);

    MultipleJoystickTest:40: error: 'Joystick' was not declared in this scope

    Joystick[joystickId].pressButton(button);

    C:\Users\Charles\Documents\ArduinoJoystick\MultipleJoystickTest\MultipleJoystickTest.ino: In function 'void testMultiButtonPush(int, unsigned int)':

    MultipleJoystickTest:52: error: 'Joystick' was not declared in this scope

    What could be wrong?