program for multiple buttons

How would I assign a button within a key matrix to an ezButton?

For example I tried this, but doesn't seem to work:

ezButton Switch_Up(buttbx.key[9].kchar);
ezButton Switch_Dn(buttbx.key[10].kchar);

Thank you in advance!

@kavster

Your topic was Moved to it's current location / section as it is more suitable.

Could you also take a few moments to Learn How To Use The Forum.

Other general help and troubleshooting advice can be found here.
It will help you get the best out of the forum in the future.

a keymatrix is usually scanned through switching one IO-pin high and then detecting another IO-pin getting HIGH when the button closes the contact.

zeButton expects that the button is connected to Ground and IO-pin and a pull-up-resistor
or
or button connected 5V and IO-pin and a pull-down-resistor.

So the code of ezButton expects a different electrical situation as a keymatrix.

You should search for code that is made for keymatrixes

best regards Stefan

Thank you for your reply, Stefan.

Long sotry short, I'm building a switch box for flight simulation.
I have a mixture of 'on-off' switches and 'on-off-on' switches.
Because I have more switches than pins available on the board, I've been using a matrix.

I've been trying to find a way to to code it so that when a switch is in the 'off' position that it triggers it's own individual joystick button.
Eg.
Switch 1:
On - Joystick Button 1
Off - Joystick Button 3
On - Joystick Button 2

Switch 2:
On - Joystick Button 4
Off - Joystick Button 5

...etc.

ezButton seemed to be the perfect way to do this as I was able to write the logic quite easily.

I've been trying (in another thread on this forum) with some help from another user to write the code just using the Joystick.h and Keypad.h libraries, but haven't been able to get it to work successfuly so far.

I've been searching as best I can for other solutions, but haven't been able to find anything else yet. Would you happen to know of any that I could look into by any chance please?

consider

// recognize multiple button presses; tgl LED when pressed

byte butPins [] = { A1, A2, A3 };
byte ledPins [] = { 10, 11, 12 };

#define N_PINS sizeof(butPins)

byte butLst [N_PINS] = {};

// -----------------------------------------------------------------------------
void setup (void)
{
    for (unsigned n = 0; n < N_PINS; n++)  {
        digitalWrite (ledPins [n], OFF);
        pinMode      (ledPins [n], OUTPUT);

        pinMode      (butPins [n], INPUT_PULLUP);
        butLst [n]  = digitalRead (butPins [n]);
    }
}

// -----------------------------------------------------------------------------
void loop (void)
{
    for (unsigned n = 0; n < N_PINS; n++)  {
        byte but = digitalRead (butPins [n]);

        if (butLst [n] != but)  {
            butLst [n] = but;

            if (LOW == but)     // button pressed
                digitalWrite (ledPins [n], ! digitalRead (ledPins [n]));
           delay (10);         // debounce
        }
    }


}

Hi Greg,

Thanks for your reply!

I'm still pretty new to coding, so trying to comprehend your example.
I get a message from the compilier saying 'OFF' was not declared in this scope.
Is that the same as just setting the LED to low in the setup?

From what I understand,
it reads the state of a button and assigns it to a temp variable.
Then it checks that temp variable against the previous state of the button.
If the button is pressed then it lights the LED.
then once the button is pressed again it turns the LED off.

Again, I'm still pretty new at this, so sorry if I've misunderstood it!

I did some gearching (searching with google)
and found the adafruit keypad library

To be sure if you could use it you should carefully examine the electrical wiring of the original adafruit keypad

From a quick look this library seems to offer events like pressed released

best regards Stefan

Thank you, Stefan.
I will read into that library later tonight as I have to pop out now.

I'll let you know if I get any luck with that.

Thanks again!

kavster:
I get a message from the compilier saying 'OFF' was not declared in this scope. Is that the same as just setting the LED to low in the setup?

replace OFF with LOW/HIGH, whichever turns the LED off. extracted this from working code but forgot to include the enum

kavster:
If the button is pressed then it lights the LED.

it checks for a change in state and if pressed, toggles the LED on/off

Ahh, I see!

So, I could treat the LED as my off position, and when the switch is toggled to one of the 'on' positions it would turn LOW, and when the switch is toggled to the off position it would turn HIGH?

Thanks, I'll see if I can write that logic in the context of my switch panel and see how that goes!

kavster:
Switch 1:
On - Joystick Button 1
Off - Joystick Button 3
On - Joystick Button 2

This is fairly easy, Wire the two outside terminals like keypad buttons. Call them 'A' and 'B'.
If A is 'pressed', turn on Joystick Button 1 and turn off Joystick Button 2.
If A is 'released', turn off Joystick Button 1 and turn on Joystick Button 2.
If B is 'pressed', turn on Joystick Button 3 and turn off Joystick Button 2.
If B is 'released', turn on Joystick Button 3 and turn on Joystick Button 2.

Note: You may need to do some special tests to see what the states of the switches are before you start the scanning. If A and B are both released you will have to turn on Joystick Button 2 manually since the scanning won't notice a 'state change'.

