Using 4x4 keyboard inputs to do different things in same sketch

Using Arduino UNO

Hi,

I want to have an editable list of codes of things in my freezer, which will be accessed with a 4x4 pad.

I know that will give me problems with limited arduino memory (I have an SD shield) and editing arrays etc. but I have started out with a simple array of 9 elements and will cross bridges as I get to them.

As far as the number pad is concerned, the idea is that if I press the A on the number pad, then that will be a signal that the next button I enter will be the code of the product. And that code will be added to the array.

The problem is that it doesn’t seem to be so easy because I can’t work out how to apply different purposes to the keypresses.

My first key press “keypressed” input works just fine, but I have invented a function addToArray that rather hopefully introduces a second keypress called key2, with an equally hopefully new instance of the keypad class.

But what happens is that the first time the A key gets pressed, the function addToArray is executed but without requiring a further keypress… it just adds the original keypressed value (‘A’) to the array. Then the second and subsequent times A is pressed, the function executes, but not the part that refers to a key press, and nothing is added to the array.

I know the whole project is a bit hopeful, but I would like to get this point sorted (about double use of the keypad) for other projects too.

Many thanks if anyone can help out.

#include <Keypad.h>


const byte numRows= 4;
const byte numCols= 4;

char keymap[numRows][numCols]= { {'1', '2', '3', 'A'},

{'4', '5', '6', 'B'},
{'7', '8', '9', 'C'},
{'*', '0', '#', 'D'} };

byte rowPins[numRows] = {9,8,7,6}; //Rows 0 to 3
byte colPins[numCols]= {5,4,3,2}; //Columns 0 to 3

//initializes an instance of the Keypad class

Keypad myKeypad= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

//a second keypad instance...? 
Keypad myKeypad2= Keypad(makeKeymap(keymap), rowPins, colPins, numRows, numCols);

 

//creating an array of values

char products[9];
int arrayCount = 0;

void setup()

{
Serial.begin(9600);
}


void loop()

{
char keypressed = myKeypad.getKey();
if (keypressed != NO_KEY)

{

if(keypressed== 'A'){
 
    Serial.print("Add code...");
    Serial.print(keypressed);
    addToArray();
    }
    
else if (keypressed=='D'){
    Serial.println("Products available...");
    Serial.println(products);
    }
    
else {
    Serial.print("Another key pressed");
    Serial.print(keypressed);
    }
}
}


void addToArray ()

{

Serial.print("Function executed."); //just to check the function executes

//the idea is that the next bit meanstaht the system will wait for a new keypress, but not so!

char key2 = myKeypad2.getKey();
    if (key2 != NO_KEY){

        products[(arrayCount)]= key2; //this adds the "keypressed" value
        Serial.println("You have added ");
        Serial.println(key2); //prints the keypressed value   
        arrayCount++;
        Serial.println("The array now contains ");
        Serial.println(products); //successfully adds the value only the first time of execution    
        Serial.println("----------------");
    }}

Why two instances of the Keypad ?

Use a state machine. See: https://forum.arduino.cc/index.php?topic=384198.0 for more info about state machines.

In your case you will start in an IDLE state and if the keypad input is ‘A’ you would switch to a ‘GATHER_ID’ state. While in the ‘GATHER_ID’ state, any character that looks like an ID is saved as part of the ID and some OTHER keypad entry lets you know what state to go to next.

UKHeliBob: Why two instances of the Keypad ?

Thanks for asking.

Just clutching for straws. With it, I got the program to do a bit more. But it still didn't do what I wanted it to.

Basic lack of understanding of how the code works.

johnwasser: Use a state machine. See: https://forum.arduino.cc/index.php?topic=384198.0 for more info about state machines.

Hi. Thanks for taking the time to post. Time to do a bit of studying! I will report on progress.

Why not log all keys pressed to a string until the '' key (or any key you want) is pressed? After registering the '' key you can decode the string with all the keys pressed and do, whatever you want to be done. Alternatively, with more effort, you can check, if the time after the last key pressed is greater than some threshold. This way, you can use all keys, but have to press the key in a certain amount of time.

LightuC: Why not log all keys pressed to a string until the '*' key (or any key you want) is pressed?

Now that's a nice solution, as it also makes saving strings rather chars easier (which was another bridge I had to cross). (However, I'll also keep still struggling with the application of the state machine, too, as it seems like an important thing to know.)

lionelm: However, I'll also keep still struggling with the application of the state machine, too, as it seems like an important thing to know.

Yes, you should definetely do that. Check out this example.