Teensy gamepad code

General GBZ-related chat goes here. Share ideas, tips and tricks, or ask questions that don't fit into the hardware/software help forums.
Post Reply
User avatar
hencethus
Posts: 27
Joined: Thu May 05, 2016 9:20 am
Been thanked: 4 times

Teensy gamepad code

Post by hencethus » Sat May 28, 2016 10:03 pm

I wanted my buttons to be recognized as a gamepad rather than triggers for keyboard events, so I got it working with this code. It's mostly just example code from Teensyduino, but I did make some modifications, including some extra code to get the d-pad to work as a hat switch. The inputs are in the order of helder's button PCB. I don't think there's probably any practical advantage to this over keyboard events, but I like it better. I don't really write C code, so this could probably use some refactoring, but it works.

Code: Select all

/* Modified example code from Teensyduino
   You must select Joystick from the "Tools > USB Type" menu
*/

#include <Bounce.h>

// Create Bounce objects for each button. The Bounce object
// automatically deals with contact chatter or "bounce", and
// it makes detecting changes very simple.
  Bounce GBZ_LEFT = Bounce(0, 10);
  Bounce GBZ_UP = Bounce(1, 10);  // 10 = 10 ms debounce time
  Bounce GBZ_DOWN = Bounce(2, 10);  // which is appropriate for
  Bounce GBZ_RIGHT = Bounce(3, 10);  // most mechanical pushbuttons
  Bounce GBZ_SELECT = Bounce(4, 10);
  Bounce GBZ_START = Bounce(5, 10);
  Bounce GBZ_X = Bounce(6, 10);
  Bounce GBZ_Y = Bounce(7, 10);
  Bounce GBZ_B = Bounce(8, 10);
  Bounce GBZ_A = Bounce(9, 10);
  Bounce GBZ_L = Bounce(10, 10);
  Bounce GBZ_R = Bounce(11, 10);

  const int numButtons = 12;

  uint8_t hatu = 0;
  uint8_t hatr = 0;
  uint8_t hatd = 0;
  uint8_t hatl = 0;

  // ganked this bit from https://gist.github.com/cleure/5820004
  // bitwise operations return 4 possible states of each d-pad axis
  // so that d-pad value can be looked up from 4x4 array
  /*
  
          0
          UP
      315    45
 270 LT   -1   RT 90
      225    135
          DN
          180
  
  */
  int GetHatState() {
    uint8_t x, y;
    const static int16_t dpad_lookup[4][4] = {
      { -1, 270,  90, -1},
      {  0, 315,  45, -1},
      {180, 225, 135, -1},
      { -1,  -1,  -1, -1}
    };
    
    y = hatu | (hatd << 1);
    x = hatl | (hatr << 1);
    
    return dpad_lookup[y][x];
  }

void setup() {
  // Configure the pins for input mode with pullup resistors.
  // The pushbuttons connect from each pin to ground.  When
  // the button is pressed, the pin reads LOW because the button
  // shorts it to ground.  When released, the pin reads HIGH
  // because the pullup resistor connects to +5 volts inside
  // the chip.
  for (int i=0; i<numButtons; i++) {
    pinMode(i, INPUT_PULLUP);
  }
  
  //  Set all axes to defaults
  Joystick.X(512);
  Joystick.Y(512);
  Joystick.Z(512);
  Joystick.Zrotate(512);
  Joystick.sliderLeft(512);
  Joystick.sliderRight(512);
  Joystick.hat(-1);
}

void loop() {
  // Update all the buttons.  There should not be any long
  // delays in loop(), so this runs repetitively at a rate
  // faster than the buttons could be pressed and released.
  GBZ_LEFT.update();   // 0
  GBZ_UP.update();     // 1
  GBZ_DOWN.update();   // 2
  GBZ_RIGHT.update();  // 3
  GBZ_SELECT.update(); // 4
  GBZ_START.update();  // 5
  GBZ_X.update();      // 6
  GBZ_Y.update();      // 7
  GBZ_B.update();      // 8
  GBZ_A.update();      // 9
  GBZ_L.update();      // 10
  GBZ_R.update();      // 11

  // Check each button for "falling" edge.
  // Update the Joystick buttons only upon changes.

  if (GBZ_B.fallingEdge()) {
    Joystick.button(1, 1);
  }
  if (GBZ_A.fallingEdge()) {
    Joystick.button(2, 1);
  }
  if (GBZ_Y.fallingEdge()) {
    Joystick.button(3, 1);
  }
  if (GBZ_X.fallingEdge()) {
    Joystick.button(4, 1);
  }
  if (GBZ_L.fallingEdge()) {
    Joystick.button(5, 1);
  }
  if (GBZ_R.fallingEdge()) {
    Joystick.button(6, 1);
  }
  if (GBZ_SELECT.fallingEdge()) {
    Joystick.button(7, 1);
  }
  if (GBZ_START.fallingEdge()) {
    Joystick.button(8, 1);
  }
  if (GBZ_UP.fallingEdge()) {
    hatu = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_RIGHT.fallingEdge()) {
    hatr = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_DOWN.fallingEdge()) {
    hatd = 1;
    Joystick.hat(GetHatState());
  }
  if (GBZ_LEFT.fallingEdge()) {
    hatl = 1;
    Joystick.hat(GetHatState());
  }

  // Check each button for "rising" edge
  // Update the Joystick buttons only upon changes.

  if (GBZ_B.risingEdge()) {
    Joystick.button(1, 0);
  }
  if (GBZ_A.risingEdge()) {
    Joystick.button(2, 0);
  }
  if (GBZ_Y.risingEdge()) {
    Joystick.button(3, 0);
  }
  if (GBZ_X.risingEdge()) {
    Joystick.button(4, 0);
  }
  if (GBZ_L.risingEdge()) {
    Joystick.button(5, 0);
  }
  if (GBZ_R.risingEdge()) {
    Joystick.button(6, 0);
  }
  if (GBZ_SELECT.risingEdge()) {
    Joystick.button(7, 0);
  }
  if (GBZ_START.risingEdge()) {
    Joystick.button(8, 0);
  }
  if (GBZ_UP.risingEdge()) {
    hatu = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_RIGHT.risingEdge()) {
    hatr = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_DOWN.risingEdge()) {
    hatd = 0;
    Joystick.hat(GetHatState());
  }
  if (GBZ_LEFT.risingEdge()) {
    hatl = 0;
    Joystick.hat(GetHatState());
  }
}

murrman92
Posts: 2
Joined: Thu Nov 15, 2018 4:47 pm

Re: Teensy gamepad code

Post by murrman92 » Fri Nov 16, 2018 7:05 am

I just built my first GBZ and I used your code for my Teensy! I like that it registers as a gamepad instead of keyboard strokes as it makes it easier to navigate the RetroPie config menus. Did you have any trouble with buttons double tapping when you used this code?

George.p
Posts: 14
Joined: Thu Jan 25, 2018 11:04 pm

Re: Teensy gamepad code

Post by George.p » Mon Apr 29, 2019 2:24 pm

hi, how do you wire the analog joystick to the teensy? thanks a lot

User avatar
BlastoSupreme
Posts: 19
Joined: Mon Mar 26, 2018 1:29 pm
Has thanked: 6 times
Been thanked: 6 times

Re: Teensy gamepad code

Post by BlastoSupreme » Sun May 05, 2019 8:56 am

This is really neat! Thanks for putting in all the comments in the code. It really helps someone like me who has absolutely no idea what they're doing code wise. <3

Theconartist03
Posts: 9
Joined: Mon Apr 16, 2018 9:31 am

Re: Teensy gamepad code

Post by Theconartist03 » Sat Aug 03, 2019 11:19 am

My button pcb is the same layout but I wired it to the teensy as gnd, up, down, left, right, start, select, a, b, x, y. Will this code work for that.

User avatar
infinitLoop
Posts: 372
Joined: Mon Dec 24, 2018 11:46 am
Has thanked: 157 times
Been thanked: 126 times
Contact:

Re: Teensy gamepad code

Post by infinitLoop » Sat Aug 03, 2019 12:15 pm

Theconartist03 wrote:
Sat Aug 03, 2019 11:19 am
My button pcb is the same layout but I wired it to the teensy as gnd, up, down, left, right, start, select, a, b, x, y. Will this code work for that.
just link the pin (number) with the button in the script:

Bounce GBZ_X = Bounce(6, 10);

that links "X" button with pin 6 (with a 10 milisecond bounce)


.

Theconartist03
Posts: 9
Joined: Mon Apr 16, 2018 9:31 am

Re: Teensy gamepad code

Post by Theconartist03 » Sat Aug 03, 2019 7:04 pm

Do I also need to edit the update all the buttons, the falling edge or the rising edge?

Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest