Switch Case Auto Update?

Greetings!

We have made a simple sketch to use a keypad with a switch case statement to output a message on the COM port monitor. Below is the code:

#include <Keypad.h>

const byte ROWS = 4;        //Four rows
const byte COLS = 4;        //Four columns

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

byte rowPins[ROWS] = {13, 12, 11, 10};  //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6};     //connect to the column pinouts of the keypad

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

void setup() {

pinMode(4, INPUT);      // Pin 4 set as an input

Serial.begin(9600);

}

void loop() {

  char key = keypad.getKey();

  switch (key) {
    // ...
    // ...
    // ...
    // ...
    
  case '9':
  if (digitalRead(4) == HIGH) {
      Serial.println("ON");
    }
    else {
      Serial.println("OFF");
    }
    break;
  }
}

To toggle Pin 4 HIGH to LOW, we use a wire to go between the GND pin and 3.3V, which seems to work fine. The question is how to change the sketch so that it automatically updates the ON/OFF state once we enter the case statement?

In other words, in order for the state to change, we have to swap to either GND or 3.3V THEN press keypad number 9 to see the update on the COM port monitor. We would like it to automatically update after we initially press 8 for the first time. This will be placed in an LCD menu screen later on and has to automatically update.

Hello

You have to do something like this

void loop() {

  char key = keypad.getKey();
  static bool key9WasPressed = false;
  
  switch (key) {
    // ...
    // ...
    // ...
    // ...
    
    case '9':
      key9WasPressed = true;
      break;
  }
  
  
  if ( key9WasPressed == true )
  {
    if (digitalRead(4) == HIGH) {
      Serial.println("ON");
    }
    else {
      Serial.println("OFF");
    }
  }
}

Of course, you have to reset key9WasPressed to false when needed.

1 Like

Oh I see! It will need to change to false when a different menu gets selected. How would it change to false like that?

If you condition the switch state with some change-of-state code ( In the IDE: File-examples-digital- state change detection ) it'll reset to false 'automatically'.  That is, when the switch is actuated you'll get one pass through the code with a (boolean) signal you might call 'switchWasPressed' being true.  Do everything you need to do for a switch closure and next time through switchWasPressed will be false.

what?

Not sure if I understand right what this means.

you connect power to the microcontroller
You press the "8"-key for the very first time and only after this first "press-key-"8"
the automatic updating shall work?

The updating itself is:
if IO-pin 4 detects HIGH update to messageto to be "ON"
if IO-pin 4 detects LOW update to message to be "OFF"

What I do not understand is

which case-statement do you mean?

best regards Stefan

Case '9', meaning once key 9 is pressed.

Essentially, the LCD menu will show different things such as LED states. For example, once a menu selection is pressed, it will show the following:

LED 1 is ON
LED 2 is ON
LED 3 is OFF
LED 4 is ON
.
.
.

As long as the user is within this menu, these items should automatically update if the LEDs turn on and off. Hope that clears things up!

no it does not really clear things up.

As long as you try to save time by posting too short worded descriptions all that happens is that proceeding in your project needs more time because another round of asking back is played.

How many rounds of playing this ping-pong-game of

too short description - asking back again

do you need to understand this?

Guix's response was spot on. I've provided the code and answered your previous question of "which case" statement. Surely this isn't rocket science to understand and I believe you should refrain from responding if you have nothing of value to comment.

Restating with "more detail":
My son and I are creating a project where we plan on using a 4x20 character LCD and a keypad to display things in different menus. One of those menus will be selected using key 9. Once key 9 is pressed, the LCD will switch to a screen that has the statuses of multiple LEDs, as mentioned in my other reply. When we toggle these LEDs on and off, their states need to update on the LCD menu as they change. The user should only have to press the "9" key ONCE to get into the LCD menu and see the LEDs displayed as being ON or OFF as we toggle the Pins from HIGH to LOW.

I hope you do not connect GND and 3.3V by a wire like you wrote... :wink:

Is it correct that you connect pin 4 by wire to 3.3V or GND?

If yes, there is more simple way to achieve this:

pinMode(4,INPUT_PULLUP);

This activates an internal pull-up resistor which keeps the input HIGH. To switch to LOW you can use a switch or button that connects pin 4 to GND.

It also makes sure that you always have a defined signal at pin 4.

There is still the issue of "bouncing" where the status of the pin may toggle several times between high and low due to the mechanical behavior of usual switches/ buttons. That may lead to unexpected behavior of the software as microcontrollers are damned quick. So within micro or at least milliseconds states may change several (ten, twenty, thirty?) times. I would suggest to google for "debouncing Arduino".

