Go Down

Topic: Update lcd only when data changes (Read 318 times) previous topic - next topic

jimmymcknife

Hi,

I'm building an lcd menu and clock. However I'm having trouble just updating the clock when the data changes, in other words I want to only update mins when 'int mins' changes, hours when 'int hours' changes and days when 'int days' changes. So far my attempts to compare to a previous state have rendered the lcd blank! here is the code working but with the lcd flickering due to updating everything every 1000ms:

Code: [Select]

#include <LiquidCrystal.h>
LiquidCrystal lcd(42, 31, 35, 34, 33, 32);

int starttime;
int activetime;
int prevoustime;

const int buttonPin1 = 46;                 // the numbers of the pushbutton pins
const int buttonPin2 = 48;
const int buttonPin3 = 26;

int buttonState1;                          // the current reading from the input pins
int buttonState2;
int buttonState3;
int lastButtonState1 = LOW;                // the previous reading from the input pins
         
int menuButton = 0;                        // counts button presses on menu selection button (button 1)
int lastmenuButton;

boolean select = false;
boolean back = false;

unsigned long lastDebounceTime = 0;        // the last time the output pin was toggled for each button
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long debounceDelay = 200;         // the debounce time

int days = 0;
int hours = 4;
int mins = 34;
int secs = 0;

int adays1 = 0;
int ahours1 = 0;
int amins1 = 0;

void setup(){
 
 Serial.begin(9600); 
  starttime = millis()/1000;

  lcd.begin(16, 2);
  lcd.clear();
}

void loop(){
 
activetime = (millis() / 1000);
if(prevoustime <= activetime){
   secs++;
   prevoustime = activetime;
 }

if(secs > 59){
   mins++;
   secs = 0;
 }
     
if(mins > 59){
   hours++;
   mins = 0;
 }
     
if(hours > 23){
   days++;
   hours = 0;
 }

if(days > 6){
   days = 0;
 }

if(menuButton == 0){

switch (days){
 
case 0:
  lcd.print("Sun - ");
  break;
case 1:
  lcd.print("Mon - ");
  break;
case 2:
  lcd.print("Tue - ");
  break;
case 3:
  lcd.print("Wed - ");
  break;
case 4:
  lcd.print("Thu - ");
  break;
case 5:
  lcd.print("Fri - ");
  break;
case 6:
  lcd.print("Sat - ");
  break;
}



if(hours < 10){
   lcd.print("0");
   lcd.print(hours);
 }
  else{
   lcd.print(hours);
 }
   
lcd.print(":");
   
if (mins < 10){
    lcd.print("0");
    lcd.print(mins);
 }
  else{
     lcd.print(mins);
 }

 lcd.print(":");
   
if (secs < 10){
    lcd.print("0");
    lcd.print(secs);
 }
  else{
     lcd.print(secs);
 }
}

delay(1000);
lcd.clear();




buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);

if((millis() - lastDebounceTime) > debounceDelay)     //Debounce button 1 & count presses
   if(buttonState1 == HIGH){
     menuButton++;
     lastDebounceTime = millis();
 }

if(menuButton != lastmenuButton){                 //scroll through menu options
    switch (menuButton){
      case 1:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Time");
      break;
   
      case 2:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 1");
      break;
         
      case 3:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 2");
      break;
     
      case 4:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 3");
      break;
     
      case 5:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 4");
      break;
     
      case 6:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 5");
      break;
    }
       
if(menuButton >= 7){                                         //go back to the beginning
   menuButton = 0;
 }

}
}


And here my attempt comparing that doesn't work:

Code: [Select]

#include <LiquidCrystal.h>
LiquidCrystal lcd(42, 31, 35, 34, 33, 32);

int starttime;
int activetime;
int prevoustime;

const int buttonPin1 = 46;                 // the numbers of the pushbutton pins
const int buttonPin2 = 48;
const int buttonPin3 = 26;

int buttonState1;                          // the current reading from the input pins
int buttonState2;
int buttonState3;
int lastButtonState1 = LOW;                // the previous reading from the input pins
         
int menuButton = 0;                        // counts button presses on menu selection button (button 1)
int lastmenuButton;

boolean select = false;
boolean back = false;

unsigned long lastDebounceTime = 0;        // the last time the output pin was toggled for each button
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long debounceDelay = 200;         // the debounce time

int days = 0;
int hours = 4;
int mins = 34;
int secs = 0;

int lastDays = 0;

int adays1 = 0;
int ahours1 = 0;
int amins1 = 0;

