Setting Values in Program Using Keypad

I’m doing a project and I would like to set values in my project from the setup() loop. I want to input a value from the keypad then press # to exit the loop. the number i input will be put into a switch case which will set values in global variables and these global variables will be used for various things in the program. what these values do are not important at the moment. Below is my code

#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

char key = 0;
const byte ROWS = 4; 
const byte COLS = 4; 
char keys[ROWS][COLS] = {
  {'1','2','3','A'}, // Keypad 1 map
  {'4','5','6','B'}, 
  {'7','8','9','C'},
  {'*','0','#','D'},

};
byte rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts 
byte colPins[COLS] = {6,7,8,9}; //connect to column pinouts
int f=0;
static float SV_magnitude = 0; //0.8f
static float inverterFrequency = 0; //60
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
  lcd.init();                      // initialize the lcd 
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  //setFrequency();
  setFrequency();
}

void loop(){
  //setFrequency();
  
  //Serial.print("Inverter Frequency = ");Serial.print(inverterFrequency);Serial.print("\n");
  //Serial.print("IModulation Index = ");Serial.print(SV_magnitude);Serial.print("\n");
  //key = keypad.getKey();

  /*if (key != NO_KEY){
    lcd.setCursor(3,0);
    lcd.print(key);
    Serial.println(key);
  }*/
}

void setFrequency()
{
  
  key = keypad.getKey();
  if(f==0){
  lcd.setCursor(0,0);
  lcd.print("Enter Mode: ");
  f=1;
  }
  
  while (key != '#') //if (key != NO_KEY) Replacewhile statement and uncomment setFrequency() in loop and comment out in setup to see desired functionality
  {
    
    lcd.setCursor(12,0);
    lcd.print(key);
  }
  Serial.print(key);
  switch(key)
  {
     case '1':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 23 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 6Hz");
     inverterFrequency = 6;
     SV_magnitude = 0.0907f;
     break;
     case '2':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 46 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 12Hz");
     inverterFrequency = 12;
     SV_magnitude = 0.1814f;
     break;
     case '3':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 69 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 18Hz");
     inverterFrequency = 18;
     SV_magnitude = 0.2721f;
     break;
     case '4':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 92 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 24Hz");
     inverterFrequency = 24;
     SV_magnitude = 0.3628f;
     break;
     case '5':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 115 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 30Hz");
     inverterFrequency = 30;
     SV_magnitude = 0.4535f;
     break;
     case '6':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 138 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 36Hz");
     inverterFrequency = 36;
     SV_magnitude = 0.5442f;
     break;
     case '7':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 161 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 42Hz");
     inverterFrequency = 42;
     SV_magnitude = 0.6349f;
     break;
     case '8':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 184 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 48Hz");
     inverterFrequency = 48;
     SV_magnitude = 0.7256f;
     break;
     case '9':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 207 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 54Hz");
     inverterFrequency = 54;
     SV_magnitude = 0.8163f;
     break;
     case '0':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 230 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 60Hz");
     inverterFrequency = 60;
     SV_magnitude = 0.907f;
     break;
     default:
     break;
     
      
  }
  
}

As the code is right now its not working, i want to be able to input values from the setup().

It is never a good idea to tell us " its not working". You Need to tell us what is Happening that is wrong or what is not happending that you expected to happen.

However, looking at your code, you have while (key != '#') followed by while (key != '#')...

So, you stay in the while Loop until the # is pressed, they you check to see if the last key was a 1, 2, etc. It can't be! You get out of the Loop when # is pressed so the last key can't be 1,2, etc!

That’s why I specified in the code in a comment that if you change the ‘while’ loop to the if condition next to it, and then uncomment setFrequency() in loop and comment it out in setup you would see the desired output of the program.

#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

char key = 0;
const byte ROWS = 4; 
const byte COLS = 4; 
char keys[ROWS][COLS] = {
  {'1','2','3','A'}, // Keypad 1 map
  {'4','5','6','B'}, 
  {'7','8','9','C'},
  {'*','0','#','D'},

};
byte rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts 
byte colPins[COLS] = {6,7,8,9}; //connect to column pinouts
int f=0;
static float SV_magnitude = 0; //0.8f
static float inverterFrequency = 0; //60
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
  lcd.init();                      // initialize the lcd 
  lcd.init();
  // Print a message to the LCD.
  lcd.backlight();
  //setFrequency();
}

