LED-strip controlled by a 4x4 keypad with different states

I would make for a project, a program code that controls a LED strip using a 4x4 keypad. The problem is what I have I want to create different states e.g. when the A key is held that meanwhile you can switch the LEDs 1-8 with the keys 1-8, then release the A key and this state remains. I need 8 states in total and would have used the keys ( A, B, C, D, 9, 0, *, # ). The other states should do exactly the same as with A only other LEDs address.

I would have made there something already but I know unfortunately no more further and/or how I should formulate generally that.

#include <FastLED_NeoPixel.h>
#define DATA_PIN 10
#define NUM_LEDS 128
#define BRIGHTNESS 250
FastLED_NeoPixel<NUM_LEDS, DATA_PIN, NEO_GRB> strip; 
#include <Keypad.h>
enum State_enum {A, B, C, D, NUMBER_NINE, NUMBER_ZERO, STAR, HASH_TAG};
void a();
void b();
void c();
void d();
void number_nine();
void number_zero();
void star();
void hash_tag();
const byte ROWS = 4;  
const byte COLS = 4;  
char keys[ROWS][COLS] = {
  { 'D', '#', '0', '*' },
  { 'C', '9', '8', '7' },
  { 'B', '6', '5', '4' },
  { 'A', '3', '2', '1' }
};
byte rowPins[ROWS] = { 6, 7, 8, 9 };  
byte colPins[COLS] = { 2, 3, 4, 5 };  
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, ROWS, COLS);
Keypad kpd = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
uint32_t red = strip.Color(255, 0, 0);
uint32_t off = strip.Color(0, 0, 0);
uint32_t green = strip.Color(0, 255, 0);
void setup() {
  strip.begin(); 
  strip.setBrightness(BRIGHTNESS);
  Serial.begin(9600);
  Serial.println("test");
  colorWipe(off, 0);  
}
void loop() {
}
void colorWipe(uint32_t color, unsigned long wait) {
  Serial.println(color);
  for (unsigned int i = 0; i < strip.numPixels(); i++) {
    strip.setPixelColor(i, color);
    strip.show();
    delay(wait);
  }
}
void a(uint32_t color){
  char key = keypad.getKey();
  if(kpd.getKeys)){
    for (int i=0; i<LIST_MAX; i++){
      switch (kpd.key[i].kstate){
          if (key == 'A') {
    switch(kpd.key[i].stateChanged){
      case PRESSED:
      { for (uint16_t i = 0; i < 16; i+2)
    Serial.println(key);
    if (isDigit(key)) {
      int keyAsNumber = key - '0';
      strip.setPixelColor(keyAsNumber - 1, red);
    }
  }
  strip.show();
}

does anyone have an idea or tip how i can do this.
Thanks in advance.

Use a logic analyzer to see what happens.

Insert Serial.println()´s at points of interrest.

Have a nice day and enjoy coding in C++.

getKeys is a function so it needs to be

if(kpd.getKeys())

I did not look further into your code (yet).

yet another chatGPT output
even worse - it is not ended

Are you sure? I doubt it would not make stupid mistakes like the one I pointed out as well as the missing curly braces at the end that you found.

I realised that once I loaded it in the IDE and did an autoformat.

Im not using AI, its made by my self.

The below can be a basic framework for your needs and is based on the MultiKey example.

I only have a 3x4 keypad and therefor have only implemented two states using the '*' and the '#'. I've spend minimal time on it, I guess there is space for improvement.

#include <Keypad.h>

const byte ROWS = 4;  //four rows
const byte COLS = 3;  //three columns
char keys[ROWS][COLS] = {
  {'1', '2', '3'},
  {'4', '5', '6'},
  {'7', '8', '9'},
  {'*', '0', '#'}};
byte rowPins[ROWS] = {4, 5, 6, 7};  //connect to the row pinouts of the keypad
byte colPins[COLS] = {8, 9, 10};    //connect to the column pinouts of the keypad

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

unsigned long loopCount;
unsigned long startTime;
String msg;


void setup()
{
  Serial.begin(9600);
  while (!Serial)
    ;
  loopCount = 0;
  startTime = millis();
  msg = "";
  Serial.println(F("Hello to multikey"));
}


void loop()
{
  static int stateNumber = 0;
  int ledNumber = -1;


  // 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:
            switch (kpd.key[i].kchar)
            {
              case '*':
                stateNumber = 1;
                break;
              case '#':
                stateNumber = 2;
                break;
              case '1' ... '8':
                if (stateNumber != 0)
                {
                  ledNumber = ((stateNumber - 1) * 8) + kpd.key[i].kchar - '1';
                }
                break;
            }
            msg = " PRESSED.";
            break;
          case HOLD:
            msg = " HOLD.";
            break;
          case RELEASED:
            if (kpd.key[i].kchar == '*' || kpd.key[i].kchar == '#')
            {
              stateNumber = 0;
              ledNumber = -1;
            }
            msg = " RELEASED.";
            break;
          case IDLE:
            msg = " IDLE.";
        }
        Serial.print("Key ");
        Serial.print(kpd.key[i].kchar);
        Serial.println(msg);

        if (ledNumber != -1)
        {
          Serial.print(F("ledNumber = "));
          Serial.println(ledNumber);
          Serial.println(F("Update your LED strip"));
        }
      }
    }
  }
}  // End loop

Note:
There is still some stuff left of the original that can removed like the loopCpunt and the startTime.

thanks for the code i will test it and give some responds to it. :slight_smile:

o'rly ? explain what this code doing?

Function prototypes. As any decent C/C++ programmer would do. The Arduino environment makes one lazy.

But the function itself does not exist in that form so it is useless.

its not generated i searched for a solution to get more then one state but i just wanted to code one ( its void a ) to test it but i wasnt shure, so i let it be like this. An AI would generate a better code with the other states.

unfortunately the code is incomplete, contains numerous errors and won't compile. in particular, parenthesis and braces don't match

  • code in setup() is invoked once, normally to initialize things. your loop() is empty. i would have thought a() should be called within it

  • kpd.getKeys() is missing a parenthesis, but why call it twice

  • this looks like it is checking to see if a particular key was pressed -- using switch() instead of if()

the following would make more sense

void a (uint32_t color)
{
    char key = keypad.getKey ();
    switch (key)  {
    case 'A':
        break
    case '0'...'9':
        strip.setPixelColor (key - '0' - 1, red);
        strip.show ();
    }
}

because keypads are multiplexed, they can't recognize more than one key at a time. code needs to recognize that the 'A' key was pressed and process the numeric keys accordingly

seems that there are other misunderstandings

The code in post #8 works as expected. You can press the combination of * (or #) and the keys 1 .. 8 to get the numbers 0 to 15; it's tested :wink:

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