johnwasser:
This is fairly easy, Wire the two outside terminals like keypad buttons. Call them 'A' and 'B'.
If A is 'pressed', turn on Joystick Button 1 and turn off Joystick Button 2.
If A is 'released', turn off Joystick Button 1 and turn on Joystick Button 2.
If B is 'pressed', turn on Joystick Button 3 and turn off Joystick Button 2.
If B is 'released', turn on Joystick Button 3 and turn on Joystick Button 2.

Note: You may need to do some special tests to see what the states of the switches are before you start the scanning. If A and B are both released you will have to turn on Joystick Button 2 manually since the scanning won't notice a 'state change'.

Yes, but the problem was how I actually assign the joystick button to the ezButton.
Other people have said that it is not possible with the ezButton library.
What you've said is what I'm trying to acheive, but have been unable to code succesfully. That's where I need the assistance.

kavster:
Yes, but the problem was how I actually assign the joystick button to the ezButton.

You don't. See the File->Examples->Keypad->MultiKey. You get separate 'PRESSED' and 'RELEASED' states for each of the keys that have changed (up to 10).
Do NOT use the value zero in the key map.
The Keypad library can handle up to 10 rows of up to 16 columns.

johnwasser:
You don’t. See the File->Examples->Keypad->MultiKey. You get separate ‘PRESSED’ and ‘RELEASED’ states for each of the keys that have changed (up to 10).
Do NOT use the value zero in the key map.
The Keypad library can handle up to 10 rows of up to 16 columns.

I was trying to acheive this with just the keypad and joystick library, but it wasn’t working properly for me.
So that’s why I tried to use ezButton (but I now know it’s not possible).
Here is my code I have so far, but this is still not working for me:

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

#define ENABLE_PULLUPS
#define NUMBUTTONS 23
#define NUMROWS 2
#define NUMCOLS 14


//define the symbols on the buttons of the keypads
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},  
};


byte rowPins[NUMROWS] = {21,20}; //connect to the row pinouts of the keypad
byte colPins[NUMCOLS] = {16,15,14,10,9,8,7,6,5,4,3,2,1,0}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad buttbx = Keypad( makeKeymap(buttons), rowPins, colPins, NUMROWS, NUMCOLS); 

//initialize an Joystick with 38 buttons;
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, 
  JOYSTICK_TYPE_JOYSTICK, 38, 0,
  false, false, false, false, false, false,
  false, false, false, false, false);


void setup() {
  Joystick.begin();
}

void loop() { 
  CheckAllButtons();
delay(100);
}

void CheckAllButtons(void) {  
     buttbx.getKeys();
                    
     for (int i=0; i<LIST_MAX; i++)   // Scan the whole key list.
     {                              
       if ( buttbx.key[i].stateChanged )   // Only find keys that have changed state.
       {                                           
          switch (buttbx.key[i].kstate) {  // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
                  case PRESSED:
                  case HOLD:
                           Joystick.setButton(buttbx.key[i].kchar, 1);
                           break;
                  case RELEASED:
                  case IDLE:
                           Joystick.setButton(buttbx.key[i].kchar, 0);
                           break;                              
       }            
      }      
     }
     if (buttbx.key[14].kstate == IDLE && buttbx.key[15].kstate == IDLE)
      {
        Joystick.setButton(31, 1);
      } else {
        Joystick.setButton(31, 0);
      }
    
}

…EDIT. Also, I don’t see the ‘Mulitkey’ example there, the only thing available is an example called ‘custom keypad’.

//define the symbols on the buttons of the keypads
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},  
};

DO NOT USE 0 AS ONE OF YOUR VALUES.

kavster:
Also, I don't see the 'Mulitkey' example there, the only thing available is an example called 'custom keypad'.

In Library Manager, find and install "Keypad by Mark Stanley, Alexander Brevig". I think you must have an ancient version.

johnwasser:
In Library Manager, find and install “Keypad by Mark Stanley, Alexander Brevig”. I think you must have an ancient version.

Ah, yes! That indeed showed me the example, thank you!
So, I have now written it as follows, is this what you mean?
(Also note, that the example code had it written as this, and the IDE highlighted them green.

char buttons[ROWS][COLS] = {
{'1','2','3'},
...
};

But, when I went into 2 digit numbers, they stopped being highlighted green, and I got complier warnings. So, I’ve changed it as below as the compilier warnings dissapeared. Please let me know if I’ve done something wrong there?

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

const byte ROWS = 2; //four rows
const byte COLS = 14; //three columns
char buttons[ROWS][COLS] = {
{1,2,3,4,5,6,7,8,9,10,11,12,13,14},
{15,16,17,18,19,20,21,22,23},
};
byte rowPins[ROWS] = {21, 20}; //connect to the row pinouts of the kpd
byte colPins[COLS] = {16, 15, 14, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0}; //connect to the column pinouts of the kpd

Keypad kpd = Keypad( makeKeymap(buttons), rowPins, colPins, ROWS, COLS );

//initialize an Joystick with 38 buttons;
Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, 
  JOYSTICK_TYPE_JOYSTICK, 38, 0,
  false, false, false, false, false, false,
  false, false, false, false, false);

void setup() {
    Joystick.begin();
}


void loop() {
    // Fills kpd.key[ ] array with up-to 10 active keys.
    // Returns true if there are ANY active keys.
    if (kpd.getKeys())
    {
        for (int i=0; i<LIST_MAX; i++)   // Scan the whole key list.
        {
            if ( kpd.key[i].stateChanged )   // Only find keys that have changed state.
            {
                switch (kpd.key[i].kstate) {  // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
                    case PRESSED:
                    case HOLD:
                    Joystick.setButton(kpd.key[i].kchar, 1);
                break;
                    case RELEASED:
                    case IDLE:
                    Joystick.setButton(kpd.key[i].kchar, 0);;
                }
             }
        }
      if (kpd.key[15].kstate == IDLE && kpd.key[16].kstate == IDLE)
      {
        Joystick.setButton(32, 1);
      } else {
        Joystick.setButton(32, 0);
      }  
    }
}

I also tried writting out your logic like this, but that hasn't worked either :confused:

switch (kpd.key[15].kstate) {
                    case PRESSED:
                    case HOLD:
                    Joystick.setButton(kpd.key[15].kchar, 1);
                    Joystick.setButton(kpd.key[32].kchar, 0);
                break;
                    case RELEASED:
                    case IDLE:
                    Joystick.setButton(kpd.key[15].kchar, 0);
                    Joystick.setButton(kpd.key[32].kchar, 1);  
                }
                switch (kpd.key[16].kstate) {
                    case PRESSED:
                    case HOLD:
                    Joystick.setButton(kpd.key[16].kchar, 1);
                    Joystick.setButton(kpd.key[32].kchar, 0);
                break;
                    case RELEASED:
                    case IDLE:
                    Joystick.setButton(kpd.key[16].kchar, 0);
                    Joystick.setButton(kpd.key[32].kchar, 1);  
                }
switch (kpd.key[15].kstate) {

This is not going to work. I believe there are only 10 entries in the key list.

Like in the MultiKey example, you go through each of the entries in the list and act on the keys that have changed state. You can (and SHOULD) ignore the ‘HOLD’ and ‘IDLE’ states since all you need are PRESSED and RELEASED.

Here is one way to do it. For the other 3-way switches, add more entries to the inner switch statements.

void loop()
{
  // Fills kpd.key[ ] array with up-to 10 active keys.
  // Returns true if there are ANY active keys.
  if (kpd.getKeys())
  {
    for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list.
    {
      if ( kpd.key[i].stateChanged )   // Only find keys that have changed state.
      {
        switch (kpd.key[i].kstate)    // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
        {
          case PRESSED:
            Joystick.setButton(kpd.key[i].kchar, 1);
            
            // Handle special 3-way switches
            switch (kpd.key[i].kchar)
            {
              case 15:
              case 16:
                Joystick.setButton(32, 0);
                break;
            }
            break;


          case RELEASED:
            Joystick.setButton(kpd.key[i].kchar, 0);
            
            // Handle special 3-way switches
            switch (kpd.key[i].kchar)
            {
              case 15:
              case 16:
                Joystick.setButton(32, 1);
                break;
            }
            break;
        }
      }
    }
  }
}

johnwasser:

switch (kpd.key[15].kstate) {

This is not going to work. I believe there are only 10 entries in the key list.

Like in the MultiKey example, you go through each of the entries in the list and act on the keys that have changed state. You can (and SHOULD) ignore the ‘HOLD’ and ‘IDLE’ states since all you need are PRESSED and RELEASED.

Here is one way to do it. For the other 3-way switches, add more entries to the inner switch statements.

void loop()

{
 // Fills kpd.key array with up-to 10 active keys.
 // Returns true if there are ANY active keys.
 if (kpd.getKeys())
 {
   for (int i = 0; i < LIST_MAX; i++) // Scan the whole key list.
   {
     if ( kpd.key[i].stateChanged )   // Only find keys that have changed state.
     {
       switch (kpd.key[i].kstate)    // Report active key state : IDLE, PRESSED, HOLD, or RELEASED
       {
         case PRESSED:
           Joystick.setButton(kpd.key[i].kchar, 1);
           
           // Handle special 3-way switches
           switch (kpd.key[i].kchar)
           {
             case 15:
             case 16:
               Joystick.setButton(32, 0);
               break;
           }
           break;

case RELEASED:
           Joystick.setButton(kpd.key[i].kchar, 0);
           
           // Handle special 3-way switches
           switch (kpd.key[i].kchar)
           {
             case 15:
             case 16:
               Joystick.setButton(32, 1);
               break;
           }
           break;
       }
     }
   }
 }
}

Thank you SO much! That’s done it, it’s finally working!