Fresh output to LCD from any sensor in if statement

I'm currently trying to use my basic knowledge to create a heat sensor using TMP36. Everything works fine, except the 1602 LCD Display doesn't update its output from the temperature output of TMP36. Without the if or switch statement, it works like I intended. I put a conditional statement so that I can toggle each input from different sensors, someday in the future (so I put the "Hello World" for sake of clarity ;)).

Here's the code:

#include <LiquidCrystal.h>

LiquidCrystal lcd(12, 11, 5, 4, 3, 2);
int ButtonPin = 8;
int ButtonOld = 0;
int ScreenState = 0;

void setup() {
  Serial.begin(9600);
  pinMode(A0, INPUT); //TMP36 pin
  pinMode(ButtonPin, INPUT);
  lcd.begin(16, 2);
}

void loop() {
  int ButtonNew = digitalRead(ButtonPin);

  if(ButtonOld == 0 && ButtonNew == 1){
    switch (ScreenState){
      case 0: //below is Temperature/TMP36 display
        TempScreen();
      	ScreenState = 1;
        break;
      case 1: //below is the Hello World Display
        lcd.clear();
        //add humidity below
        lcd.setCursor(0, 0);
        lcd.print("Hello World");
        delay(1000); 
        ScreenState = 0;
      	break;
      }
  }
  
  ButtonOld = ButtonNew;
  delay(100);
}

void TempScreen(){
   // community calculation
  float voltage = analogRead(A0) * 5;
  voltage /= 1024;
  float temp = (voltage - 0.5) * 100 ; 

  // temperature output
  lcd.setCursor(0, 0);
  lcd.print("TEMPERATURE:");
  
  lcd.setCursor(0, 1);
  lcd.print(temp);
  lcd.print("°C");
  delay(1000);
}

Also, any tips to make C++ code more readable or neat would be gladly appreciated :slightly_smiling_face:

Suggest you wire your switches as S3 is wired below.

Use:

pinMode(ButtonPin, INPUT_PULLUP);

Look for for a switch closed condition i.e. LOW



// https://forum.arduino.cc/t/fresh-output-to-lcd-from-any-sensor-in-if-statement/932275/1

//*********************************************************************************
// Version   YY/MM/DD    Description
// =======   ========    ===========
// 1.00      21 12 04    Working sketch LCD and the analog TMP36 temperature sensor
//
//


//********************************************************************************
//#define serialLCDisBeingUsed  //uncomment if you have a serial LCD               <-----<<<<<

#ifdef  serialLCDisBeingUsed
#include <Wire.h>

//Use I2C library:     https://github.com/duinoWitchery/hd44780
//LCD Reference:       https://www.arduino.cc/en/Reference/LiquidCrystal

#include <hd44780.h>   //main hd44780 header

//NOTE:
//hd44780_I2Cexp control LCD using I2C I/O expander backpack (PCF8574 or MCP23008)
//hd44780_I2Clcd control LCD with native I2C interface (PCF2116, PCF2119x, etc...)

//I2C expander i/o class header
#include <hd44780ioClass/hd44780_I2Cexp.h> 

//If you do not know what your I2C address is, first run the 'I2C_Scanner' sketch
//OR
//Run: I2CexpDiag.ino
//C:\Users\YourName\Documents\Arduino1.69\libraries\hd44780\examples\ioClass\hd44780_I2Cexp\I2CexpDiag

//hd44780_I2Cexp lcd(0x3F);
hd44780_I2Cexp lcd(0x27);

//********************************************************************************

#else

#include <LiquidCrystal.h>

// LCD pin         4   6  11  12  13  14
//                RS  EN  D4  D5  D6  D7
LiquidCrystal lcd(12, 11,  5,  4,  3,  2);

#endif

//********************************************************************************

const byte buttonPin    = 8;
const byte heartbeatLED = 13;


byte buttonOld;
byte screenState;

//timing stuff
unsigned long switchMillis;
unsigned long heartbeatMillis;


