So I made a button box using a key matrix. Two of the buttons are toggle switches, these two toggle switches when they are turned on, its as if I am holding down a momentary button. When I turn off the toggle its as if I let go, I expected this but am trying to program around this.
I am currently using the code below.
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;
}
}
}
}
}
I would like to change this code so that when the state of key 0 is changed (either off to on, or on to off) that the joystick button is pressed for 50ms.
I have been trying to work with the following but this seems to just register all buttons as button 0 for some reason.
void CheckAllButtons(void)
{
if (buttbx.getKeys())
{
if (buttbx.key[0].stateChanged)
{
switch (buttbx.key[0].kstate)
{
case PRESSED:
{
Joystick.pressButton(0);
delay(50);
Joystick.releaseButton(0);
break;
}
case HOLD:
case RELEASED:
{
Joystick.pressButton(0);
delay(50);
Joystick.releaseButton(0);
break;
}
case IDLE:
break;
}
}
for (int i = 1; i < LIST_MAX; i++)
{
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;
}
}
}
}
Also tried this but all buttons seems to be detected as button 0. Not sure what I am missing.
if (buttbx.getKeys())
{
for (int i = 0; i < LIST_MAX; i++)
{
if (buttbx.key[i].stateChanged)
{
if (i == 0)
{
switch (buttbx.key[i].kstate)
{
case PRESSED:
Joystick.pressButton(i);
delay(50);
Joystick.releaseButton(i);
break;
case HOLD:
break;
case RELEASED:
Joystick.pressButton(i);
delay(50);
Joystick.releaseButton(i);
break;
case IDLE:
break;
}
}
else
{
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;
}
}
}
}
}
So now I have discovered I need to look at the kcode of the key not the index or the array. However i am still sometime gettings keypresses on the kcode=0 key when I press other keys.
for (int i = 0; i < LIST_MAX; i++)
{
if (buttbx.key[i].stateChanged)
{
// Serial.println(buttbx.key[i].kcode);
if (buttbx.key[i].kcode == 0)
{
switch (buttbx.key[i].kstate)
{
case PRESSED:
case HOLD:
Joystick.setButton(buttbx.key[i].kchar, 1);
delay(100);
Joystick.setButton(buttbx.key[i].kchar, 0);
Serial.println("0 Button RELEASED");
break;
case RELEASED:
Joystick.setButton(buttbx.key[i].kchar, 1);
delay(100);
Joystick.setButton(buttbx.key[i].kchar, 0);
Serial.println("0 Button RELEASED");
break;
case IDLE:
break;
}
}
else
{
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;
}
}
}
The problem is almost certainly caused by using a kchar of zero. That value is reserved for NO_KEY. When a new button is pressed, the library looks for the first entry that has a kchar of 0 (NO_KEY) and USES THAT FOR THE NEW KEY.
// Key is NOT on the list so add it.
if ((idx == -1) && button) {
for (byte i=0; i<LIST_MAX; i++) {
if (key[i].kchar==NO_KEY) { // Find an empty slot or don't add key to list.
key[i].kchar = keyChar;
key[i].kcode = keyCode;
key[i].kstate = IDLE; // Keys NOT on the list have an initial state of IDLE.
nextKeyState (i, button);
break; // Don't fill all the empty slots with the same key.
}
}
}
Do not use zero for a key character. Just use unique ASCII characters and ignore them. You will find the zero-based index of the key (row * COLS + col) in buttbx.key[i].kcode
There is no need to put zero-based indexes into the key character map since that just attempts to duplicate the .kcode field.