Saving a switch input to choose mode of operation

I have a 2560 controller with a membrane switch (keypad) on it. When I press buttons A, B or C I want it to change the mode of the "traffic light system". My issue is unless I hold it down, the read value goes back to zero and my mode of operation won't continue to execute. So how I can get the program to read the button, and then store that value unless a different button is pressed?

I was using serial print to see if I was saving the value and it doesn't! Any help would be appreciated.

                                    //traffic light PIN assignments
int RedEastWest = 23;
int YellowEastWest = 24;
int GreenEastWest = 25;
int RedturnEW = 26;
int YellowturnEW = 27;
int GreenturnEW = 28;
int RedNorthSouth = 29;
int YellowNorthSouth = 30;
int GreenNorthSouth = 31;
int RedturnNS = 32;
int YellowturnNS = 33;
int GreenturnNS = 34;


                                  // photocell PIN assignments
int ldrPin = 0; // A0 Pin connected to LDR

                                  // pedestrian button assignments
int Buzzer = 12;
int Crossbtn = 22;

                                  // button pad PIN assignments
#include <Keypad.h>
const byte ROWS = 4; //four rows
const byte COLS = 4; //four columns
//define the cymbols on the buttons of the keypads
char hexaKeys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {43, 42, 41, 40}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {39, 38, 37, 36}; //connect to the column pinouts of the keypad

//initialize an instance of class NewKeypad
Keypad customKeypad = Keypad( makeKeymap(hexaKeys), rowPins, colPins, ROWS, COLS);

                                // LCD output PIN assignments
#include <LiquidCrystal.h>

// initialize the library with the numbers of the interface pins
LiquidCrystal lcd(2, 3, 4, 5, 6, 7);

// Setup steps for each component as listed
void setup() 
{
  // define modes for each component
  // Traffic lights
  pinMode(RedEastWest, OUTPUT);
  pinMode(YellowEastWest, OUTPUT);
  pinMode(GreenEastWest, OUTPUT);
  pinMode(RedNorthSouth, OUTPUT);
  pinMode(YellowNorthSouth, OUTPUT);
  pinMode(GreenNorthSouth, OUTPUT);
  pinMode(RedturnEW, OUTPUT);
  pinMode(YellowturnEW, OUTPUT);
  pinMode(GreenturnEW, OUTPUT);
  pinMode(RedturnNS, OUTPUT);
  pinMode(YellowturnNS, OUTPUT);
  pinMode(GreenturnNS, OUTPUT);


  
  // photocell no setup step


  // Pedestrian button
  pinMode(Crossbtn, INPUT);
  pinMode(Buzzer,OUTPUT);//initialize the buzzer pin as an output
  
  // button pad has no setup step
  Numberpad();
  
  
  // LCD setup
  // set up the LCD's number of columns and rows:
  lcd.begin(16, 2);
  // Print a message to the LCD.
  lcd.print("Traffic Control");
  delay(2000);
  // scroll 13 positions (string length) to the left
  // to move it offscreen left:
  for (int positionCounter = 0; positionCounter < 16; positionCounter++) {
    // scroll one position left:
    lcd.scrollDisplayLeft();
    // wait a bit:
    delay(150);
  }

  Serial.begin(9600); 
}

void loop() 
{
  // Check for keypad entry to select mode
    char choice = Numberpad();
    Serial.println(choice);    
    if (choice == 'A') {
      ModeStreet();}
      else if  (choice == 'B') {
        ModeAvenue();}
        else if (choice == 'C') {
          ModeNight();  }
          
}

char Numberpad(){
  
  char lastKey;
  char  customKey = customKeypad.getKey();
   
  if (customKey == 'A'){
    lcd.begin(16,2);
    lcd.setCursor(0,0);
    lcd.print("  Street Mode");
    lastKey = customKey;
    
  }
  else if (customKey == 'B'){
    lcd.begin(16,2);
    lcd.setCursor(0,0);
    lcd.print("  Avenue Mode");
    lastKey = customKey;
    
  }
  else if (customKey == 'C'){
    lcd.begin(16,2);
    lcd.setCursor(0,0);
    lcd.print("   Night Mode");
    lastKey = customKey;
  }
  else if (customKey == 0) {
    lastKey = lastKey;
  }
  return lastKey;
}


void ModeStreet() 
{
  Numberpad();
  digitalWrite(RedEastWest, HIGH);
    delay(2000);

 /*   Code for the alarm/buzzer for Pedestrian crosswalk
 unsigned char i;
 while(1)
 {
   //output an frequency
   for(i=0;i<10;i++)
   {
    digitalWrite(Buzzer,HIGH);
    delay(1000);//wait for 1ms
    digitalWrite(Buzzer,LOW);
    delay(1000);//wait for 1ms
    Serial.print(i);
    
    
    }
    //output another frequency
     for(i=0;i<5;i++)
      {
        digitalWrite(Buzzer,HIGH);
        delay(400);//wait for 2ms
        digitalWrite(Buzzer,LOW);
        delay(1000);//wait for 2ms
        Serial.print(i );
      }                                   */
}

void ModeAvenue()
{
    Numberpad();
    digitalWrite(RedEastWest, HIGH);
    delay(2000);
}

void ModeNight()
{
   Numberpad();
   digitalWrite(RedEastWest, HIGH);
    delay(2000);```

why not use the keypress to set a (global/static) "mode" variable that determines which mode to invoke?

Is there a reference for that? I'm new to this platform normally I'm in PLC world!

consider following which simulates some of your routines


char
Numberpad ()  {
    if (Serial.available ())  {
        return Serial.read();
    }

    return 0;
}

void ModeStreet ()  { Serial.println (__func__);  };
void ModeAvenue ()  { Serial.println (__func__);  };
void ModeNight  ()  { Serial.println (__func__);  };

// -----------------------------------------------------------------------------
char mode;

void loop()
{
    char choice = Numberpad();
    Serial.println(choice);

    if ('A' == choice || 'B' == choice || 'C' == choice)
        mode = choice;

    switch (mode)  {
    case 'A':
        ModeStreet();
        break;

    case 'B':
        ModeAvenue();
        break;
    case 'C':
        ModeNight();
        break;
    }
}

void setup ()
{
    Serial.begin (9600);
}
1 Like

Thank you for your input! I will look at your code until it makes sense to me! lol. I appreciate it! This definitely gets me in the right direction.

This is working for a Serial input with my keyboard. But I have a membrane keypad switch for the input. Is there a buffer or read program for that? I will search for one or am I overthinking it?

i don't have the keypad you have so i simulated it with my version of NumberPad(). you should use your library

1 Like

I figured it out! My problem was using the delay function. Once I searched multi-tasking in Arduino topics, I learned I needed to use a timer and then execute operations or functions according to time elapsed instead of trying to latch a temporary input. This freed up my loop to always be able to see a button press. Thanks for your help!