//*********************************************************************************
void setup()
{
  Serial.begin(9600);

  pinMode(heartbeatLED, OUTPUT);

  pinMode(buttonPin, INPUT_PULLUP);

  lcd.begin(16, 2);

  lcd.setCursor(0, 0);
  //                   111111
  //         0123456789012345
  lcd.print("Testing 12345678");

} //END of setup()


//*********************************************************************************
void loop()
{
  //***************************************
  //time to toggle the heartbeat LED ?
  if (millis() - heartbeatMillis >= 500)
  {
    //restart the TIMER
    heartbeatMillis = millis();

    //toggle LED
    digitalWrite(heartbeatLED, !digitalRead(heartbeatLED));

  }

  //*********************************
  //is it time to check the switches ?
  if (millis() - switchMillis >= 50)
  {
    //restart this TIMER
    switchMillis = millis();

    checkSwitches();
  }

  //*********************************
  //other non blocking code goes here
  //*********************************

} //END of loop()


//*********************************************************************************
void checkSwitches()
{
  byte buttonNew = digitalRead(buttonPin);

  if (buttonOld != buttonNew)
  {
    //update to the new state
    buttonOld = buttonNew;

    //was the switch closed ?
    if (buttonNew == LOW)
    {
      switch (screenState)
      {
        case 0:
          tempScreen();

          screenState = 1;

          break;
        
        case 1:
          lcd.clear();

          lcd.setCursor(0, 0);
          //                   111111
          //         0123456789012345
          lcd.print("Humidity:       ");

          screenState = 0;

          break;
      }
    }
  }

} //END of   checkSwitches()


//*********************************************************************************
void tempScreen()
{
  //TMP36 pin
  float value = analogRead(A0);
  value = (value * 5.0) / 1024.0;
  value = (value - 0.5) * 100 ;
  
  //temperature output
  lcd.setCursor(0, 0);
  //                   111111
  //         0123456789012345
  lcd.print("TEMPERATURE:    ");

  lcd.setCursor(0, 1);
  //                  111111
  //        0123456789012345
  //        XXX.XX  °C
  lcd.print(value);

  lcd.setCursor(8, 1);
  lcd.print(char(223)); // °
  lcd.print("C");

} //END of  TempScreen()
1 Like

Yes, if it is left in screenState == 0, it won't refresh the display if the temperature changes.

You want something like this for your loop() (untested):

void loop() {
  int ButtonNew = digitalRead(ButtonPin);

  if (ButtonOld == 0 && ButtonNew == 1) {
    // button press detected. Toggle screenState
    if ( screenState == 0 ) screenState = 1 ;
    else screenState = 0 ;
  }

  switch (ScreenState) {
    case 0: //below is Temperature/TMP36 display
      TempScreen();
      break;
    case 1: //below is the Hello World Display
      lcd.clear();
      //add humidity below
      lcd.setCursor(0, 0);
      lcd.print("Hello World");
      delay(1000);
      break;
  }
  
  ButtonOld = ButtonNew;
  delay(100);
}
1 Like

@6v6gt
Perfect, it works flawlessly without the delay in both void loop and TempScreen. Thank you!

@LarryD
Thank you for the 12C module address too, mine is still on shipment so I just use whatever I have. And the code work flawlessly, although I'm still trying to understand this part:

Also, what is the difference between the S3 switch from the diagram above and mine?
Screen Shot 2021-12-05 at 4.19.51 PM
(sorry for the Fritzing diagrams)

Thank you for the 12C module address too, mine is still on shipment so I just use whatever I have. And the code work flawlessly, although I'm still trying to understand this part:

The code should work with either I2C or parallel LCDs.

If I2C is desired, remove the // comment marks on the line of code with the arrow i.e. <-----<<<<<


That block of code toggles the LED on pin 13 (on board LED) .
It tells you if your code is free from blocking (stopping or stuttering).

if (millis() - heartbeatMillis >= 500)

The above is acting as a non blocking TIMER of 500ms


Your switch circuit is the same except the S3 version uses an internal resistor inside the Arduino.

1 Like

I see now, thanks :smiley: