Change delay/running time by keypad

Hi!

How would one go about entering a delay time by keypad, so that the arduino remembers all keypresses and changes a variable accordingly?

Say, if I want to, when I start up my arduino, be prompted to enter a time for a LED to run... if I want it to run for 2236 seconds, I would have to press "2", "2", "3" & "6". But each press must be remembered, and only when I confirm my entry, the numbers entered should be remembered and put together as "2236" seconds.

I want to be able to enter 1 digit and soforth up to 5 digits. However, if I want to enter "1", I could just enter "00001" to make the programming easier.

But how would I go about doing that - any suggestions?

How many digits do you want to remember ? Suppose you want to enter 4 digits every time then you just need to count the key presses until you have 4.

If you want a different number of key presses each time perhaps the Arduino would keep storing the keypresses until (say) the # key is pressed.

Another option is for the Arduino to decide no more keypresses are coming if the gap between keypresses exceeds some specified time.

Whatever system you choose it would be wise to present the value to the user for confirmation before acting on it.

...R

Hi,

I dont want a time delay deciding when the entering of digits are complete. Whether it stores the digits until "#" is pressed or you have to enter a complete 5-digit number doesn't really matter. By the way.. I want 5 digits, so potentially it could be 99999 seconds.

What I need to know is how I can achieve that... a code example would be awesome, or just some pointers in the right direction. :)

And of course I will have the user confirm his entries bu pushing a key... a LCD will be used to guide the user.

cajodk: Whether it stores the digits until "#" is pressed or you have to enter a complete 5-digit number doesn't really matter. By the way.. I want 5 digits, so potentially it could be 99999 seconds.

What I need to know is how I can achieve that... a code example would be awesome, or just some pointers in the right direction.

I have given you the pointers.

You have a go at writing the code. If you cannot get it to work then post your code and we will try to help.

...R

Okay— first problem is - I want to be able to enter digits and keep them on the display until confirmed by user. BUT - this way the digits only appear on the LCD the moment I press them. I know that’s probably because I’m not remembering the state… but at this moment I can’t really figure out how to do that - or maybe there is an even smarter way?

#include <Keypad.h>
#include <LiquidCrystal.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] = {
  11, 12, 2, 3}; //PINS WHERE THE ROWS OF THE KEYPAD IS CONNECTED
byte colPins[COLS] = {
  4, 5, 6};  //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
byte ledPin = 13; 
byte currentState = 1;        //MAKE VARIABLE CURRENTSTATE, SET IT TO START IN STATE 1 IN AUTOMODE


//LCD DISPLAY SETUP
LiquidCrystal lcd(19, 18, 7, 8, 9, 10);  //PINS WHERE THE LCD DISPLAY IS CONNECTED

unsigned long dlyTime = 0;

void setup(){
  Serial.begin(9600);
  lcd.begin(16, 2);   // SETTING UP LCD'S NUMBER OF COLUMNS AND ROWS
}

void loop(){
  char key = keypad.getKey();
  lcd.setCursor(0, 0);
  lcd.print ("Set delay time:");
  delay (50);
  lcd.setCursor(0, 1);
  lcd.print ("_____ seconds");

  if (dlyTime == 0);
  {
    enterDelay();
  }
}

void enterDelay(void){
 
   
   
  char key = keypad.getKey();
  switch (currentState)
  {

    //***************************
  case 1:
 //Serial.println("case1");
    lcd.setCursor(0, 1);
    if (key) 
    {
      
      lcd.print(key);
      lcd.setCursor(1, 1);
      lcd.print("____");
      currentState = 2;
    }

    else {
      currentState = 1;
    }


    break;
    //***************************
  case 2:

    lcd.setCursor(1, 1);
    if (key) 
    {
      lcd.print(key);
      currentState = 3;
    }
    else {
      currentState = 2;
    }
    break;
    //***************************
  case 3:

    lcd.setCursor(2, 1);
    if (key) 
    {
      lcd.print(key);
      currentState = 4;
    }
    else {
      currentState = 3;
    }
    break;
    //***************************
  case 4:

    lcd.setCursor(3, 1);
    if (key) 
    {
      lcd.print(key);
      currentState = 5;
    }
    else {
      currentState = 4;
    }
    break;
    //***************************
  case 5:

    lcd.setCursor(4, 1);
    if (key) 
    {
      lcd.print(key);
      currentState = 5;
    }
    else {
      currentState = 5;
    }
    break;
    //***************************
  default:
    currentState = 1;              //Back to state 1
  } // END SWITCH/CASE===========================================================
}

I suspect you are making life difficult for yourself by not planning the program so that the the overall logic is separate from the details.

I would make my loop() like this

void loop() { readKeypad(); updateLCD(); checkValidNumber(); actOnValidNumber(); }

There would need to be an array to hold the characters that are entered - so the array might first be 3----, then 35---, 356-- etc as the characters are entered (assuming you want 5 digits). This would happen in the readKeypad() function.

The updateLCD() function would just display whatever happens to be in the array of characters.

The checkValidNumber() function would be watching to see if all 5 characters are entered. When they are it would set a variable that tells the readKeypad() function not to accept any more data for the moment

The actOnValidNumber() function would do whatever it should only if there was a complete number to work with.

The important thing is that each of the functions completes its task very quickly so that loop() can repeat as fast as possible.

Have a look at planning and implementing a program

...R

I would think you want to enter some numbers sequentially, but if you forget and walk away, the function should time out.

for that, you would want to get into this input mode and if no key is pressed for say, 15 seconds, it just times out.

also, since numbers are always right justified, 1 is always one, as is 01 001 0001 and 00001 leading zeros are probably not needed.

https://www.arduino.cc/en/Tutorial/StringAdditionOperator

no matter if you have 1 or 5 digits, when you press # that value would be loaded.

read the value, enter it into string2 then shift the display to display string1 and the curser as free. if you hit # the value goes to the global variable.

if you hit another number then string1 = string1 + string2 display string1

if you set the timer to time out at 5 or 10 seconds and you hit a wrong number, you can just wait.

option 2

enter digit

to store to string2

string1=string1 + string2

if # is held for 2 seconds global variable = string1 string1 is cleared, or not

lets you hit '0'# 5 times to clear.

dave-in-nj: I would think you want to enter some numbers sequentially, but if you forget and walk away, the function should time out.

Another way to do this would be to have a "clear" key.

I wonder if the "*" (star) key is available to be used as a "clear" key.

The way I would solve this problem does not involve putting the digits in an array.