ESP8266 - LCD Menu Issues

Hi,

I have a weather station project involving a couple of sensors and an ESP8266. I have all of my statistics go to a website, which works fine. I decided to add an LCD screen to it to view the information on site. I have one menu button, simply to toggle between readings (starts up showing air temperature, press the button once to view a new measurement, etc. ).

The problem that I am having is that something is blocking my loop for about 5 seconds. The light on the ESP8266 blinks every time that 5 seconds passes, and it only detects that button press while the button is pressed while the light blinks. With that said, I used to have a line in the HTML part of the code that auto-refreshed the page every 5 seconds, but I have since removed it, but it seems to either have stuck or something is blocking the loop for that 5 second duration.

I do have a pulldown resistor on the logic pin to keep the unpressed state low until the button has been pressed.

Here is the code that I have:

#include <ESP8266WiFi.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

//Static IP setup
IPAddress staticIP (10, 0, 0, 50);
IPAddress gateway (10, 0, 0, 1);
IPAddress subnet (255, 255, 255, 0);

//wifi information
const char* ssid = "SSID";
const char* password = "PASSWORD";

//server
WiFiServer server(80);

//integers
int ledPin = 16;
int menuButtonPushCounter = 0;
int menuButtonState = 0;
int menuLastButtonState = 0;
const int menuButton = 14;
const int adcPin = A0;

//definitions
#define DHTTYPE DHT11
#define DHTPIN 0
#define ONE_WIRE_BUS 2
Adafruit_BMP085 bmp;
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd = LiquidCrystal_I2C (0x27, 16, 2);

//floats
float WaterC = 0;
float WaterF = 0;
const float m = -5.59701;

//Millis Timing

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(menuButton, INPUT);

  WiFi.hostname("Greenhouse Monitor");
  WiFi.begin(ssid, password);
  WiFi.disconnect();
  WiFi.hostname ("Greenhouse Monitor");
  WiFi.config(staticIP, subnet, gateway);
  WiFi.begin(ssid, password);

  dht.begin();
  lcd.init();
  lcd.backlight();
  
  if (!bmp.begin()){
    Serial.println("Check wiring...");
    while(1);
  }
  server.begin(); 
}

void loop() {

//Barometric Pressure
  float PressurePa = bmp.readPressure();
  float PressureInHg = (PressurePa + 3966)/3386 ;

//Temperature
  float TempC = bmp.readTemperature();
  float TempF = (TempC *9/5) + 32;

//humidity
  float humidity = dht.readHumidity();

//Dew Point
  float dewPointF = TempF - ((100 - humidity) * 0.36);
  float dewPointC = (dewPointF - 32) * 5/9;
  
//Water Temperature
  sensors.requestTemperatures();
  WaterC = sensors.getTempCByIndex(0);
  WaterF = sensors.toFahrenheit(WaterC);

//pH Sensor
  float Po = analogRead(adcPin) * 3.3 / 1024;
  float phValue = 7 - (1.65 - Po) * m;

//Menu Button
  menuButtonState = digitalRead(menuButton);
    if (menuButtonState != menuLastButtonState){
      if (menuButtonState == HIGH){
        menuButtonPushCounter++;
      }
      delay(50);
    }

//LCD Menus
        if (menuButtonPushCounter == 0){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Air Temp");
          lcd.setCursor(0, 1);
          lcd.print(TempF);
          lcd.setCursor(6, 1);
          lcd.print("F");
  }else
        if (menuButtonPushCounter == 1){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Humidity");
          lcd.setCursor(0, 1);
          lcd.print(humidity);
  }else
        if (menuButtonPushCounter == 2){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Dew Point");
          lcd.setCursor(0, 1);
          lcd.print(dewPointF);
  }else
        if (menuButtonPushCounter == 3){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Pressure");
          lcd.setCursor(0, 1);
          lcd.print(PressureInHg);
  }else
        if (menuButtonPushCounter == 4){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("Water Temp");
          lcd.setCursor(0, 1);
          lcd.print(WaterF);
  }else
        if (menuButtonPushCounter == 5){
          lcd.clear();
          lcd.setCursor(0, 0);
          lcd.print("pH Level");
          lcd.setCursor(0, 1);
          lcd.print(phValue);
  }else
        if (menuButtonPushCounter == 6){
          menuButtonPushCounter = 0;
  }else{}
  
   WiFiClient client = server.available();
   String request = client.readStringUntil('\r');

      if (client){
          client.println("HTTP/1.1 200 OK"); //send new page
          client.println("Content-Type: text/html");
          client.println();

          client.println("<HTML>");
          client.println("<HEAD>");
          client.println("<TITLE> Greenhouse Monitor</TITLE>");
          client.println("</HEAD>");
          client.println("<BODY bgcolor=#000000>");
          client.println("<H1 style=\"color:Green;\">Shenango Greenhouse Monitor</H1>");
          client.println("<hr>");
          client.println("
");

          client.println("<H1 style=\"color:Green;\">Grow Lights:</H1>");

          client.println("<H3><a href=\"/?GROWON\"\">Turn On Growlights</a>
</H2>");
          client.println("<H3><a href=\"/?GROWOFF\"\">Turn Off Growlights</a>
</H2>");

          client.println("<H1 style=\"color:Green;\">Air Temperature:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(TempC);
          client.println("C");
          client.println("
");
          client.println(TempF);
          client.println("F");
          client.println("</H3>");
          
          client.println("<H1 style=\"color:Green;\">Relative Humidity:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(humidity);
          client.println("%");
          client.println("</H3>");

          client.println("<H1 style=\"color:Green;\">Dew Point</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(dewPointC);
          client.println(" C");
          client.println("
");
          client.println(dewPointF);
          client.println(" F");
          client.println("</H3>");

          client.println("<H1 style=\"color:Green;\">Barometric Pressure:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(PressurePa);
          client.println(" Pa");
          client.println("
");
          client.println(PressureInHg);
          client.println(" InHg");
          client.println("</H3>");

          client.println("<H1 style=\"color:Green;\">Water Temperature:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(WaterC);
          client.println("C");
          client.println("
");
          client.println(WaterF);
          client.println("F");
          client.println("</H3>");

          client.println("<H1 style=\"color:Green;\">Water Acidity:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(phValue);
          client.println(" pH");
          client.println("</H3>");
          
          client.println("<H1 style=\"color:Green;\">Flow Valve 1:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(" L/Min");
          client.println("</H3>");

          client.println("<H1 style=\"color:Green;\">Flow Valve 2:</H1>");
          client.println("<H3 style=\"color:White;\">");
          client.println(" L/Min");
          client.println("
");
          client.println("</H3>");  

          client.println("</BODY>");
          client.println("</HTML>");
  }

            if (request.indexOf("/?GROWON") != -1){
              digitalWrite(ledPin, LOW);
            }
            if (request.indexOf("/?GROWOFF") != -1){
              digitalWrite(ledPin, HIGH);
            }
          delay(10);
          client.stop();
}

Could anyone provide some intel on why this is happening? I have been trying to fix this for days, and have nothing else to try. I am at a loss right now lol. Anyways, any input of any kind is greatly appreciated. Thanks, and have a good one!

You are doing this unconditionally in the loop():
String request = client.readStringUntil('\r') ;

It waits for a timeout.

Maybe do it only if client.available() == true

6v6gt:
You are doing this unconditionally in the loop():
String request = client.readStringUntil('\r') ;

It waits for a timeout.

Maybe do it only if client.available() == true

So basically make an if statement that says if the client is available, then do the string request = client.readStringUntil('\r');

6v6gt:
You are doing this unconditionally in the loop():
String request = client.readStringUntil('\r') ;

It waits for a timeout.

Maybe do it only if client.available() == true

Well I just thought of something. Couldn't I omit that line of code and somehow set the timeout to a value less than 5 seconds? I am not sharp with HTMLstuff, so please correct me if I am wrong! this is just me thinking LOL!

So I am trying to use voids to condense some of the code in the loop so that I can try to fix some of the timing issues. The issue that I am running into is that now my variables aren't in the scope anymore.

Here is my current code. I have no idea what is going on.

#include <ESP8266WiFi.h>
#include <Wire.h>
#include <Adafruit_BMP085.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <LiquidCrystal_I2C.h>

//Static IP setup
IPAddress staticIP (10, 0, 0, 50);
IPAddress gateway (10, 0, 0, 1);
IPAddress subnet (255, 255, 255, 0);

//wifi information
const char* ssid = "SSID";
const char* password = "PASSWORD";

//server
WiFiServer server(80);

//integers
int ledPin = 16;
int menuButtonPushCounter = 0;
int menuButtonState = 0;
int menuLastButtonState = 0;
const int menuButton = 14;
const int adcPin = A0;

//definitions
#define DHTTYPE DHT11
#define DHTPIN 0
#define ONE_WIRE_BUS 2
Adafruit_BMP085 bmp;
DHT dht(DHTPIN, DHTTYPE);
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
LiquidCrystal_I2C lcd = LiquidCrystal_I2C (0x27, 16, 2);

//floats
float WaterC = 0;
float WaterF = 0;
const float m = -5.59701;

//Millis Timing
unsigned long previousMillis1 = 0;
unsigned long previousMillis2 = 0;
const long interval1 = 100;
const long interval2 = 3000;

void setup() {
  Serial.begin(9600);
  pinMode(ledPin, OUTPUT);
  pinMode(menuButton, INPUT);

  WiFi.hostname("Greenhouse Monitor");
  WiFi.begin(ssid, password);
  WiFi.disconnect();
  WiFi.hostname ("Greenhouse Monitor");
  WiFi.config(staticIP, subnet, gateway);
  WiFi.begin(ssid, password);

  dht.begin();
  lcd.init();
  lcd.backlight();

  if (!bmp.begin()) {
    Serial.println("Check wiring...");
    while (1);
  }
  server.begin();
}

void sensorReadings() {
  //Barometric Pressure
  float PressurePa = bmp.readPressure();
  float PressureInHg = (PressurePa + 3966) / 3386 ;

  //Temperature
  float TempC = bmp.readTemperature();
  float TempF = (TempC * 9 / 5) + 32;

  //humidity
  float humidity = dht.readHumidity();

  //Dew Point
  float dewPointF = TempF - ((100 - humidity) * 0.36);
  float dewPointC = (dewPointF - 32) * 5 / 9;

  //Water Temperature
  sensors.requestTemperatures();
  WaterC = sensors.getTempCByIndex(0);
  WaterF = sensors.toFahrenheit(WaterC);

  //pH Sensor
  float Po = analogRead(adcPin) * 3.3 / 1024;
  float phValue = 7 - (1.65 - Po) * m;
}

void publishWebpage() {
  WiFiClient client = server.available();
  String request = client.readStringUntil('\r');

  if (client) {
    client.println("HTTP/1.1 200 OK"); //send new page
    client.println("Content-Type: text/html");
    client.println();

    client.println("<HTML>");
    client.println("<HEAD>");
    client.print("<meta http-equiv=\"refresh\" content=\"2\">");
    client.println("<TITLE> Greenhouse Monitor</TITLE>");
    client.println("</HEAD>");
    client.println("<BODY bgcolor=#000000>");
    client.println("<H1 style=\"color:Green;\">Shenango Greenhouse Monitor</H1>");
    client.println("<hr>");
    client.println("
");

    client.println("<H1 style=\"color:Green;\">Grow Lights:</H1>");

    client.println("<H3><a href=\"/?GROWON\"\">Turn On Growlights</a>
</H2>");
    client.println("<H3><a href=\"/?GROWOFF\"\">Turn Off Growlights</a>
</H2>");

    client.println("<H1 style=\"color:Green;\">Air Temperature:</H1>");
    client.println("<H3 style=\"color:White;\">");
    client.println(TempC);
    client.println("C");
    client.println("
");
    client.println(TempF);
    client.println("F");
    client.println("</H3>");

    client.println("<H1 style=\"color:Green;\">Relative Humidity:</H1>");
    client.println("<H3 style=\"color:White;\">");
    client.println(humidity);
    client.println("%");
    client.println("</H3>");

    client.println("<H1 style=\"color:Green;\">Dew Point</H1>");
    client.println("<H3 style=\"color:White;\">");
    client.println(dewPointC);
    client.println(" C");
    client.println("
");
    client.println(dewPointF);
    client.println(" F");
    client.println("</H3>");

    client.println("<H1 style=\"color:Green;\">Barometric Pressure:</H1>");
    client.println("<H3 style=\"color:White;\">");
    client.println(PressurePa);
    client.println(" Pa");
    client.println("
");
    client.println(PressureInHg);
    client.println(" InHg");
    client.println("</H3>");

    client.println("<H1 style=\"color:Green;\">Water Temperature:</H1>");
    client.println("<H3 style=\"color:White;\">");
    client.println(WaterC);
    client.println("C");
    client.println("
");
    client.println(WaterF);
    client.println("F");
    client.println("</H3>");

    client.println("<H1 style=\"color:Green;\">Water Acidity:</H1>");
    client.println("<H3 style=\"color:White;\">");
    client.println(phValue);
    client.println(" pH");
    client.println("</H3>");

    client.println("
");
    client.println("</H3>");

    client.println("</BODY>");
    client.println("</HTML>");
  }

  if (request.indexOf("/?GROWON") != -1) {
    digitalWrite(ledPin, LOW);
  }
  if (request.indexOf("/?GROWOFF") != -1) {
    digitalWrite(ledPin, HIGH);
  }
  delay(10);
  client.stop();
}
void loop() {

  //timing
  unsigned long currentMillis = millis();
  
  //sensor readings
  sensorReadings();

  //Menu Button
  if (currentMillis - previousMillis1 >= interval1) {
    previousMillis1 = currentMillis;
    if (digitalRead(menuButton) == HIGH) {
      menuButtonPushCounter++;
    }
  }
  //LCD Menus
  if (menuButtonPushCounter == 0) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Air Temp");
    lcd.setCursor(0, 1);
    lcd.print(TempF);
    lcd.setCursor(5, 1);
    lcd.print((char)223);
    lcd.print("F");
  } else if (menuButtonPushCounter == 1) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Humidity");
    lcd.setCursor(0, 1);
    lcd.print(humidity);
    lcd.setCursor(5, 1);
    lcd.print("%");
  } else if (menuButtonPushCounter == 2) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Dew Point");
    lcd.setCursor(0, 1);
    lcd.print(dewPointF);
    lcd.setCursor(5, 1);
    lcd.print((char)223);
    lcd.print("F");
  } else if (menuButtonPushCounter == 3) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Pressure");
    lcd.setCursor(0, 1);
    lcd.print(PressureInHg);
    lcd.setCursor(6, 1);
    lcd.print("InHg");
  } else if (menuButtonPushCounter == 4) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Water Temp");
    lcd.setCursor(0, 1);
    lcd.print(WaterF);
    lcd.setCursor(5, 1);
    lcd.print((char)223); =
      lcd.print("F");
  } else if (menuButtonPushCounter == 5) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("pH Level");
    lcd.setCursor(0, 1);
    lcd.print(phValue);
  } else if (menuButtonPushCounter == 6) {
    menuButtonPushCounter = 0;
  } else {}

  if (currentMillis - previousMillis2 >= interval2) {
    publishWebpage();
  }
}

I think by ‘voids’ you mean functions such a loop() etc. which don’t return a value, so their definition is preceded by the keyword void.
Variables which are defined in a function are not generally visible outside a function, hence the scope issue. One solution is to make such variables global.

Anyway, if you are getting compiler errors, I suggest that you go back to the previous version and solve the problem of the unwanted delays there.

Try changing this statement:
String request = client.readStringUntil('\r') ;
To:
String request = “” ;

And directly under:
if (client){
Add this:
request = client.readStringUntil('\r') ;

To see if that helps. It is not very pretty, but it may get you further.

Edit:
You can also look at this tutorial. It is quite similar to yours in that it is a web server on an ESP8266 which also does local activities (in this case, switching leds) in the loop(). It is also well commented.

1 Like

That worked flawlessly! I added a debounce factor and it is working just the way I envisioned it to. I will take a look at that link that you sent me as well. I may learn a thing or two from it.

Thanks so much,
Joe

1 Like