Keypad matrix but with toggle switches?

since you all have been really helpful with my projects, i figured i would reach out. So not too long ago i was posting about a button box that i was making for simulators. Running an arduino lenardo pro micro and i have it programmed with a modified keypad matrix script that i found online. (ill have it below).

now the issue, the game sees the toggle switches as if im turning them on n off rapidly, however, windows shows it as normal, switch is turned on, button is light up on joystick manager. I wanted to use some toggles (as well as some momentary buttons) to mix it up, make it a bit more immersive, as not ever button/switch in a car or truck is a momentary thing.

is there anyway to change this behavior on this code?

i also dont use rotary switches on this box either. is that the part thats giving me the issue? i have 13 switches and 9 buttons in a matrix.

//BUTTON BOX 
//USE w ProMicro
//Tested in WIN10 + Assetto Corsa
//AMSTUDIO
//20.8.17

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

#define ENABLE_PULLUPS
#define NUMROTARIES 4
#define NUMBUTTONS 24
#define NUMROWS 5
#define NUMCOLS 5
Joystick_ Joystick;

byte buttons[NUMROWS][NUMCOLS] = {
  {0,1,2,3,4},
  {5,6,7,8,9},
  {10,11,12,13,14},
  {15,16,17,18,19},
  {20,21,22,23},
};

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

rotariesdef rotaries[NUMROTARIES] {
  {0,1,24,25,0},
  {2,3,26,27,0},
  {4,5,28,29,0},
  {6,7,30,31,0},
};

#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

byte rowPins[NUMROWS] = {21,20,19,18,15}; 
byte colPins[NUMCOLS] = {14,16,10,9,8}; 

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



void setup() {
  pinMode(A6, INPUT);
  Joystick.begin();
  }

const int pinToButtonMap = A6;

void loop() { 



  CheckAllEncoders();

  CheckAllButtons();

}

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) {
   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) {
  for (int i=0;i<NUMROTARIES;i++) {
    unsigned char result = rotary_process(i);
    if (result == DIR_CCW) {
      Joystick.setButton(rotaries[i].ccwchar, 1); delay(50); Joystick.setButton(rotaries[i].ccwchar, 0);
    };
    if (result == DIR_CW) {
      Joystick.setButton(rotaries[i].cwchar, 1); delay(50); Joystick.setButton(rotaries[i].cwchar, 0);
    };
  }
    int pot = analogRead(A6);
int mapped = map(pot,0,1023,0,255);
{Joystick.setThrottle(mapped);
}}

How is your matrix wired, I assume you use have diodes if the toggles work as expected anywhere.

And what exactly happens when you switch a toggle form open to closed... and what happens when you switch back to open?

You say it acts like it is being turned on and off rapidly, it isn't clear to me when these rapid signals are showing up and in what relation to you switching the switch.

a7

yea i found out the hard way that i needed diodes lol. so no more ghosting issues. i have it setup in a 5x5 pattern. everything registers as it should in windows game controller properties. the game however, is expecting momentary pressing, and not the toggle switch being constantly on.

so obviously i could just replace the toggles with more momentary buttons but i feel like its possible to do in code or even another app (i started seeing somewhere that a auto hot key program may be able to be used to solve this).

i need to be able to turn the physical switch to the on positon, but it needs to act as if i just pressed a button. and then when i turn off the physical switch, it needs to act as if the button was pressed once more.

                    case PRESSED:
                    case RELEASED:
                              Joystick.setButton(buttbx.key[i].kchar, 1);
                              break;
                    case HOLD:
                    case IDLE:
                              Joystick.setButton(buttbx.key[i].kchar, 0);
                              break;

Please read this thread thoroughly, I do believe it addresses the same issue.

At a glance @PaulRB's idea looks plausible; you'll have to figure out a way for that logic to apply to the toggles and not the push buttons, or they will start giving you action on press and release. I think. It's sleepy and I'm still a little early.

But do read that thread. Never heard from the OP, please let us hear from you as you solve this easily solved problem.

a7

i really do appreciate your guys input!! so pauls way of doin it would of worked minute the push buttons i already have. i dug deeper into my issue, and decided to take out the resistors i put in on the columns. (i had found another forum/schematic on doin a button matrix and they added 10k resistors on the columns. i pulled those, and its working as it should. i did also find a program called SV Mapper, and that will allow me to do the on/off as i was trying to do in this topic. thanks again!

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.