how to save value from keypad

Hi.
I'm still new with Arduino programming and need some advice. I'm currently doing internship project at this company. I'm stuck right now on my arduino coding.

For my project i have to enter values for 2 things : how many cycles and how many time taken. This will control a solenoid valve automatically according to the value that the user inserted. User will have to pressed # to save the value, A to insert cycles value, B to insert time taken value, C to on the solenoid valve and D to stop it.

 #include <LiquidCrystal.h>
 #include <Keypad.h>
 #include <EEPROM.h>

 LiquidCrystal lcd(13, 12, 11, 10, 9, 8); // For LCD

 const byte ROWS = 4; //four rows
 const byte COLS = 4; //four columns
 //define the cymbols on the buttons of the keypads
 char keys[ROWS][COLS] = {
    {'1','2','3','A'},
    {'4','5','6','B'},
    {'7','8','9','C'},
    {'*','0','#','D'}
 };
 byte rowPins[ROWS] = {4, 5, 6, 7}; //connect to the row pinouts of the keypad
 byte colPins[COLS] = {15, 14, 2, 3}; //connect to the column pinouts of the keypad

 //initialize an instance of class NewKeypad
 Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //For keypad

 int set[1]={0};
 int pos=0;
 int VALVE = 35; //set the valve pin
 
 
 void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(4, 0);
  // Set the posotion of the message.
  lcd.print("WELCOME");
  lcd.setCursor(2, 1);
  lcd.print("PLEASE WAIT");
  
  set[0] = EEPROM.read(0);
  delay(1000);
  
  pinMode(VALVE, OUTPUT);
  Serial.begin(9600);

 
 }

 void loop()
 { 
  lcd.setCursor(4, 0);
  lcd.print("Choose:");
  lcd.setCursor(0, 1);
  lcd.print("A:Cycle B:Time");
  
   char Key = keypad.getKey();
   if(Key)
   {
     switch (Key) {
        case 'A':
          {
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("How many cycles?");
            char tmpKey;
            char cycle;
            bool looping = true;
            while(looping)
              {
                tmpKey = keypad.getKey(); 
                if(tmpKey)
                {
                  Serial.println(tmpKey);
                  lcd.setCursor(0,1);
                  lcd.print(tmpKey);
                  cycle = tmpKey;
                  
                  if (cycle == '#')
                    looping = false;  
                }                
              }
          }
          break;
          
        case 'B':
          {
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("How many time taken?");
            int time_taken;
            time_taken = keypad.getKey()*1000; 
      
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("[C] Start    [D] Stop");
            char condition;
            condition = keypad.getKey();
            int i;
            int cycle;
      
              if( condition == 'C' )
                {        
                  for(i=0;i<cycle;i++)
                    {
                      digitalWrite(VALVE, HIGH); 
                      delay(time_taken);
                      digitalWrite(VALVE, LOW);
                      delay(time_taken);
                    }
                }  

          break;

           }
         
    }//switch fn will end here
  }
 }

The program that i wrote, is not function as i want. it will not save the value that i pressed using the keypad.Can someone please give me a hint, how should it look like? Thank you.

p/s: This is my first time i asked something in this forum. So forgive me if i've done something wrong with my question.

This was a fun exercise I enjoyed providing you an example to work from:
I do not have a keypad so this is not tested or compile this code but you can get the idea of what to do and you will need to debug it further no promises for functioning code

First thing to note is that the code loops fast and I use trick to skip a portion of code without using delay for timing. The LCD can't get blasted or you will freeze up the arduino.
and the timer for the cycles can be stopped at any time simply by changing the ControlMode to something other than 3 some where else in the code in the code

    if (ControlMode == 3) {
      static unsigned long _ETimer;
      if ( millis() - _ETimer >= time_taken { // Exact Timing
      _ETimer += time_taken;
      digitalWrite(VALVE, !digitalRead(VALVE));
        if ( i >= cycle; )ControlMode = 4;
        i++;
      }
    }

Second you need to convert the ASCii Character to an int using atoi() fuction to find the real numeric value of the character. This will also let yo type in more than 1 character like 100 and convert it to an int with the value of 100

well Take a look can answer your questions:
Please feel free to criticize my code I am an armature at Arduino and can learn from others too :slight_smile:

#include <LiquidCrystal.h>
#include <Keypad.h>
#include <EEPROM.h>

LiquidCrystal lcd(13, 12, 11, 10, 9, 8); // For LCD

const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char keys[ROWS][COLS] = {
  {'1', '2', '3', 'A'},
  {'4', '5', '6', 'B'},
  {'7', '8', '9', 'C'},
  {'*', '0', '#', 'D'}
};
byte rowPins[ROWS] = {4, 5, 6, 7}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {15, 14, 2, 3}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS); //For keypad