void setup(){
 
 Serial.begin(9600); 
  starttime = millis()/1000;

  lcd.begin(16, 2);
  lcd.clear();
}

void loop(){
 
activetime = (millis() / 1000);
if(prevoustime <= activetime){
   secs++;
   prevoustime = activetime;
 }

if(secs > 59){
   mins++;
   secs = 0;
 }
     
if(mins > 59){
   hours++;
   mins = 0;
 }
     
if(hours > 23){
   days++;
   hours = 0;
 }

if(days > 6){
   days = 0;
 }

if((menuButton == 0) && (days != lastDays)){

switch (days){
 
case 0:
  lcd.print("Sun - ");
  break;
case 1:
  lcd.print("Mon - ");
  break;
case 2:
  lcd.print("Tue - ");
  break;
case 3:
  lcd.print("Wed - ");
  break;
case 4:
  lcd.print("Thu - ");
  break;
case 5:
  lcd.print("Fri - ");
  break;
case 6:
  lcd.print("Sat - ");
  break;
}



if(hours < 10){
   lcd.print("0");
   lcd.print(hours);
 }
  else{
   lcd.print(hours);
 }
   
lcd.print(":");
   
if (mins < 10){
    lcd.print("0");
    lcd.print(mins);
 }
  else{
     lcd.print(mins);
 }

 lcd.print(":");
   
if (secs < 10){
    lcd.print("0");
    lcd.print(secs);
 }
  else{
     lcd.print(secs);
 }
}

delay(1000);
lcd.clear();
lastDays = days;



buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);

if((millis() - lastDebounceTime) > debounceDelay)     //Debounce button 1 & count presses
   if(buttonState1 == HIGH){
     menuButton++;
     lastDebounceTime = millis();
 }

if(menuButton != lastmenuButton){                 //scroll through menu options
    switch (menuButton){
      case 1:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Time");
      break;
   
      case 2:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 1");
      break;
         
      case 3:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 2");
      break;
     
      case 4:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 3");
      break;
     
      case 5:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 4");
      break;
     
      case 6:
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set Alarm 5");
      break;
    }
       
if(menuButton >= 7){                                         //go back to the beginning
   menuButton = 0;
 }

}
}


Any advise would be really welcome, i can't seem to get my head around it!

Cheers

PaulS

#1
Mar 12, 2017, 12:25 am Last Edit: Mar 12, 2017, 12:26 am by PaulS
Code: [Select]
lastDays = days;
Why isn't that right up where you wrote days to the LCD?

