Can't figure out where I'm going wrong.

Hi i am trying to figure out why an LED won't light up when a button is pressed using the keypad and joystick library, is there a problem with my code? LED is connected to pin 1 and ground on a pro micro.

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

#define ENABLE_PULLUPS

#define NUMBUTTONS 32
#define NUMROWS 6
#define NUMCOLS 6

int Dial1 = A0;
int Dial2 = A1;
int Dial3 = A2;
int Dial4 = A3;
int LED = 1;

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},
{24, 25, 26, 27, 28, 29},
{30, 31}
};

byte rowPins[NUMROWS] = {8, 9, 10, 14, 15, 16};
byte colPins[NUMCOLS] = {2, 3, 4, 5, 6, 7};

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

Joystick_ Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 32, 0, false, false, true, false, false, false, true, true, true, false, false);

void setup() {

Joystick.begin();
Joystick.setZAxisRange(0, 1023);
Joystick.setRudderRange(0, 1023);
Joystick.setThrottleRange(0, 1023);
Joystick.setAcceleratorRange(0, 1023);
pinMode(LED, OUTPUT);


}

void JButtonStates() {
Joystick.setZAxis(analogRead(Dial1));
Joystick.setRudder(analogRead(Dial2));
Joystick.setThrottle(analogRead(Dial3));
Joystick.setAccelerator(analogRead(Dial4));

}

void loop() {
JButtonStates();
delay(10);
CheckAllButtons();

}

void CheckAllButtons(void)
{

if (switchpnl.getKeys())
{
for (int i = 0; i < LIST_MAX; i++)
{
if ( switchpnl.key[i].stateChanged )
{
switch (switchpnl.key[i].kstate)
{
case PRESSED:
Joystick.setButton(switchpnl.key[i].kchar, 1);
if (i == 0){
digitalWrite(LED, HIGH);
}
break;
case HOLD:
Joystick.setButton(switchpnl.key[i].kchar, 1);
delay(2500);
Joystick.setButton(switchpnl.key[i].kchar, 0);
break;
case RELEASED:
case IDLE:
Joystick.setButton(switchpnl.key[i].kchar, 0);
if (i == 0){
digitalWrite(LED, LOW);
}
break;
}
}
}
}
}

Is your LED connected to Pin 1? Does a simple Blink sketch set for Pin 1 blink the LED? If not, the problem is likely wiring. Maybe the LED is backward.

you can always test an LED/resistor circuit by momentarily connecting it across 5V and ground. when you have that working, move the 5V end to the I/O pin

Which Arduino board?
Pins 0 and 1 are the serial RX and TX pins on many boards.

pcbbc:
Which Arduino board?
Pins 0 and 1 are the serial RX and TX pins on many boards.

I tried it on multiple pins, this is a pro micro arduino. The LED works when connected to 5v and ground fine so the LED is working

johnwasser:
Is your LED connected to Pin 1? Does a simple Blink sketch set for Pin 1 blink the LED? If not, the problem is likely wiring. Maybe the LED is backward.

I'll have a look this afternoon and load a simple blink sketch to see if the pins are fine for LED

how about simply

loop ()
{
     digitalWrite (LED, ! digitalRead (LED));
     delay (500);
}

Ok so i figured out a hack to get it work but, now what i did was wire and define a completely new container just for the buttons that i want to light an LED. Seems like because i am using the keypad library and my buttons are wired in a matrix i had to do some sort of trickery as i couldn't figure out. In the below example an LED lights up when any of the buttons are pressed and goes off when released. Now my question is how do i convert the byte container value for buttons to readable? I want to make an if statement that goes something like "if button 8 is pressed then turn on LED" button 8 is 7 in the byte container. I'm thinking it has something to do with "i" in "int i = 0; i < LIST_MAX; i++" because that part checks the byte container for witch buttons state changes.

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

#define ENABLE_PULLUPS

#define NUMBUTTONS 32
#define NUMROWS 6
#define NUMCOLS 6

int Dial1 = A0;
int Dial2 = A1;
int Dial3 = A2;
int Dial4 = A3;
int LED = A4;
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},
{24, 25, 26, 27, 28, 29},
{30, 31}
};

byte rowPins[NUMROWS] = {8, 9, 10, 14, 15, 16};
byte colPins[NUMCOLS] = {2, 3, 4, 5, 6, 7};

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

Joystick_
 Joystick(JOYSTICK_DEFAULT_REPORT_ID, JOYSTICK_TYPE_GAMEPAD, 32, 0, 
false, false, true, false, false, false, true, true, true, false, 
false);

void setup() {

Joystick.begin();
Joystick.setZAxisRange(0, 1023);
Joystick.setRudderRange(0, 1023);
Joystick.setThrottleRange(0, 1023);
Joystick.setAcceleratorRange(0, 1023);
switchpnl.setHoldTime(15000);
pinMode(LED, OUTPUT);



}


