Code works, but not in game

Hi,

I had created a post here the other day because my code was not working right, since then that is fixed, but the game controller does not 100% function in game. All of the buttons work, but the mini arduino joystick is not being recognized in the game, but is in the "set up USB game controller".

Below is the code that is currently on the Pro Micro. Any help would be appreciated

#include <Keypad.h>
#include <Joystick.h>

//DEFINITIONS
#define ENABLE_PULLUPS
#define NUMROTARIES 1 //replace "?" with number of rotary encoders you are using
#define NUMBUTTONS 6 //replace "?"with number of buttong you are using
#define NUMROWS 3 //replace "?" with number of rows you have
#define NUMCOLS 2 //replace "?" with number of columns you have 
int buttonPin = 14;

//BUTTON MATRIX
//first change number of rows and columns to match your button matrix, 
//then replace all "?" with numbers (starting from 0)
byte buttons[NUMROWS][NUMCOLS] = {
  {1,2},
  {3,4},
  {5,6}
  
};

struct rotariesdef {
  byte pin1;
  byte pin2;
  int ccwchar;
  int cwchar;
  volatile unsigned char state;
};

//ROTARY ENCODERS
//each line controls a different rotary encoder
//the first two numbers refer to the pins the encoder is connected to 
//the second two are the buttons each click of the encoder wil press 
//do NOT exceed 31 for the final button number
rotariesdef rotaries[NUMROTARIES] {
  {0,1,22,23,0}, //rotary 1

};

#define DIR_CCW 0x10
#define DIR_CW 0x20
#define R_START 0x0

#ifdef HALF_STEP
#define R_CCW_BEGIN 0x1
#define R_CW_BEGIN 0x2
#define R_START_M 0x3
#define R_CW_BEGIN_M 0x4
#define R_CCW_BEGIN_M 0x5
const unsigned char ttable[6][4] = {
  // R_START (00)
  {R_START_M,            R_CW_BEGIN,     R_CCW_BEGIN,  R_START},
  // R_CCW_BEGIN
  {R_START_M | DIR_CCW, R_START,        R_CCW_BEGIN,  R_START},
  // R_CW_BEGIN
  {R_START_M | DIR_CW,  R_CW_BEGIN,     R_START,      R_START},
  // R_START_M (11)
  {R_START_M,            R_CCW_BEGIN_M,  R_CW_BEGIN_M, R_START},
  // R_CW_BEGIN_M
  {R_START_M,            R_START_M,      R_CW_BEGIN_M, R_START | DIR_CW},
  // R_CCW_BEGIN_M
  {R_START_M,            R_CCW_BEGIN_M,  R_START_M,    R_START | DIR_CCW},
};
#else
#define R_CW_FINAL 0x1
#define R_CW_BEGIN 0x2
#define R_CW_NEXT 0x3
#define R_CCW_BEGIN 0x4
#define R_CCW_FINAL 0x5
#define R_CCW_NEXT 0x6

const unsigned char ttable[7][4] = {
  // R_START
  {R_START,    R_CW_BEGIN,  R_CCW_BEGIN, R_START},
  // R_CW_FINAL
  {R_CW_NEXT,  R_START,     R_CW_FINAL,  R_START | DIR_CW},
  // R_CW_BEGIN
  {R_CW_NEXT,  R_CW_BEGIN,  R_START,     R_START},
  // R_CW_NEXT
  {R_CW_NEXT,  R_CW_BEGIN,  R_CW_FINAL,  R_START},
  // R_CCW_BEGIN
  {R_CCW_NEXT, R_START,     R_CCW_BEGIN, R_START},
  // R_CCW_FINAL
  {R_CCW_NEXT, R_CCW_FINAL, R_START,     R_START | DIR_CCW},
  // R_CCW_NEXT
  {R_CCW_NEXT, R_CCW_FINAL, R_CCW_BEGIN, R_START},
};
#endif

//BUTTON MATRIX PART 2
byte rowPins[NUMROWS] = {A0,A1,A2}; //change "?" to the pins the rows of your button matrix are connected to
byte colPins[NUMCOLS] = {2,3}; //change "?" to the pins the rows of your button matrix are connected to

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);

//JOYSTICK SETTINGS
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,
  JOYSTICK_TYPE_JOYSTICK,
  32, //number of buttons
  0, //number of hat switches
  //Set as many axis to "true" as you have potentiometers for
  true, // y axis
  true, // x axis
  false, // z axis
  false, // rx axis
  false, // ry axis
  false, // rz axis
  false, // rudder
  false, // throttle
  false, // accelerator
  false, // brake
  false); // steering wheel

const int numReadings = 20;
 
int readings[numReadings];      // the readings from the analog input
int index = 0;              // the index of the current reading
int total = 0;                  // the running total
int currentOutputLevel = 0;

//POTENTIOMETERS PART 1
//add all the axis' which are enabled above
int yAxis_ = 0;
int xAxis_ = 0;  

               
//POTENTIOMETERS  PART 2
//Which pins are your potentiometers connected to?
int potentiometerPin1 = 10; //Change "?" to the pin your potentiometer is connected to
int potentiometerPin2 = 9;
const bool initAutoSendState = true;


void setup() {
  Joystick.begin();
  rotary_init();
  for (int thisReading = 0; thisReading < numReadings; thisReading++) {
    readings[thisReading] = 0;
  }

    // Initialize the button pin as an input with a pull-up resistor
  pinMode(buttonPin, INPUT_PULLUP);
  
  // Initialize the joystick object with the appropriate number of buttons
  //Joystick.begin(1);
  
}

void loop() {

  CheckAllEncoders();
  CheckAllButtons();
  CheckAllPotentiometers();

    // Read the button state
  int buttonState = digitalRead(buttonPin);

  // If the button is pressed, set the joystick button to be pressed
  if (buttonState == LOW) {
    Joystick.setButton(0, true);
  } else {
    Joystick.setButton(0, false);
  }


  // Send the updated joystick state to the computer
  Joystick.sendState();

  // Wait a short delay before repeating the loop
  delay(10);
}
 


//POTENTIOMETERS PART 3
//change the details to match the details above for each potentiometer you are using
void CheckAllPotentiometers(){
                           
  //potentiometer 1
  currentOutputLevel = getAverageOutput(potentiometerPin1);
  yAxis_ = map(currentOutputLevel,1023,0,0,255);
  Joystick.setYAxis(yAxis_); 

  //potentiometer 2
  currentOutputLevel = getAverageOutput(potentiometerPin2);
  xAxis_ = map(currentOutputLevel,0,1023,0,255);
  Joystick.setXAxis(xAxis_);


}

int getAverageOutput(int pinToRead){
  index = 0;
  total = 0; 
 
  while (index < numReadings){
    readings[index] = analogRead(pinToRead);
    total = total + readings[index];
    index = index + 1;
    //delay (1);
  }
  return total / numReadings;
}


void CheckAllButtons(void) {
      if (buttbx.getKeys())
    {
       for (int i=0; i<LIST_MAX; i++)   
        {
           if ( buttbx.key[i].stateChanged )   
            {
            switch (buttbx.key[i].kstate) { 
                    case PRESSED:
                    case HOLD:
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              break;
                    case RELEASED:
                    case IDLE:
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;
            }
           }   
         }
     }
}


void rotary_init() {
  for (int i=0;i<NUMROTARIES;i++) {
    pinMode(rotaries[i].pin1, INPUT);
    pinMode(rotaries[i].pin2, INPUT);
    #ifdef ENABLE_PULLUPS
      digitalWrite(rotaries[i].pin1, HIGH);
      digitalWrite(rotaries[i].pin2, HIGH);
    #endif
  }
}


unsigned char rotary_process(int _i) {
  //Serial.print("Processing rotary: ");
  //Serial.println(_i);
  unsigned char pinstate = (digitalRead(rotaries[_i].pin2) << 1) | digitalRead(rotaries[_i].pin1);
  rotaries[_i].state = ttable[rotaries[_i].state & 0xf][pinstate];
  return (rotaries[_i].state & 0x30);
}

void CheckAllEncoders(void) {
  Serial.println("Checking rotaries");
  for (int i=0;i<NUMROTARIES;i++) {
    unsigned char result = rotary_process(i);
    if (result == DIR_CCW) {
      Serial.print("Rotary ");
      Serial.print(i);
      Serial.println(" <<< Going CCW");
      Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
    };
    if (result == DIR_CW) {
      Serial.print("Rotary ");
      Serial.print(i);
      Serial.println(" >>> Going CW");
      Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
    };
  }
  Serial.println("Done checking");
}

If you've been around, you would know you need to post a schematic.

The code works, the computer recognizes the motion, the game does not. How a schematic going to help with that? Everything is wired correctly and coded to match.

It would help us understand the hardware references in the code. I'm putting you on my permanent ignore list since you have your own ideas about how we are supposed to solve the problem.

2 Likes

If the code works, the computer recognizes the motion but the game doesn't, we can't help you, contact the game's technical support.

Regards

2 Likes

As requested

this is very wierdest art to scan pressed keys i ever seen in gamepad sketches.
UPD. to be not offtopic i can recommend MMjoy2 or NikoHood projects

Does the sketch not provide enough information for you? Everything is connected as it is IRL

i meant, i don't like this block.

say, you has only 7 buttons, there is enough pins, why you try to build a button matrix?

try this example

// Simple gamepad example that demonstraits how to read five Arduino
// digital pins and map them to the Arduino Joystick library.
//
// The digital pins 2 - 6 are grounded when they are pressed.
// Pin 2 = UP
// Pin 3 = RIGHT
// Pin 4 = DOWN
// Pin 5 = LEFT
// Pin 6 = FIRE
//
// NOTE: This sketch file is for use with Arduino Leonardo and
//       Arduino Micro only.
//
// by Matthew Heironimus
// 2016-11-24
//--------------------------------------------------------------------

#include <Joystick.h>

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID,JOYSTICK_TYPE_GAMEPAD,
  1, 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() {
  // Initialize Button Pins
  pinMode(2, INPUT_PULLUP);
  pinMode(3, INPUT_PULLUP);
  pinMode(4, INPUT_PULLUP);
  pinMode(5, INPUT_PULLUP);
  pinMode(6, INPUT_PULLUP);

  // Initialize Joystick Library
  Joystick.begin();
  Joystick.setXAxisRange(-1, 1);
  Joystick.setYAxisRange(-1, 1);
}

// Last state of the buttons
int lastButtonState[5] = {0,0,0,0,0};

void loop() {

  // Read pin values
  for (int index = 0; index < 5; index++)
  {
    int currentButtonState = !digitalRead(index + 2);
    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;
      }
      lastButtonState[index] = currentButtonState;
    }
  }

  delay(10);
}

You don't like it or you think it might be the reason why the game is not recognizing the joystick?

Just an additional note, I did mess with the dead zones and sensitivities of the x and y axis in the game, still nothing

yes, not like, this code is work, i know, but can't help me. nevermind.

i made some joysticks, gamepad and racing wheel. and some game need to be calibrated on a particular device, for example Europa Track Simulator.
if device working in "Windows joystick check" then problem is in the game itself.
but if not, maybe other HID libraries do.

This was a great idea, I started up ETS and the joystick works fine in that game. So the problem is game specific. Does not help me with my problem, but is helpful. Thanks

i using Xpadder program, it let me to store long(or not) key sequences and to send in game by gamepad button pressing

So I got the joystick to work in game with a different code, but now I am having trouble that the button matrix does not get recognized. I made a separate code to focus on the joystick, got it working and combined what was needed... but I must have missed something for the matrix. Do you see anything that I missed?

#include <Keypad.h>
#include <Joystick.h>

#define joyX A10
#define joyY A9
#define joyButton1 14
#define ENABLE_PULLUPS
#define NUMBUTTONS 6
#define NUMROWS 3
#define NUMCOLS 2 
int xAxis_ = 0; 
int yAxis_ = 0;  
int lastButton1State = 0;

//BUTTON MATRIX

byte buttons[NUMROWS][NUMCOLS] = {
  {1,2},
  {3,4},
  {5,6}
  
};

byte rowPins[NUMROWS] = {A0,A1,A2};
byte colPins[NUMCOLS] = {2,3};

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);



Joystick_ Joystick(0x03, 0x04, 1, 0,true,true,false,false,false,false,false,false,false,false,false);

const bool initAutoSendState = true;

void setup() {
    Serial.begin(9600);
  pinMode(joyButton1, INPUT_PULLUP);

  Joystick.begin();
}

void loop() {

int rawX, rawY, outputX, outputY;
  rawX = analogRead(A9);
  outputX = rawX;  
 Joystick.setXAxis(outputX); 
  
  rawY = analogRead(A10);
  outputY = map(rawY, 0, 1023, 1023, 0);
 Joystick.setYAxis(outputY);


  int currentButton1State = !digitalRead(joyButton1);
  if (currentButton1State != lastButton1State){
    Joystick.setButton(0, currentButton1State);
    lastButton1State = currentButton1State;
  }

delay(10);
}

or you are trying to use something that doesn't exist. You said it's a Micro Pro, so how many analog inputs are on this board?

What you changed had to do with the joystick, which was working fine. Your optimization makes sense, but does not change anything with the button matrix.

#include <Keypad.h>
#include <Joystick.h>

#define joyButton1 14
#define NUMROWS 3
#define NUMCOLS 2

char buttons[NUMROWS][NUMCOLS] = {
  {'1', '2'},
  {'3', '4'},
  {'5', '6'}
};

byte rowPins[NUMROWS] = {11, 12, 13};
byte colPins[NUMCOLS] = {2, 3};

Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS);
Joystick_ Joystick(0x03, JOYSTICK_TYPE_JOYSTICK, 7, 0, true, true, false, false, false, false, false, false, false, false, false);

void setup() {
  pinMode(joyButton1, INPUT_PULLUP);
  Joystick.begin(false);
}

void loop() {
  Keypad.getKeys();
  Joystick.setXAxis(analogRead(A0));
  Joystick.setYAxis(1024 - analogRead(A1));
  Joystick.setButton(0, !digitalRead(joyButton1));
  for (char i = '1'; i <= '6'; i++)Joystick.setButton(i - '0',  Keypad.isPressed(i));

  Joystick.sendState();
  delay(10);
}

you have to change your connecting wires according to what is written in the sketch

I don’t understand why, it worked fine before with how the connecting wires are