Problem with Data refreshing on LCD

Hi All,

I am having an issue with data refreshing on an LCD, but the variable is updating on a serial print.

The background of the project:
There are two temperature sensors taking a) the room temp (DHT11) b) the temp of a radiator (DS18B20)
The temperatures are uploaded to a webpage and an LCD screen, also a serial output.
When the radiator is on, temperature rises to above 25 degrees and turns on a fan to blow the hot air round the room.
The LCD will then update to show the fan as running.
when the temp drops below 25 (radiator is off) the fan also goes off
The LCD then show the fan as off.

Except:
when the temperature goes above 25 the LCD stops updating the rad temperature, but the serial print does.
The satus does not show as running.

This is until the temp drops below 25, when it then updates temprature and status shows as off.

The code is below, and i am at a loss as to why this happens.

Any advice would be gratefully recieved as i think i am just missing something silly, and if i have missed information you need i am sorry, and please do let me know

Many thanks

Jon

#include <ESP8266WiFi.h>
#include <WiFiClient.h>
#include <ESP8266WebServer.h>
#include <ESP8266mDNS.h>
#include <OneWire.h> 
#include <DallasTemperature.h>
#include <Wire.h>
#include <LCD.h>
#include <LiquidCrystal_I2C.h>

#define I2C_ADDR    0x27 // <<----- Add your address here.  Find it from I2C Scanner
#define BACKLIGHT_PIN     3
#define En_pin  2
#define Rw_pin  1
#define Rs_pin  0
#define D4_pin  4
#define D5_pin  5
#define D6_pin  6
#define D7_pin  7

LiquidCrystal_I2C  lcd(I2C_ADDR,En_pin,Rw_pin,Rs_pin,D4_pin,D5_pin,D6_pin,D7_pin);

#define motor 5

int hold=10000;
int last_do=0;
int fan=0;
String fanstate;
String statis = "OFF";


///set up temps on DHT11////
//Celsius to Fahrenheit conversion
double Fahrenheit(double celsius)
{
  return 1.8 * celsius + 32;
}


//Celsius to Kelvin conversion
double Kelvin(double celsius)
{
  return celsius + 273.15;
}

double dewPoint(double celsius, double humidity)
{
  // (1) Saturation Vapor Pressure = ESGG(T)
  double RATIO = 373.15 / (273.15 + celsius);
  double RHS = -7.90298 * (RATIO - 1);
  RHS += 5.02808 * log10(RATIO);
  RHS += -1.3816e-7 * (pow(10, (11.344 * (1 - 1/RATIO ))) - 1) ;
  RHS += 8.1328e-3 * (pow(10, (-3.49149 * (RATIO - 1))) - 1) ;
  RHS += log10(1013.246);

        // factor -3 is to adjust units - Vapor Pressure SVP * humidity
  double VP = pow(10, RHS - 3) * humidity;

        // (2) DEWPOINT = F(Vapor Pressure)
  double T = log(VP/0.61078);   // temp var
  return (241.88 * T) / (17.558 - T);
}


double dewPointFast(double celsius, double humidity)
{
  double a = 17.271;
  double b = 237.7;
  double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);
  double Td = (b * temp) / (a - temp);
  return Td;
}


#include <dht11.h>

dht11 DHT11;

#define DHT11PIN 13

int overide = 0;
/// end temps set up

//start onewire temp setup
#define ONE_WIRE_BUS 12 
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);
//end one wire

///start wifi setup///
MDNSResponder mdns;
 
ESP8266WebServer server(80);
String webPage;
String webPage1;
const char* ssid     = "xxxxxxxx";      //wifi name
const char* password = "xxxxxx";  //wifi password
///end wifi set up///

void setup() {
  // set up wifi //
    pinMode(motor, OUTPUT);  //led pin 16
    pinMode(13, OUTPUT);  //running
    pinMode(15, OUTPUT);  //on off

    digitalWrite(15, HIGH);
  
  Serial.begin(74880);
  delay(100);
 
 
  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);
  
  WiFi.begin(ssid, password);
  WiFi.config(IPAddress(192,168,1,18), IPAddress(192,168,1,1), IPAddress(255,255,255,0));
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
 
  Serial.println("");
  Serial.println("WiFi connected");  
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
  
  if (mdns.begin("esp8266", WiFi.localIP())) 
    Serial.println("MDNS responder started");
 
  server.on("/", [](){
    server.send(200, "text/html", webPage);
  });
  server.on("/socket1On", [](){
    server.send(200, "text/html", webPage);
    // Turn off LED
    digitalWrite(motor, HIGH);
    
    delay(1000);
  });
  server.on("/socket1Off", [](){
   server.send(200, "text/html", webPage);
    //Turn on LED
    digitalWrite(motor, LOW);
    overide = 0;
     Serial.println("Do low 1 ");
  });

  server.begin();
  Serial.println("HTTP server started");
// end wifi set up

// start temp set up //

  Serial.begin(74880);
  Serial.println("DHT11 TEST PROGRAM ");
  Serial.print("LIBRARY VERSION: ");
  Serial.println(DHT11LIB_VERSION);
  Serial.println();

// end temo set up //
//one wire
 Serial.println("Dallas Temperature IC Control Library Demo"); 
 // Start up the library 
 sensors.begin();
// end one wire


//set up LCD //
Wire.begin(D4,D5);
 lcd.begin (20,4); //  <<----- My LCD was 16x2

 
// Switch on the backlight
lcd.setBacklightPin(BACKLIGHT_PIN,POSITIVE);
lcd.setBacklight(HIGH);
lcd.home (); // go
lcd.setCursor (2,0); 
lcd.print("**FAN CONTROL**");  
lcd.setCursor (0,1); 
lcd.print("Room Temp:"); 
lcd.setCursor (0,2); 
lcd.print("RAD Temp:");  
lcd.setCursor (0,3); 
lcd.print("Fan Status:");
}

void loop() {
  if (millis() - last_do > hold) {
    lcd.home ();
  readtemp();
  onewre();
  server.handleClient();
  last_do=millis();

  
  }
}

void readtemp(){
    Serial.println("\n");

  int chk = DHT11.read(DHT11PIN);

  Serial.print("Read sensor: ");
  switch (chk)
  {
    case DHTLIB_OK: 
    Serial.println("OK"); 
    break;
    case DHTLIB_ERROR_CHECKSUM: 
    Serial.println("Checksum error"); 
    break;
    case DHTLIB_ERROR_TIMEOUT: 
    Serial.println("Time out error"); 
    break;
    default: 
    Serial.println("Unknown error"); 
    break;
  }
  lcd.setCursor (11,1); 
  lcd.print((float)DHT11.temperature, 2);
  lcd.setCursor (16,1); 
  lcd.print(F("\xDF""C."));
  webPage = "<h1>ESP8266 Web Server</h1><p>Fan Over-ride ";
  webPage += "<h2>Room Data</h2>";
  webPage +="<p>Humidity (%): ";
  webPage +=(float)DHT11.humidity, 2;
  webPage +="</p><p>";

  webPage +="Temperature (°C): ";
  webPage +=(float)DHT11.temperature, 2;
  webPage +="</p><p>";

  webPage +="Temperature (°F): ";
  webPage +=Fahrenheit(DHT11.temperature), 2;
  webPage +="</p><p>";

  webPage +="Temperature (°K): ";
  webPage +=Kelvin(DHT11.temperature), 2;
  webPage +="</p><p>";

  webPage +="Dew Point (°C): ";
  webPage +=dewPoint(DHT11.temperature, DHT11.humidity);
  webPage +="</p><p>";

  webPage +="Dew PointFast (°C): ";
  webPage +=dewPointFast(DHT11.temperature, DHT11.humidity);
  webPage +="</p>";

 
}

