Dynamic Display Problem/Question

Hi,

I'm working on a project where I'm using a 20x4 LCD and using a push button to "page". That part works fine.

The issue is that I'm reading data from a load cell and I'm not able to get the value to "dynamically" update on the LCD. When the code enters the "Page 2 section" it reads the value of the scale at that time but doesn't change if the scale changes, unless you "re-page" with the button.

Basically, when the display is on "Page 2" or any other page that I may add, I'd like the scale to operate as if though it's part of the main loop.

Attached is the code I'm using, some I've written and some I've gleaned from the internet.

Any help will be greatly appreciated.

/*
 * This code create a MENU structure on a 16x2 LCD screen.
 * Six (6) different screens are implemented, and you can travel
 * thru them by pressing a button on Arduino PIN 4. Each press
 * of the button advances one (1) screen. 
 * 
 * Made by Clovis Fritzen in 05/06/2017
 * http://www.FritzenMaker.com
 * http://www.FritzenLab.com.br
*/
//Based on YWROBOT's LiquidCrystal_I2C library, Library version:1.1
//Also based on the Debounce.ino sketch that comes with Arduino IDE

#include <Wire.h> 
#include <LiquidCrystal_I2C.h>
#include "HX711.h"

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

int WhichScreen =0;   // This variable stores the current Screen number
boolean hasChanged = true;
const int buttonPin = 7;    // the number of the pushbutton pin
int buttonState;             // the current reading from the input pin
int lastButtonState = LOW;   // the previous reading from the input pin
unsigned long lastDebounceTime = 0;  // the last time the output pin was toggled
unsigned long debounceDelay = 50;    // the debounce time; increase if the output flickers

HX711 LRscale;

#define calibration_factor 1190.0 //This value is obtained using the SparkFun_HX711_Calibration sketch
#define CLK  2
#define LROUT  3

int PagePin=7;

float LRWeight;


void setup()
{
  lcd.init();
  lcd.backlight();
  pinMode(buttonPin,INPUT_PULLUP);
  Serial.begin(9600);

  //BEGIN SCALE SETUP
  LRscale.begin(LROUT, CLK);
  LRscale.set_scale(calibration_factor);
  LRscale.tare();  
  //END BEGIN SCALE SETUP
   
}
void loop()
{

LRWeight = LRscale.get_units();



  if (hasChanged == true) {
    
  switch(WhichScreen) {
    case 1:
    {
      firstScreen();
    }
      break;
    
    case 2:
      {
        secondScreen();
      }
      break;
  }
}

    //-------------------------------
    // BEGIN of the switch debouncing code
    int reading = digitalRead(buttonPin);
  if (reading != lastButtonState) {
    // reset the debouncing timer
    lastDebounceTime = millis();
  }

if ((millis() - lastDebounceTime) > debounceDelay) {
    // whatever the reading is at, it's been there for longer
    // than the debounce delay, so take it as the actual current state:

    // if the button state has changed:
    if (reading != buttonState) {
      buttonState = reading;

      // only toggle the LED if the new button state is HIGH
      if (buttonState == HIGH) {
        hasChanged = true;
        WhichScreen++;
        
        
      }
    } else {
      hasChanged = false;
    }
  }
  lastButtonState = reading;
  // END of the switch Debouncing code
  // --------------------------------------
  if (WhichScreen > 2){
    WhichScreen = 1;
  }

}

void firstScreen()
  {
  lcd.clear();
  lcd.setCursor(0,0);           
  lcd.print("First Screen");
  }


void secondScreen()
  {  
  Serial.println(LRWeight);  //Printing to serial monitor, it 'updates' dynamically like I want the LCD to do
  lcd.clear();
  lcd.setCursor(4,1);
  lcd.print(LRWeight);  // This doesn't update dynamically.  It only shows the static weight at the time secondScreen() was entered.

  }

Hi,
Try, reading the load cell inside the secondscreen function.

Tom... :smiley: :+1: :coffee: :australia:

Thanks Tom,

I had given that a try earlier and it didn't work.. I gave it another try and it didn't work again. If I read from inside the secondscreen function, the serial monitor doesn't report anything either. It's like it all quits at that point.

Here's how the secondscreen function looks now:

void secondScreen()
  {
  LRWeight = LRscale.get_units();
  Serial.println(LRWeight);
  lcd.clear();
  lcd.setCursor(4,1);
  lcd.print(LRWeight);
  }

Hi,

That would be because you only post the second page when you press the button.
You need to latch the page select to page 1 or page 2, which ever you press so that it loops through that function.

You might like to look at switch.. case funtion, using the switch variable to be your page number.

https://www.arduino.cc/reference/en/language/structure/control-structure/switchcase/

Thanks.. Tom... :smiley: :+1: :coffee: :australia:

Thanks Tom,

I'm not sure I understand. I'm using the switch case as illustrated in the link you posted but I do realize I'm missing something; just haven't figured it out yet.

switch(WhichScreen) { case 1: { firstScreen(); } break;
case 2:
  {
    secondScreen();
  }
  break;

}
}

I'm just not understanding why firstscreen() or secondscreen() is called, it doesn't loop. Just runs one time.

Thanks again for your help.

This is the line that only shows a page once each time the page changes. You could remove it and get some flicker or add a second condition to re-show the page if the data has changed (you have to store the previous LRWeight value to tell if it has changed).

  if (pageHasChanged  || 
      (WhichScreen == 2 && dataHasChanged)) {

Thank you!

I had removed that line last night and it did cause some flicker... I'll take your advice and do some more testing.