Problem while writing code for diy HID Arduino Gamepad

118 Views Asked by At

Hello there I'm trying to create a diy HID Gamepad that I will later integrate into something bigger, using the Arduino Pro Micro but I'm new to Arduino/MCUs development/programming, I trying to create a gamepad with a 4x4 buttons matrix and two Azoteq TPS43-201A-S Capacitive Trackpads which use the Azoteq IQS570 Capacitive touch controller, and I'm not sure if I wrote the code for the matrix right and I have no idea how to write code for the trackpad, here is how far I came with the code.



#include <Keypad.h>
#include <Gamepad.h>

// Define the 4x4 button matrix
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'Y', 'X', 'B', 'A'},
  {'LEFT', 'RIGHT', 'UP', 'DOWN'},
  {'LB', 'RB', 'SE', 'MU'},
  {'JL', 'JR', 'E1', 'E2'}
};

// Define the pin numbers for the rows and columns of the matrix
byte rowPins[ROWS] = {9, 8, 7, 6}; // Row pins are connected to Arduino pins 9, 8, 7, 6
byte colPins[COLS] = {5, 4, 3, 2}; // Column pins are connected to Arduino pins 5, 4, 3, 2

Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Gamepad gp;

void setup() {
  for (byte i = 0; i < ROWS; i++) {
    pinMode(rowPins[i], INPUT_PULLUP);
  }

  for (byte i = 0; i < COLS; i++) {
    pinMode(colPins[i], INPUT_PULLUP);
  }

  pinMode(A0, INPUT); //right stick y-axis
  pinMode(A1, INPUT); //right stick x-axis
  pinMode(A2, INPUT); //left stick y-axis
  pinMode(A3, INPUT); //left stick x-axis
  pinMode(A4, INPUT); //left trigger
  pinMode(A5, INPUT); //right trigger

  calibrate();
}

void loop() {
  int rt, lt, lx, ly, rx, ry;

  rt = analogRead(A5);
  lt = analogRead(A4);
  lx = analogRead(A3);
  ly = analogRead(A2);
  rx = analogRead(A1);
  ry = analogRead(A0);

  // Convert 0-1000 to -127 - 127
  rt = floor((rt - rightTcenter) * multiplierRT);
  lt = floor((lt - leftTcenter) * multiplierLT);
  lx = floor((lx - leftXcenter) * multiplierLX);
  ly = floor((ly - leftYcenter) * multiplierLY);
  rx = floor((rx - rightXcenter) * multiplierRX);
  ry = floor((ry - rightYcenter) * multiplierRY);

  if (rt > 127) rt = 127;
  if (lt > 127) lt = 127;
  if (lx > 127) lx = 127;
  if (ly > 127) ly = 127;
  if (rx > 127) rx = 127;
  if (ry > 127) ry = 127;

  gp.setRightTaxis(rt);
  gp.setLeftTaxis(lt);
  gp.setLeftXaxis(lx);
  gp.setRightXaxis(rx);
  gp.setLeftYaxis(ly);
  gp.setRightYaxis(ry);

  char key = keypad.getKey();

  if (key) {
    handleButtonPress(key);
  }

  delay(20);
}

void handleButtonPress(char button) {
  for (byte row = 0; row < ROWS; row++) {
    for (byte col = 0; col < COLS; col++) {
      if (button == keys[row][col]) {
        if (digitalRead(rowPins[row]) == LOW && digitalRead(colPins[col]) == LOW) {
          gp.setButtonState(row * COLS + col, true);
        } else {
          gp.setButtonState(row * COLS + col, false);
        }
      }
    }
  }
}

int rightTcenter = 500;
int leftTcenter = 500;
int rightXcenter = 500;
int rightYcenter = 500;
int leftXcenter = 500;
int leftYcenter = 500;
double multiplierRT = 0.254; //127 / 500
double multiplierLT = 0.254;
double multiplierRX = 0.254;
double multiplierRY = 0.254;
double multiplierLX = 0.254;
double multiplierLY = 0.254;

void calibrate() {
  int rt, lt, lx, ly, rx, ry;
  int i = 0;
  while (i < 13) {
    rt = analogRead(A5);
    lt = analogRead(A4);
    lx = analogRead(A3);
    ly = analogRead(A2);
    rx = analogRead(A1);
    ry = analogRead(A0);
    bool validRT = rt > (rightTcenter - 100) && rt < (rightTcenter + 100);
    bool validLT = lt > (leftTcenter - 100) && lt < (leftTcenter + 100);
    bool validLX = lx > (leftXcenter - 100) && lx < (leftXcenter + 100);
    bool validLY = ly > (leftYcenter - 100) && ly < (leftYcenter + 100);
    bool validRX = rx > (rightXcenter - 100) && rx < (rightXcenter + 100);
    bool validRY = ry > (rightYcenter - 100) && ry < (rightYcenter + 100);
    if (validRT && validLT && validLX && validLY && validRX && validRY) {
      i++;
      //nothing to do here!
    } else
      i = 0;
    delay(20);
  }
  rightTcenter = rt;
  leftTcenter = lt;
  leftXcenter = lx;
  leftYcenter = ly;
  rightXcenter = rx;
  rightYcenter = ry;
  multiplierRT = (double)127 / (double)rt;
  multiplierLT = (double)127 / (double)lt;
  multiplierLX = (double)127 / (double)lx;
  multiplierLY = (double)127 / (double)ly;
  multiplierRX = (double)127 / (double)rx;
  multiplierRY = (double)127 / (double)ry;
}



I tried giving each button a pin, but there weren't enough pins. So, I switched to a matrix. I also tried searching online to find information about the TPS43-201A-S or the IQS570, but it looks like nobody knows anything except two or three people – one of them on Reddit. However, he used the trackpad with Linux, while I'm trying to use it with an Arduino Pro Micro.

1

There are 1 best solutions below

2
brhans On
  1. You've unnecessarily duplicated your array of key names in keys and matrixKeys (minor issue, not the cause of your trouble)

  2. You're passing char button as the parameter to your handleButtonPress function, and then inside that function you're comparing it to elements of your (duplicate) matrixKeys array. That will never work - your matrixKeys is an array of string pointers, so comparing those to a char will never result in a match.

It appears that you're also using the Arduino Keypad library incorrectly.
The documentation here seems to imply that you're supposed to initialize it with an array of chars, not an array of string pointers as you've done.
So your keys[ROWS][COLS] should be initialized with something more like:

{
  {'Y', 'X', 'B', 'A'},
  {'L', 'R', 'U', 'D'},
  {'1', '2', '3', '4'},
  {'5', '6', '7', '8'}
};

Feel free to replace the 1 thru 8 digits with something more meaningful for you, as long as they stay single characters.
Then inside handleButtonPress there's no need to declare a new array containing the same set of char elements, just reference keys.