Good luck!

1 Like

Thank you for the insight! Yes, for testing purposes, we currently have a wire connected to pin 4 and we insert the other end into GND or 3.3V to see the state change, but we will try this in the future!

giving an overview about the complete functionality enables to receive more than a short detail-answer

#include <Keypad.h>

const byte ROWS = 4;        //Four rows
const byte COLS = 4;        //Four columns

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

byte rowPins[ROWS] = {13, 12, 11, 10};  //connect to the row pinouts of the keypad
byte colPins[COLS] = {9, 8, 7, 6};     //connect to the column pinouts of the keypad

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


// all those "repetetive variables Led1..Led4 
// can be replaced by using arrays
// this would make the code shorter 
// but requires to learn how arrays work
const byte Led1_Pin = 2;
const byte Led2_Pin = 3;
const byte Led3_Pin = 4;
const byte Led4_Pin = 5;

byte Led1State;
byte Led2State;
byte Led3State;
byte Led4State;

byte lastLed1State;
byte lastLed2State;
byte lastLed3State;
byte lastLed4State;

boolean LedChangeDetected = false;

boolean ShowLEDStates = false;


void PrintLEDStatesOnLCD() {
  Led1State = digitalRead(Led1_Pin);
  
  if ( lastLed1State != Led1State ) { // check if a state-CHANGE has occurred
    // only in case a state-CHANGE has REALLY happened update display etc.
    lastLed1State = Led1State;        // update variable lastLed1State

    if (Led1State == HIGH) {
      //printToLCD "ON"
    }
    else {
      //printToLCD "OFF"      
    }
  }
  // same for Led2, Led3, Led4
  // code can be shortened by using an array for all Leds
}


void setup() {
  //pinMode(4, INPUT);      // Pin 4 set as an input
  // ATTENTION !!
  // make sure to adjust baudrate in serial monitor to 115200 baud
  Serial.begin(115200); 
  Serial.println( F("setup-Start") );
  pinMode(Led1_Pin,OUTPUT);
  pinMode(Led2_Pin,OUTPUT);
  pinMode(Led3_Pin,OUTPUT);
  pinMode(Led4_Pin,OUTPUT);
}


void loop() {

  char key = keypad.getKey();

  switch (key) {
    case '1':
      ShowLEDStates = false; 
      break;
    
    // ...
    // ...
    // ...
    // ...

    case '9':
      ShowLEDStates = true; 
      break;
  }

  if (ShowLEDStates) { // a boolean variable contains value true/false ITSELF
    PrintLEDStatesOnLCD();
  }
}

best regards Stefan

1 Like

Making a common project with your son is a great thing to have fun, gain experience and spend some interesting time in a useful way!

Glad if my post was of assistance!

What you probably might find also useful as a basis for your sketch is something called "state machine". It takes a little time to get behind its idea, but is key to a lot of otherwise complex designs.

There is a comprehensive example available at Wokwi which I wrote some time ago:

https://wokwi.com/projects/322586637175358035

Feel free to check it out (or not)... There are quite some comments in the code. If you do have questions just post it here.

1 Like

We will definitely check it out!

Currently, we are having trouble getting a working menu structure made with what we have. I don't believe the "LiquidCrystal" library is compatible with the LCD we are using, as it has a US2066 driver, but once we sort this out we will definitely give it a shot!

So good luck and success to sort this out... :wink:

If things were easy what would be the joy of success?

1 Like

Exactly!

There is a library on GitHub for the US2066-driver.

Though the description says
This code is written for the Arduino Mega.

Which microcontroller are you using?

Arduino UNO

I installed the US2066-library and tried to compile it for Arduino Uno.
This US2066-library uses direct port-manipulation specific to the Ardunio-Mega
This results in compiler-errors for the arduino uno.

I guess you don't want to run up the learning-curve for becoming an LCD-driverchip specialist.

Then there are three options:
asking in the arduino-forum for support in adapting the US2066-driver-library to the Arduino Uno

buying a LCD that has a much more popular driver-chip with Arduino-Uno-compatible drivers

buying an Arduino Mega to be able to use the US2066-driver LCD

Thank you for the research. We may just use this US2066 LCD in 8-bit parallel mode and use their code as a reference. It looks really nice, probably since it has OLEDs. The one issue then would be implementing the call-functions to update the menus when a condition is set. Could get clunky, but we'll see