Teensy gamepad code
Posted: 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());
}
}