Posted on 15 Comments

Arduino: USB Gamepad

/*
 * tinkerBOY's usb_gamepad v1.0
 * 
 */

#include <Joystick.h>

#define PINS 14
#define ENABLE_ANALOG1 false
int X1 = A0;
int Y1 = A1;

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

class CButton {
  public:
  int pin = NULL;
  int lastState = 0;
  
  CButton(int p) {
    pin = p;
  }
};

CButton Buttons[PINS] ={0,1,2,3,4,5,6,7,8,9,10,16,14,15};

void setup() {
  for(int i=0 ; i<PINS ;i++) {
    pinMode(Buttons[i].pin, INPUT_PULLUP);
  }

  Joystick.begin();
  if (ENABLE_ANALOG1) {
    Joystick.setXAxisRange(-512, 512);
    Joystick.setYAxisRange(-512, 512);
  }
}

void JButtonStates() {
  if (ENABLE_ANALOG1) {
    Joystick.setXAxis(analogRead(X1) - 512);
    Joystick.setYAxis(analogRead(Y1) - 512);
  }
  
  for (int i = 0; i < PINS; i++) {
    int currentState = !digitalRead(Buttons[i].pin);
    
    if (currentState != Buttons[i].lastState) {
      Joystick.setButton(i, currentState);
      Buttons[i].lastState = currentState;
    }
  }  
}

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

6-Button version:

/*
 * tinkerBOY's usb_gamepad v1.0 - 6-Button version
 * 
 */
 
#include <Joystick.h>

#define PINS 16
#define ENABLE_ANALOG1 false
int X1 = A0;
int Y1 = A1;

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

class CButton {
  public:
  int pin = NULL;
  int lastState = 0;
  
  CButton(int p) {
    pin = p;
  }
};

CButton Buttons[PINS] ={0,1,2,3,4,5,6,7,8,9,10,16,14,15,20,21};

void setup() {
  for(int i=0 ; i<PINS ;i++) {
    pinMode(Buttons[i].pin, INPUT_PULLUP);
  }

  Joystick.begin();
  if (ENABLE_ANALOG1) {
    Joystick.setXAxisRange(-512, 512);
    Joystick.setYAxisRange(-512, 512);
  }
}

void JButtonStates() {
  if (ENABLE_ANALOG1) {
    Joystick.setXAxis(analogRead(X1) - 512);
    Joystick.setYAxis(analogRead(Y1) - 512);
  }
  
  for (int i = 0; i < PINS; i++) {
    int currentState = !digitalRead(Buttons[i].pin);
    
    if (currentState != Buttons[i].lastState) {
      Joystick.setButton(i, currentState);
      Buttons[i].lastState = currentState;
    }
  }  
}

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

 

15 thoughts on “Arduino: USB Gamepad

  1. […] Run the software, create a new file, copy and paste the code from https://www.tinkerboy.xyz/arduino-usb-gamepad/. […]

  2. can you please post a wiring diagram from the microcrontoller to the button PCB?

    1. Which button PCB?

  3. What am I doing wrong here.
    The zip doesnt contain a valid library and the copied and pasted sketch wont verify

    its got to be me but i dont know what ive done

    Help!!!

  4. Does this program have functionality for L2 and R2?

    1. Yes.

  5. Getting the same thing here. I copied the sketch but when I tried adding the library by the add library button it says “Specified folder/zip file does not contain a invalid library” on 1.8.10 Arduino. When I added manually and check the program the ArduinoJoystick library is greyed out. Any advice or tips? Thanks.

    1. The zip fil must be unpacked first. A folder inside is the library, not the whole zip file. Copy the lib folder to where you have other livs.

  6. Hi. if using the arduino microcontroller with a gameboy button pcb what would be the wiring? thanks

  7. Could help me and write a program for x,y digital axis plus 2 fire buttons with simple rapidfire (arduino atari-like joystick)?

  8. […] the arduino sketch is the one I found HERE but I changed pin 16 to one of the analogue pins to get around my broken […]

  9. Currently I have my nintendo switch stick connect to 5pin .5mm pcb wired to v3 and i enabled with sudo minicom but my analog/joystick still doesnt work. Where do I add this or do i even use this?

  10. Can you post code that makes every input on the aruino a button input, even a3-a0?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.