void onewre(){
   // call sensors.requestTemperatures() to issue a global temperature 
 // request to all devices on the bus 
/********************************************************************/
 Serial.print(" Requesting temperatures..."); 
 sensors.requestTemperatures(); // Send the command to get temperature readings 
 Serial.println("DONE"); 
/********************************************************************/
float temp = sensors.getTempCByIndex(0);
  lcd.setCursor (11,2); 
  lcd.print(temp);
  lcd.setCursor (16,2); 
  lcd.print(F("\xDF""C."));

 Serial.print("Temperature is: "); 
 Serial.print(temp); 
   webPage += "<h2>Room Data</h2>";
   webPage += "Radiator temperature is: ";
   webPage += (temp);
   webPage += "°C";


   if ((temp > 25) and fan == 0) {
    digitalWrite(motor, HIGH);
    Serial.println("Do high 2 ");
    //digitalWrite(13, HIGH);
    fan=1;
     statis = "Running";
    
   } else if ((temp < 26) and fan == 1){
    digitalWrite(motor, LOW);
    Serial.println("Do low 2 ");
    //digitalWrite(13, LOW);
    fan=0;
     statis = "OFF";
   }
   Serial.println(statis);
     lcd.setCursor (11,3); 
    lcd.print(statis);
}

double a = 17.271;
double b = 237.7;
double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);

From above declaration of "temp " - do you have enough characters to display temp on LCD between postilions 11 and 15 ?

Also recheck if double variable is OK to send to LCD without specifying the format - characteristic and mantissa.

  if (millis() - last_do > hold) {
    lcd.home ();
  readtemp();
  onewre();
  server.handleClient();

Why are you only periodically handling client requests?

232:
double a = 17.271;
double b = 237.7;
double temp = (a * celsius) / (b + celsius) + log(humidity*0.01);

From above declaration of "temp " - do you have enough characters to display temp on LCD between postilions 11 and 15 ?

Also recheck if double variable is OK to send to LCD without specifying the format - characteristic and mantissa.

Thanks for the reply.
Yes everything displays fine on the LCD, except when the fan is running, if i use the word 'On' or 'Running' so length should not make a difference, it is a 20,4 display.

It also does not explain why it does not update the temp when it is above 25 degrees, unless i am missng something there?

PaulS:

  if (millis() - last_do > hold) {

lcd.home ();
 readtemp();
 onewre();
 server.handleClient();



Why are you only periodically handling client requests?

because i put the bracket in the wrong place :confused: thanks, i will move that!!

There is only ONE place in code where you explicitly test for running fan.

To test set temp = 26, copy the "print " lines as indicated and add delay and for(;;); stop
If it works the p[problem is elsewhere.

temp = 26;  // test 
if ((temp > 25) and fan == 0) {
 digitalWrite(motor, HIGH);
 Serial.println("Do high 2 ");
 //digitalWrite(13, HIGH);
 fan=1;
 statis = "Running";
delay(1000);             // test keep fan on for 1 second 
whoops edited temp =< 26 hope the sequence is correct , I have no means to test it 
 } else if ((temp =< 26) and fan == 1) {
 digitalWrite(motor, LOW);
 Serial.println("Do low 2 ");
 //digitalWrite(13, LOW);
 fan=0;
 statis = "OFF";
        Serial.println(statis);
 lcd.setCursor (11,3);
 lcd.print(statis);
        for(;;);  // test  stop 


 }
 Serial.println(statis);
 lcd.setCursor (11,3);
 lcd.print(statis);

 }

HI thank you.

that part does worl, all that does not work is updating the LCD with the word on or running and updating the LCD with the temperature all the time it is about 25 degrees.

The web and serial all update, it is just the LCD that doesnt

Try initializing

statis = " Initial statis";
before this part
and add delay so you can observe

  if ((temp > 25) and fan == 0) {
    digitalWrite(motor, HIGH);
    Serial.println("Do high 2 ");
    //digitalWrite(13, HIGH);
    fan=1;
     statis = "Running";
   
   } else if ((temp < 26) and fan == 1){
    digitalWrite(motor, LOW);
    Serial.println("Do low 2 ");
    //digitalWrite(13, LOW);
    fan=0;
     statis = "OFF";
   }
   Serial.println(statis);          this works?  lets make sure 
   Serial.println(__LINE__);    are we there yet ? 
     lcd.setCursor (11,3);
    lcd.print(statis);  is this the code which does not  work ? 
   delay(1000);

232:
Try initializing

statis = " Initial statis";
before this part
and add delay so you can observe

  if ((temp > 25) and fan == 0) {

digitalWrite(motor, HIGH);
    Serial.println("Do high 2 ");
    //digitalWrite(13, HIGH);
    fan=1;
    statis = “Running”;
 
  } else if ((temp < 26) and fan == 1){
    digitalWrite(motor, LOW);
    Serial.println("Do low 2 ");
    //digitalWrite(13, LOW);
    fan=0;
    statis = “OFF”;
  }
  Serial.println(statis);          this works?  lets make sure
  Serial.println(LINE);    are we there yet ?
    lcd.setCursor (11,3);
    lcd.print(statis);  is this the code which does not  work ?
  delay(1000);

that’s done just below the defines:

#define motor 5

int hold=10000;
int last_do=0;
int fan=0;
String fanstate;
String statis = "OFF";

Reason I suggested to do initializing JUST before the if()
I really suspect the problem is elsewhere.
To verify - just print it BEFORE you enter the if() - both Serial and LCD and add the suggested delay BEFORE you do the if() too. I do suspect loop() "problem". But I was wrong before.

Personally - when I was coding Arduino I never did like the loop() to control the code execution.
It is OK for simple "blink " but gets in the way with more complex code .
IMHO - your mileage will vary.

Here is something to check - your "temp" is double , maybe the expression "temp >25" cannot be evaluated correctly
Just for kicks , try casting it to int - "(int) temp > 25 ".

232:
when I was coding Arduino I never did like the loop() to control the code execution

I note your use of the past tense ("when I was") in that quote.

TolpuddleSartre:
I note your use of the past tense ("when I was") in that quote.

True, I do not wish to elaborate too MUCH.

Grew up with BASIC "band X" until it became annoying having too many issues with "serial " communication.
Last project was WWVB receiver analyzing 60kHZ signal for "time stamp".
Spent months trying to make Due play with USB.
Got caught in two feuding Arduinos haggling over "who is the boss" and in the process "releasing" buggy IDE more often that I change underparts.
"Forced " to switch to another IDE which "advanced " to " latest and greatest" Windows...

In short - found more user friendly OS, processor board with native USB ports,WiFi, Ethernet , new IDE etc.
Currently coding my VNA ( Vector network analyzer ) and another radio related project.
Life is good.

Hopefully I did not bore you to tears.

Hi all,

Thank you for yall your answers and suggestions.

It looks like the sca and sdl share the pins on the motor shield with the motors, meaning turning on the motor screws with the communication until that pin goes low.

I have not found anwhere a clear diagram or explanation of which pins from the NodeMCU feed which pins on the motor shield inclusing the motors.

I also have been confused by the designations of the pins as it seems to use a mix of GPIO and Digital pins.

I have emailed the designers to ask if there is any information.

Excellent, very glad you found it .

I am currently "struggling" with similar GPIO mode setting " problem". In my case changing the GPIO mode to SPI the spec is not very descriptive if setting to SPI mode does change the GPIO "direction", or it has to be done separately.
BTW I am not too thrilled with term "GPIO" - when you change the mode to SPI the library I am using still calls it "GPIO". Perhaps "(hardware) register would be more generic.