Ok so I am very new to this and I have this program that well the lcd flickers on "Menu" but no big deal there and I manage to when I press the button it changes my display to menu2 but in my menu2 i am not able to return to Menu I tried using the same program I used to toggle my button in my Menu section for it to go to Menu2 but that just messed my code and the lcd starts displaying both menus so is there a way to return from 1 menu to the other I tried using switch cases but run with the same issue I am able to enter the subMenu but the return does not work
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 6, 8, 10);
int button = 12;
int buttonState;
unsigned long buttonDown;
int Exit = 13;
int ExitState;
unsigned long buttonDown2;
int mod = 0;
void setup() {
lcd.begin(16,2);
Serial.begin(9600);
pinMode(button, INPUT_PULLUP);
pinMode(Exit, INPUT_PULLUP);
lcd.setCursor(5,0);
lcd.print("Welcome");
delay(2000);
}
void MENU(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu1");
while(buttonState == LOW){
buttonDown = millis(); //record the time the button went down
while(!buttonState) {
//wait until the button is released
if(millis()-buttonDown>100) {
//button was held for 0.1 seconds
MENU2();
break; //leave the loop
}
}
}
}
void MENU2(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu2");
while(ExitState == LOW){ //wait until the button is pushed (active-low, so TRUE=not pushed)
buttonDown2 = millis(); //record the time the button went down
while(!ExitState) {
//wait until the button is released
if(millis()-buttonDown2>100) {
//button was held for 0.1 seconds
MENU();
break; //leave the loop
}
}
}
}
void loop() {
buttonState = digitalRead(button);
ExitState = digitalRead(Exit);
MENU();
}
If you're new, you'll have a hard time making out your own menu, and most of the time I can't think of any benefits.
I highly suggest looking into many different menu management libs available out there and choose one.
Recently I had such a dilemma and settled down with LiquidMenu which was perfect for my use case and pretty simple to use.
You can see how I used it in my last project: Airsoft bomb prop - Kulverstukas's blog
Not tested, but I would personally change the code slightly to something like this: Use a variable to check what page you are on, and only refresh the LCD when a change is made (this should stop your flickering).
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 6, 8, 10);
int button = 12;
int buttonState;
unsigned long buttonDown;
int Exit = 13;
int ExitState;
unsigned long buttonDown2;
int mod = 0;
int pageDisplayed=0;
boolean pageChanged = false;
void setup() {
lcd.begin(16,2);
Serial.begin(9600);
pinMode(button, INPUT_PULLUP);
pinMode(Exit, INPUT_PULLUP);
lcd.setCursor(5,0);
lcd.print("Welcome");
delay(2000);
}
void Menu1(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu1");
}
void Menu2(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu2");
}
void Menu3(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu3");
}
void loop() {
buttonState = digitalRead(button);
while(buttonState == LOW){
buttonDown = millis(); //record the time the button went down
while(!buttonState) {
//wait until the button is released
if(millis()-buttonDown>100) {
pageDisplayed++; // increment the page to display
if (pageDisplayed>3) pageDisplayed=1;
pageChanged=true;
}
}
}
if (pageChanged) {
pageChanged=false; // reset page changed flag so only refresh the page when needed
switch(pageDisplayed) {
case 1: // page 1 chosen
Menu1();
break;
case 2: // page 2 chosen
Menu2();
break;
case 3: // page 3 chosen
Menu3();
break;
default: // something went wrong - invalid page, so set and show page 1
pageDisplayed=1;
Menu1;
break;
}
}
}
Thanks @dh68 I understand where this is going and going to see if it works for me but I just tried and it just displays the welcome and nothing else so I am going to check on this and @kulverstukass I tried just looking for a menu template but it gets to complicated for me since I need to include some sensors later on and on the ones that are already built I have a hard time where to edit and start including my program
No worries - Not got too much time to investigate at the moment but I think its the button de-bounce that is wrong. Here's a slightly more crude but simple version: Give this a bash - should be a good starting point. Also added some serial print statements for debugging that should help show what's going on
#include <LiquidCrystal.h>
LiquidCrystal lcd(2, 3, 4, 6, 8, 10);
int button = 12;
int buttonState;
unsigned long buttonDown = 0;
int Exit = 13;
int ExitState;
unsigned long buttonDown2;
int mod = 0;
int pageDisplayed=0;
boolean pageChanged = false;
void setup() {
lcd.begin(16,2);
Serial.begin(115200);
pinMode(button, INPUT_PULLUP);
pinMode(Exit, INPUT_PULLUP);
lcd.setCursor(5,0);
lcd.print("Welcome");
Serial.println("Welcome");
}
void Menu1(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu1");
Serial.println("Menu 1");
}
void Menu2(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu2");
Serial.println("Menu 2");
}
void Menu3(){
lcd.clear();
lcd.setCursor(5,0);
lcd.print("Menu3");
Serial.println("Menu 3");
}
void checkButton()
{
buttonState = digitalRead(button);
if(buttonState == LOW){
Serial.println("Button Down!");
while (digitalRead(button)==LOW)
{
Serial.println("button still pressed - wait for release!");
}
Serial.println("Button released");
pageDisplayed++; // increment the page to display
if (pageDisplayed>3) pageDisplayed=1;
pageChanged=true;
buttonDown=millis();
}
}
void loop() {
checkButton();
if (pageChanged) {
pageChanged=false; // reset page changed flag so only refresh the page when needed
switch(pageDisplayed) {
case 1: // page 1 chosen
Menu1();
break;
case 2: // page 2 chosen
Menu2();
break;
case 3: // page 3 chosen
Menu3();
break;
default: // something went wrong - invalid page, so set and show page 1
pageDisplayed=1;
Menu1();
break;
}
}
// Do what ever else you want here
// like read sensors, etc
}
And thanks a lot dh68 with this menu system i can now start working on my complete project I need to add a couple of sensors and work on some stuff but with the menu I can work on this thanks
I´ll probably be back once I get my sensors and start constructing my ventilator since that is my project but thanksa lot for the help
Hey @dh68 quick question here and don´t know if you would know
But I made some changes to the code just on what is displayed and decided to use tinkercad to add my temperature sensor since the one on tinkercad is the one I am going to use the tmp36, ok so I added it and it displays my temp but it does not update it if I change the temperature value I mean if I change from menu1 to menu2 it updates but is there a way for it to update while on menu1 without changing displays
I leave my code and my setup from tinkercad I am going to be working on this but any tips highly appreciated
#include <LiquidCrystal.h>
LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int buttonRight = 9;
int buttonRightState;
unsigned long buttonDown = 0;
int buttonLeft = 10;
int buttonLeftState;
unsigned long buttonDown2;
int pageDisplayed=0;
boolean pageChanged = false;
void setup() {
lcd.begin(16,2);
Serial.begin(9600);
pinMode(buttonRight, INPUT_PULLUP);
pinMode(buttonLeft, INPUT_PULLUP);
lcd.setCursor(0,0);
lcd.print("Sistema de Altos");
lcd.setCursor(5,1);
lcd.print("Flujos");
Serial.println("Welcome");
}
void Menu1(){
float voltageT = analogRead(A0) * 0.004882814;
float degreesC = (voltageT - 0.5) * 100.0;
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Temp= C");
lcd.setCursor(5,0);
lcd.print(degreesC);
lcd.setCursor(0,1);
lcd.print("Flujo=25Lpm ");
Serial.println("Menu 1");
}
void Menu2(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("FiO2= ");
Serial.println("Menu 2");
}
void Menu3(){
lcd.clear();
lcd.setCursor(0,0);
lcd.print("Flujo= ");
Serial.println("Menu 3");
}
void checkButton() {
buttonRightState = digitalRead(buttonRight);
buttonLeftState = digitalRead(buttonLeft);
if(buttonRightState == LOW){
Serial.println("Button Down!");
while (digitalRead(buttonRight)==LOW)
{
Serial.println("button still pressed - wait for release!");
}
Serial.println("Button released");
pageDisplayed++; // increment the page to display
if (pageDisplayed>3) pageDisplayed=1;
pageChanged=true;
buttonDown=millis();
}
if(buttonLeftState == LOW){
Serial.println("Button Down!");
while (digitalRead(buttonLeft)==LOW)
{
Serial.println("button still pressed - wait for release!");
}
Serial.println("Button released");
pageDisplayed--; // decreases the page to display
if (pageDisplayed<1) pageDisplayed=3;
pageChanged=true;
buttonDown=millis();
}
}
void loop() {
checkButton();
if (pageChanged) {
pageChanged=false; // reset page changed flag so only refresh the page when needed
switch(pageDisplayed) {
case 1: // page 1 chosen
Menu1();
break;
case 2: // page 2 chosen
Menu2();
break;
case 3: // page 3 chosen
Menu3();
break;
default: // something went wrong - invalid page, so set and show page 1
pageDisplayed=1;
Menu1();
break;
}
}
// Do what ever else you want here
// like read sensors, etc
}
And also a question I need to place values in menu 2 and 3 and have them displayed on menu1 is this possible? I am going to try to add like a counter on menu 2 and 3 for now since I dont have sensors and want the number that is in the counter in menu 2 to be displayed also in menu 1 is there like a way for this with the code that I have right now?