void loop(){
  setFrequency();
  
  //Serial.print("Inverter Frequency = ");Serial.print(inverterFrequency);Serial.print("\n");
  //Serial.print("IModulation Index = ");Serial.print(SV_magnitude);Serial.print("\n");
  //key = keypad.getKey();

  /*if (key != NO_KEY){
    lcd.setCursor(3,0);
    lcd.print(key);
    Serial.println(key);
  }*/
}

void setFrequency()
{
  
  key = keypad.getKey();
  if(f==0){
  lcd.setCursor(0,0);
  lcd.print("Enter Mode: ");
  f=1;
  }
  
  if (key != NO_KEY)
  {
    
    lcd.setCursor(12,0);
    lcd.print(key);
  }
  Serial.print(key);
  switch(key)
  {
     case '1':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 23 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 6Hz");
     inverterFrequency = 6;
     SV_magnitude = 0.0907f;
     break;
     case '2':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 46 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 12Hz");
     inverterFrequency = 12;
     SV_magnitude = 0.1814f;
     break;
     case '3':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 69 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 18Hz");
     inverterFrequency = 18;
     SV_magnitude = 0.2721f;
     break;
     case '4':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 92 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 24Hz");
     inverterFrequency = 24;
     SV_magnitude = 0.3628f;
     break;
     case '5':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 115 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 30Hz");
     inverterFrequency = 30;
     SV_magnitude = 0.4535f;
     break;
     case '6':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 138 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 36Hz");
     inverterFrequency = 36;
     SV_magnitude = 0.5442f;
     break;
     case '7':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 161 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 42Hz");
     inverterFrequency = 42;
     SV_magnitude = 0.6349f;
     break;
     case '8':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 184 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 48Hz");
     inverterFrequency = 48;
     SV_magnitude = 0.7256f;
     break;
     case '9':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 207 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 54Hz");
     inverterFrequency = 54;
     SV_magnitude = 0.8163f;
     break;
     case '0':
     lcd.clear();
     lcd.setCursor(0,0);
     lcd.print("Vs = 230 VRMS");
     lcd.setCursor(0,1);
     lcd.print("fs = 60Hz");
     inverterFrequency = 60;
     SV_magnitude = 0.907f;
     break;
     default:
     break;
     
      
  }
  
}

This demonstrates how i want the program to actually work, but i want to be able to do this from the setup not loop. When i put in loop I’m not able to input any value and the program doesn’t display the values that i have in the cases when the corresponding button is pressed

Read Several Things at a Time to get familiar with dealing with time, always good to understand and to handle your keypad use the technics of Serial Input Basics, the approach would be exactly the same but reading the keys instead of the Serial buffer