int set[1] = {0};
int pos = 0;
int VALVE = 35; //set the valve pin
int SpamDelay = 100; // No faster than 10 times a second for LCD or you could crash the arduino!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

void setup() {
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.setCursor(4, 0);
  // Set the posotion of the message.
  lcd.print("WELCOME");
  lcd.setCursor(2, 1);
  lcd.print("PLEASE WAIT");

  set[0] = EEPROM.read(0);
  delay(1000);

  pinMode(VALVE, OUTPUT);
  Serial.begin(9600);
  keypad.setDebounceTime(100)

}

void loop()
{
  static char MyStr[17];
  static byte MyStrPos = 0;
  static int ControlMode;
  static int LastControlMode;
  static unsigned long _ATimer; //Span Timer
  static int Cycles;
  static int time_taken;
  
  char Key = keypad.getKey();

  if (Key != NO_KEY) {
    MyStr[MyStrPos] = Key;
    Serial.print(key);
    if (Key == 'A') {
      ControlMode = 1;
      MyStrPos = 0;
    }
    if (Key == 'B') {
      ControlMode = 2;
      MyStrPos = 0;
    }
    if (Key == 'C') {
      ControlMode = 3;
      CycleStrPos = 0;
    }
    if (Key == 'D') {
      ControlMode = 4;
      CycleStrPos = 0;
    }
    if (Key == '#') {
      MyStr[MyStrPos]  = '\0';
      if (ControlMode == 1) {
        ControlMode = 0;
        Serial.println();
        Cycles = atoi (MyStr);
        Serial.print("Cycles as an String: ")Serial.println(MyStr);
        Serial.print("Cycles as an int   : ")Serial.println(Cycles);
        CycleStrPos = 0;
      }
      else if (ControlMode == 2) {
        ControlMode = 0;
        time_taken = atoi(MyStr) * 1000;
        Serial.println();
        Serial.print("time_taken as an String: ")Serial.println(MyStr);
        Serial.print("time_taken as an int   : ")Serial.println(time_taken);
        CycleStrPos = 0;
      }
    }
    MyStrPos++;
  }
  if ((ControlMode = 4) || (unsigned long)(millis() - _ATimer) >= SpamDelay) { // No more often than Spam Delay
    _ATimer = millis();
    if (ControlMode != LastControlMode) {
      lcd.clear();
    }
    switch (ControlMode) {
      case (0):
        lcd.setCursor(4, 0);
        lcd.print("Choose:");
        lcd.setCursor(0, 1);
        lcd.print("A:Cycle B:Time");
        break;
      case (1):
        lcd.setCursor(0, 0);
        lcd.print("How many cycles?");
        lcd.setCursor(0, 1);
        lcd.print(CycleStr);
        break;
      case (2):
        lcd.setCursor(0, 0);
        lcd.print("How many time taken?");
        lcd.setCursor(0, 1);
        lcd.print(CycleStr);
        break;
      case (3):
        lcd.setCursor(0, 0);
        lcd.print("[C] Start    [D] Stop");
        break;
      case (4):
        lcd.setCursor(0, 0);
        lcd.print("Stopped");
        delay(1000);
        ControlMode = 0;
        break;
    }

    if (ControlMode == 3) {
      static unsigned long _ETimer;
      if ( millis() - _ETimer >= time_taken { // Exact Timing
      _ETimer += time_taken;
      digitalWrite(VALVE, !digitalRead(VALVE));
        if ( i >= cycle; )ControlMode = 4;
        i++;
      }
    }
  }
}

what is CycleStrPos ? when i compiled the program it said that the CycleStrPos was not declared in the scope. sorry if i asked u dumb question. still in the process of learning. and i am a slow learner. sigh.

azuan:
what is CycleStrPos ? when i compiled the program it said that the CycleStrPos was not declared in the scope. sorry if i asked u dumb question. still in the process of learning. and i am a slow learner. sigh.

sorry
change it to MyStrPos It started as CycleStrPos but I decided to use it for more than one input so I changed the name and messed you up :slight_smile:
static char MyStr[17];
static byte MyStrPos = 0;

look like there are no problem with your coding. but then the lcd displayed 'stopped' all the time. when i pressed my keypad nothing happen.

I placed some serial output code in there. do yo get any response from this?

You will need to troubleshoot the code for complete functionality because I do not have a keypad to test it with and it is intended to be an example to set you in a direction that will allow you to succeed.

you may want to post the corrected code that you have gotten to compile :slight_smile:

I may be able to spot other mistakes or someone may be able to test it further that has a keypad and an LCD display.

thanks for the example sir. it really help. ;D