Code: [Select]
if((menuButton == 0) && (days != lastDays)){
Did you wait a whole day to see if this worked? Why is lastDays initialized to a value that is valid for days?
The art of getting good answers lies in asking good questions.

Nick_Pyner

Somewhere in that mess, I bet you have more
Code: [Select]
lcd.clear();s
than you need.

As I understand it, clearing the screen is your problem and, as a matter of principle, you should only need to clear the screen when you need to clear the screen. It is quite possible that, here, you never need to clear the screen.

If you wrote the programme properly you could update it on a regular basis, irrespective of whether the data changes, thereby getting rid of all those conditions,  and not have a problem. It is essentially just a matter of formatting the prints.

You probably have too many
Code: [Select]

        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Set
s as well.

Amongst all the other redundant programming. A case in point being
Code: [Select]

if(hours < 10){
   lcd.print("0");
   lcd.print(hours);
 }
  else{
   lcd.print(hours);
 }

where
Code: [Select]

if(hours < 10){
   lcd.print("0");
 }
lcd.print(hours);
should suffice.
And you just need to properly consider what you need to print,  what you don't, and where to print what you do need. You already know that you are not obliged start everything at 0,0.






jimmymcknife

Hi Nick,

Thank you for the pointers. I will look through some more and see if i can remove any unnecessary lcd.clear() commands and other redundant code. I am trying to 'write the programme properly' but am very new to this hence asking for help and advice. If there is anything else in my code that you think is a mess would you point it out so that I can change it and learn from my mistakes?

Cheers
James

jimmymcknife

I think i'm just really struggling with the logic of where/how to write the command that says only print if data is not the same as it was last time

jimmymcknife

Ok, so have removed all the button stuff for now and have the days seemingly only to update when there's a change... does this seem right. Is this still a mess? there is still a flicker that im trying to get rid of and i still can't work out how to update hours and mins only when there's a change.

Groove

Quote
. Is this still a mess?
Is what still a mess?
Per Arduino ad Astra

stephaneroque


Modify this:

Quote
delay(1000);
lcd.clear();
With this:
Quote
delay(1000);
And
Quote
if(menuButton == 0){
lcd.clear();
switch (days){

Nick_Pyner

If you are still flogging this dead horse
update hours and mins only when there's a change.
then
Is this still a mess?
Very probably.

In your original, you appear to be counting seconds off twice, thereby making your clock run at half speed. The following code compiles, but not tested. It isn't actually much smaller than yours, but may be closer to what you want, and at least give better grounds for discussion, by virtue of the absence of lcd.clears. I appreciate what you are trying to do, but you would be better off investing about $2-50 in a DS3231 module and properly telling the time instead of wasting it with this stuff.
Code: [Select]

#include <LiquidCrystal.h>
LiquidCrystal lcd(42, 31, 35, 34, 33, 32);

int starttime;
int activetime;
int prevoustime;

const int buttonPin1 = 46;                 // the numbers of the pushbutton pins
const int buttonPin2 = 48;
const int buttonPin3 = 26;

int buttonState1;                          // the current reading from the input pins
int buttonState2;
int buttonState3;
int lastButtonState1 = LOW;                // the previous reading from the input pins
         
int menuButton = 0;                        // counts button presses on menu selection button (button 1)
int lastmenuButton;

boolean select = false;
boolean back = false;

unsigned long lastDebounceTime = 0;        // the last time the output pin was toggled for each button
unsigned long lastDebounceTime2 = 0;
unsigned long lastDebounceTime3 = 0;
unsigned long debounceDelay = 200;         // the debounce time

int days = 0;
int hours = 4;
int mins = 34;
int secs = 0;

int lastDays = 0;

int adays1 = 0;
int ahours1 = 0;
int amins1 = 0;

void setup(){
 
 Serial.begin(9600);
  starttime = millis()/1000;

  lcd.begin(16, 2);
  lcd.clear();
}

void loop(){
   secs++;

if(secs > 59){
   mins++;
   secs = 0;
 }
     
if(mins > 59){
   hours++;
   mins = 0;
 }
     
if(hours > 23){
   days++;
   hours = 0;
 }

if(days > 6){
   days = 0;
 }

if((menuButton == 0) && (days != lastDays)){

switch (days){
 
case 0:
  lcd.print("Sun - ");
  break;
case 1:
  lcd.print("Mon - ");
  break;
case 2:
  lcd.print("Tue - ");
  break;
case 3:
  lcd.print("Wed - ");
  break;
case 4:
  lcd.print("Thu - ");
  break;
case 5:
  lcd.print("Fri - ");
  break;
case 6:
  lcd.print("Sat - ");
  break;
}

if(hours < 10){
   lcd.print("0");
 }
   lcd.print(hours);
   
lcd.print(":");
   
if (mins < 10){
    lcd.print("0");
 }
     lcd.print(mins);

 lcd.print(":");
   
if (secs < 10){
    lcd.print("0");
 }
     lcd.print(secs);
}
delay(1000);

lastDays = days;

buttonState1 = digitalRead(buttonPin1);
buttonState2 = digitalRead(buttonPin2);
buttonState3 = digitalRead(buttonPin3);

if((millis() - lastDebounceTime) > debounceDelay)     //Debounce button 1 & count presses
   if(buttonState1 == HIGH){
     menuButton++;
     lastDebounceTime = millis();
 }

if(menuButton != lastmenuButton){                 //scroll through menu options
        lcd.setCursor(0, 0);
        lcd.print("Set             ");
    switch (menuButton){
      case 1:
      lcd.setCursor(4,0);
      lcd.print("Time");
      break;
lcd.setCursor(4,0);
lcd.print("Alarm ");   
      case 2:
      lcd.setCursor(10,0);
        lcd.print("1");
      break;
         
      case 3:
      lcd.setCursor(10,0);
        lcd.print("2");
      break;
     
      case 4:
      lcd.setCursor(10,0);
        lcd.print("3");
      break;
     
      case 5:
      lcd.setCursor(10,0);
        lcd.print("4");
      break;
     
      case 6:
      lcd.setCursor(10,0);
        lcd.print("5");
      break;
    }
       
if(menuButton >= 7){                                         //go back to the beginning
   menuButton = 0;
 }
}
}

jimmymcknife

Thank you for your help. I decided not to use a clock module as I'm very new to this and wanted to try and learn a bit more through building this project with as little extra hardware as possible. Also it is only to be a timer/alarm system to trigger various events through the week on a daily/weekly/selected weekday basis and the time does not need to be particularly accurate as i will most probably be adjusting and re setting most weeks. (the project is an irrigation system, but i wanted to do it ground up in order to try and learn as i go).

Go Up