(I have this tutorial in French that you could look at to get an idea, code in post #6 should be easy to read)

How about this?

#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

const byte ROWS = 4; 
const byte COLS = 4; 

char keys[ROWS][COLS] = 
{
    {'1','2','3','A'}, // Keypad 1 map
    {'4','5','6','B'}, 
    {'7','8','9','C'},
    {'*','0','#','D'},

};

byte rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts 
byte colPins[COLS] = {6,7,8,9}; //connect to column pinouts

bool f;
static float SV_magnitude = 0; //0.8f
static float inverterFrequency = 0; //60

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

char
    key_pressed;

void setup()
{
    Serial.begin(9600);
    lcd.init();                      // initialize the lcd 
    lcd.init();    
    lcd.backlight();
    //
    lcd.setCursor(0,0);
    lcd.print("Enter Mode: ");
    //
    f = false;

}//setup

void loop()
{
    char
        key;
        
    key = keypad.getKey();
    
    if( key != NO_KEY )
    {
        if( key == '#' )
            setFrequency( key_pressed );
        else
        {
            Serial.println( key );
            key_pressed = key;
            
        }//else
         
    }//if
    
}//loop


void setFrequency( char key )
{
    if( f )
        return;        

    f = true;
    switch(key)
    {
        case '1':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 23 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 6Hz");
            inverterFrequency = 6;
            SV_magnitude = 0.0907f;
            
        break;
        case '2':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 46 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 12Hz");
            inverterFrequency = 12;
            SV_magnitude = 0.1814f;
            
        break;
        case '3':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 69 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 18Hz");
            inverterFrequency = 18;
            SV_magnitude = 0.2721f;
            
        break;
        case '4':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 92 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 24Hz");
            inverterFrequency = 24;
            SV_magnitude = 0.3628f;
            
        break;
        case '5':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 115 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 30Hz");
            inverterFrequency = 30;
            SV_magnitude = 0.4535f;
            
        break;
        case '6':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 138 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 36Hz");
            inverterFrequency = 36;
            SV_magnitude = 0.5442f;
            
        break;
        case '7':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 161 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 42Hz");
            inverterFrequency = 42;
            SV_magnitude = 0.6349f;
            
        break;
        case '8':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 184 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 48Hz");
            inverterFrequency = 48;
            SV_magnitude = 0.7256f;
            
        break;
        case '9':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 207 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 54Hz");
            inverterFrequency = 54;
            SV_magnitude = 0.8163f;
            
        break;
        case '0':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 230 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 60Hz");
            inverterFrequency = 60;
            SV_magnitude = 0.907f;
            
        break;
        
        default:
            //if key not recognized, allow user to try again
            f = false;
        break;

    }//switch
  
}//setFrequency

Blackfin I tired your code and it doesn't work :frowning: . See I'm using this as an interface for an inverter project I'm working on, and when you set up the pwm module once the program exits the setup loop you cant change certain properties of the pwm waveforms. Hence i need to set these properties before before I exit the setup loop, and i could do this if i could set the values of some global variables demonstrated in the code I've posted. Implementing it in loop is fine, but implementing it in the setup is the tricky part.

Ok my bad Blackfin the code works by itself, let me integrate it in my main program and see if it works

Blackfin that won’t work because the values are still being set in loop, i need to be able to set the values from the setup loop using the setFrequency function.

It can be made to work with a state machine. There's already one there; 'f'. When set, setFrequency no longer responds to keypresses. The values are set and then left. You could use the setting of 'f' to allow other things to happen in your loop.

Do it your way though.

I don't understand what you are trying to say...

#include <Keypad.h>
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

LiquidCrystal_I2C lcd(0x27,20,4);  // set the LCD address to 0x27 for a 16 chars and 2 line display

const byte ROWS = 4; 
const byte COLS = 4; 

char keys[ROWS][COLS] = 
{
    {'1','2','3','A'}, // Keypad 1 map
    {'4','5','6','B'}, 
    {'7','8','9','C'},
    {'*','0','#','D'},

};

byte rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts 
byte colPins[COLS] = {6,7,8,9}; //connect to column pinouts

static float SV_magnitude = 0; //0.8f
static float inverterFrequency = 0; //60

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

char
    key_pressed;

void setup()
{
    Serial.begin(9600);
    lcd.init();                      // initialize the lcd 
    lcd.init();    
    lcd.backlight();
    //
    lcd.setCursor(0,0);
    lcd.print("Enter Mode: ");

}//setup

//loop state machine states
#define SET_FREQ            0
#define DO_SOMETHING_ELSE   1
void loop()
{
    static byte
        state = SET_FREQ;
    char
        key;

    switch( state )
    {
        case    SET_FREQ:
            key = keypad.getKey();
            
            if( key != NO_KEY )
            {
                if( key == '#' )
                {
                    if( setFrequency( key_pressed ) )
                    {
                        state = DO_SOMETHING_ELSE;
                        
                    }//else
                    
                }//if
                else
                {
                    Serial.println( key );
                    key_pressed = key;
                    
                }//else
                 
            }//if
        
        break;

        case    DO_SOMETHING_ELSE:
            //do whatever you need to do after setting the frequency
            
        break;
                
    }//switch
    
}//loop


bool setFrequency( char key )
{
    switch(key)
    {
        case '1':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 23 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 6Hz");
            inverterFrequency = 6;
            SV_magnitude = 0.0907f;
            
        break;
        case '2':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 46 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 12Hz");
            inverterFrequency = 12;
            SV_magnitude = 0.1814f;
            
        break;
        case '3':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 69 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 18Hz");
            inverterFrequency = 18;
            SV_magnitude = 0.2721f;
            
        break;
        case '4':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 92 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 24Hz");
            inverterFrequency = 24;
            SV_magnitude = 0.3628f;
            
        break;
        case '5':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 115 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 30Hz");
            inverterFrequency = 30;
            SV_magnitude = 0.4535f;
            
        break;
        case '6':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 138 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 36Hz");
            inverterFrequency = 36;
            SV_magnitude = 0.5442f;
            
        break;
        case '7':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 161 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 42Hz");
            inverterFrequency = 42;
            SV_magnitude = 0.6349f;
            
        break;
        case '8':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 184 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 48Hz");
            inverterFrequency = 48;
            SV_magnitude = 0.7256f;
            
        break;
        case '9':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 207 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 54Hz");
            inverterFrequency = 54;
            SV_magnitude = 0.8163f;
            
        break;
        case '0':
            lcd.clear();
            lcd.setCursor(0,0);
            lcd.print("Vs = 230 VRMS");
            lcd.setCursor(0,1);
            lcd.print("fs = 60Hz");
            inverterFrequency = 60;
            SV_magnitude = 0.907f;
            
        break;
        
        default:
            return false;
        break;
        
    }//switch

    return true;
  
}//setFrequency

Thanks for the help but you keep misunderstanding what I’m saying. I’m using an Arduino due, and I’m using the PWM module. Once you set the period of the waveform in the setup, the only way you can change it is if there’s an interrupt, but my interrupt occurs every 0.00009 seconds which is way too fast to receive any input from a keypad. So I need to set the period value from the keypad, this can be done by setting values in the switch cases as shown in my code. But it needs to happen in the setup() not in loop(). So I need when the program starts and goes through setup() that I be prompted to input the values which will go to a specific case which would set a few global variables.

why don't you create a while loop in the setup that does not leave the setup until you've provided the right info?

That's what I was trying to do, but I'm not that good with programming so I haven't got it to work yet.

here is the code at the end of my french tutorial slightly modified to listen to the keypad in the setup until a correct password is entered. I did not try this and just did a find & replace to change the french variable names into english. Give it a try and you should not leave the setup() until you’ve entered the secret password which is 1221# (a # validate the input)

#include <Keypad.h>

const byte ROWS = 4; //4 rows
const byte COLS = 4;  //4 cols

char keys[ROWS][COLS] = {
  {'1','2','3','A'}, // Keypad 1 map
  {'4','5','6','B'}, 
  {'7','8','9','C'},
  {'*','0','#','D'},

};

byte rowPins[ROWS] = {2,3,4,5}; //connect to row pinouts 
byte colPins[COLS] = {6,7,8,9}; //connect to column pinouts

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

const byte maxMessageSize = 50;
char message[maxMessageSize + 1]; // +1 for trailing '\0'

const char endMarkerKey = '#';
const char mySecretPassword[] = "1221";

boolean listenKeypad()
{
  static byte indexMessage = 0;
  boolean waitForIncomingMessage = true;

  char c = membraneKeypad.getKey();
  if (c != NO_KEY) {
    if (c == endMarkerKey) {
      message[indexMessage] = '\0'; // terminate the c-string
      indexMessage = 0; // next time we will start fresh
      waitForIncomingMessage = false;
    } else if (indexMessage <= maxMessageSize - 1) message[indexMessage++] = (char) c; // save input if there is enough space in the buffer
  }
  return waitForIncomingMessage;
}

void setup() {
  Serial.begin(115200);

  boolean passwordEntered = false;
  while (!passwordEntered) {
    if (! listenKeypad()) {
      if (!strcmp(message, mySecretPassword)) {
        Serial.println(F("pwd OK"));
        
        // DO SOMETHING HERE WHEN INPUT IS CORRECT
        
        passwordEntered = true;
      } else {
        Serial.println(F("incorrect pwd, try again"));
      }
    }
  }
  Serial.println(F("Now entering loop()"));
}

void loop() {
  // do what you want here
}