Hi, I'm making a usb gamepad with dpad and 4 buttons using the Joystick library, all buttons are running through a 4021 shift register, on an Arduino Pro Micro.
As you can see below, I've basically combined the shift register example from here:(Parallel to Serial Shifting-In with a CD4021BE | Arduino) with the Joystick example for a gamepad, adding a few more buttons.
I'm testing my results through my laptop's game controller properties.
My issue is that while the additional buttons work, the laptop won't recognize the Dpad buttons. If I change the Joystick settings to be no xAxis or yAxis and just 8 buttons, they all are recognized. Also, when I initially tried the Joystick example with buttons on pins my laptop recognized it as the dpad.
Another issue is that when I jiggle the latch, clock, and data wires, the laptop's dpad recognition DID move. Changing which pins I used didn't fix this.
Any thoughts?
//Shift Register Shit:
int clockPin = 7;
int latchPin = 8;
int dataPin = 9;
byte switchVar1 = 72;
char note2sing[] = {
'R', 'L', 'D', 'U', 'T', 'E', 'B', 'A'};
//Joystick Shit:
#include <Joystick.h>
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
4, 0, // Button Count, Hat Switch Count
true, true, false, // X and Y, but no Z Axis
false, false, false, // No Rx, Ry, or Rz
false, false, // No rudder or throttle
false, false, false); // No accelerator, brake, or steering
void setup() {
Serial.begin(9600);
//Shift Register Setup:
pinMode(latchPin, OUTPUT);
pinMode(clockPin, OUTPUT);
pinMode(dataPin, INPUT);
//Joystick Setup:
Joystick.begin();
Joystick.setXAxisRange(-1, 1);
Joystick.setYAxisRange(-1, 1);
}
//Joystick: Last state of the buttons
int lastButtonState[8] = {0,0,0,0,0,0,0,0};
void loop() {
//Shift Register get data:
digitalWrite(latchPin,1);
delayMicroseconds(20);
digitalWrite(latchPin,0);
switchVar1 = shiftIn(dataPin, clockPin);
//switchVar1 = ~switchVar1; //THIS IS THE SHIT THAT INVERTS THE BUTTON PRESS
//Serial for debugging
// Serial.println(switchVar1, BIN);
// for (int n=0; n<=7; n++)
// {
// if (switchVar1 & (1 << n) ){
// Serial.println(note2sing[n]);
// }
// }
//Serial.println("-------------------");
//delay(500);
//Joystick assign buttons
Joystick.setButton(0, !bitRead(switchVar1, 7));
Joystick.setButton(1, !bitRead(switchVar1, 6));
Joystick.setButton(2, !bitRead(switchVar1, 5));
Joystick.setButton(3, !bitRead(switchVar1, 4));
Joystick.setButton(4, !bitRead(switchVar1, 3));
Joystick.setButton(5, !bitRead(switchVar1, 2));
Joystick.setButton(6, !bitRead(switchVar1, 1));
Joystick.setButton(7, !bitRead(switchVar1, 0));
//Joystick do Joystick shit
for (int index = 0; index < 8; index++)
{
int currentButtonState = !digitalRead(index + 4);
if (currentButtonState != lastButtonState[index])
{
switch (index) {
case 0: // UP
if (currentButtonState == 1) {
Joystick.setYAxis(-1);
} else {
Joystick.setYAxis(0);
}
break;
case 1: // RIGHT
if (currentButtonState == 1) {
Joystick.setXAxis(1);
} else {
Joystick.setXAxis(0);
}
break;
case 2: // DOWN
if (currentButtonState == 1) {
Joystick.setYAxis(1);
} else {
Joystick.setYAxis(0);
}
break;
case 3: // LEFT
if (currentButtonState == 1) {
Joystick.setXAxis(-1);
} else {
Joystick.setXAxis(0);
}
break;
case 4: // FIRE
Joystick.setButton(0, currentButtonState);
break;
case 5: //
Joystick.setButton(1, currentButtonState);
break;
case 6: //
Joystick.setButton(2, currentButtonState);
break;
case 7: //
Joystick.setButton(3, currentButtonState);
break;
}
lastButtonState[index] = currentButtonState;
}
}
}
byte shiftIn(int myDataPin, int myClockPin) {
int i;
int temp = 0;
int pinState;
byte myDataIn = 0;
pinMode(myClockPin, OUTPUT);
pinMode(myDataPin, INPUT);
for (i=7; i>=0; i--)
{
digitalWrite(myClockPin, 0);
delayMicroseconds(0.2);
temp = digitalRead(myDataPin);
if (temp) {
pinState = 1;
myDataIn = myDataIn | (1 << i);
}
else {
pinState = 0;
}
digitalWrite(myClockPin, 1);
}
return myDataIn;
}