void JAnalogStates() {
Joystick.setZAxis(analogRead(Dial1));
Joystick.setRudder(analogRead(Dial2));
Joystick.setThrottle(analogRead(Dial3));
Joystick.setAccelerator(analogRead(Dial4));

}

void loop() {
JAnalogStates();
delay(10);
CheckAllButtons();
delay (500);

}
void CheckAllButtons(void)
{
 
if (switchpnl.getKeys())
{
for (int i = 0; i < LIST_MAX; i++)
{
 if (switchpnl.key[i].kstate==PRESSED)
  {
    digitalWrite(LED, HIGH);
  }

else if (switchpnl.key[i].kstate==RELEASED)
{
digitalWrite(LED, LOW);
}
if ( switchpnl.key[i].stateChanged )
{
switch (switchpnl.key[i].kstate)
{
case PRESSED:
Joystick.setButton(switchpnl.key[i].kchar, 1);
break;
case HOLD:
case RELEASED:
case IDLE:
Joystick.setButton(switchpnl.key[i].kchar, 0);
break;
}
}
}
}
}

The Keypad library gets confused if you use the character '\0' in your table. I understand that you want the index values 0 through 31 but since you are using 'switchpnl.key' you can completely ignore the values in the table (as long as each is a unique, non-zero character) by using .kcode in place of .kchar.

Change your table to something like:

byte buttons[NUMROWS][NUMCOLS] =
{
  {'a', 'b', 'c', 'd', 'e', 'f'},
  {'g', 'h', 'i', 'j', 'k', 'l'},
  {'m', 'n', 'o', 'p', 'q', 'r'},
  {'s', 't', 'u', 'v', 'w', 'x'},
  {'A', 'B', 'C', 'D', 'E', 'F'},
  {'G', 'H', 'I', 'J', 'K', 'L'}
};

Then when you are processing inputs, just change from .kchar to .kcode:

        switch (switchpnl.key[i].kstate)
        {
          case PRESSED:
            Joystick.setButton(switchpnl.key[i].kcode, 1);
            break;
          case HOLD:
            // WARNING! If you don't put a "break;" here every key pressed will be released after 500 milliseconds.
          case RELEASED:
          case IDLE:
            Joystick.setButton(switchpnl.key[i].kcode, 0);
            break;
        }

Style note: When using pins above 13 on an UNO, Nano, Mini, Leonardo, or Micro you should use the pin names instead of the pin numbers. The mapping of names to numbers changes between models. For example, Pin 14 is A0 on the UNO but MISO on the Micro so your intentions can be unclear if you use the number.

byte rowPins[NUMROWS] = {8, 9, 10, MISO, SCK, MOSI};
byte colPins[NUMCOLS] = {2, 3, 4, 5, 6, 7};

This also makes it clear that you are using some of the SPI pins for I/O so nobody will try to add an SPI device (like an SD card) to your sketch.

johnwasser:
The Keypad library gets confused if you use the character '\0' in your table. I understand that you want the index values 0 through 31 but since you are using 'switchpnl.key' you can completely ignore the values in the table (as long as each is a unique, non-zero character) by using .kcode in place of .kchar.

Change your table to something like:

byte buttons[NUMROWS][NUMCOLS] =

{
 {'a', 'b', 'c', 'd', 'e', 'f'},
 {'g', 'h', 'i', 'j', 'k', 'l'},
 {'m', 'n', 'o', 'p', 'q', 'r'},
 {'s', 't', 'u', 'v', 'w', 'x'},
 {'A', 'B', 'C', 'D', 'E', 'F'},
 {'G', 'H', 'I', 'J', 'K', 'L'}
};





Then when you are processing inputs, just change from .kchar to .kcode:


switch (switchpnl.key[i].kstate)
       {
         case PRESSED:
           Joystick.setButton(switchpnl.key[i].kcode, 1);
           break;
         case HOLD:
           // WARNING! If you don't put a "break;" here every key pressed will be released after 500 milliseconds.
         case RELEASED:
         case IDLE:
           Joystick.setButton(switchpnl.key[i].kcode, 0);
           break;
       }





Style note: When using pins above 13 on an UNO, Nano, Mini, Leonardo, or Micro you should use the pin names instead of the pin numbers. The mapping of names to numbers changes between models. For example, Pin 14 is A0 on the UNO but MISO on the Micro so your intentions can be unclear if you use the number.


byte rowPins[NUMROWS] = {8, 9, 10, MISO, SCK, MOSI};
byte colPins[NUMCOLS] = {2, 3, 4, 5, 6, 7};



This also makes it clear that you are using some of the SPI pins for I/O so nobody will try to add an SPI device (like an SD card) to your sketch.

Thank you, makes sense i will give it a try tonight. I have not run into an issue with the pin names and numbers yet so can i leave it as is?