ESP8266 running DHT22, LCD, stops working

Hi Guys, I've an issue with and esp8266, which I use to control a sauna light and heating, and send temperature and humidity via MQTT. I've used this same code and hardware elsewhere and it's rock stable, however in the instance I'm also using a LCD display over I2C. I find after an hour or so the the DHT22 sensor and the LCD stops working, but I can MQTT is still working.

Any ideas what could be going wrong??

Here is my code:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include "DHT.h"
#include <Wire.h> 
#include <LiquidCrystal_I2C.h>

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

// Uncomment one of the lines bellow for whatever DHT sensor type you're using!
//#define DHTTYPE DHT11   // DHT 11
//#define DHTTYPE DHT21   // DHT 21 (AM2301)
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321

// Change the credentials below, so your ESP8266 connects to your router
const char* ssid = "www.Sheepspeed.com";
const char* password = "effb101661";
String messageText;
// Change the variable to your Raspberry Pi IP address, so it connects to your MQTT broker
const char* mqtt_server = "192.168.100.84";

// Initializes the espClient
WiFiClient espClient;
PubSubClient client(espClient);

// Connect an LED to each GPIO of your ESP8266
const int heater = 10;
const int light = 16;
//char * = "text";
// DHT Sensor
const int DHTPin = 0;
int heateron;
// Initialize DHT sensor.
DHT dht(DHTPin, DHTTYPE);

// Timers auxiliar variables
long now = millis();
long lastMeasure = 0;

// Don't change the function below. This functions connects your ESP8266 to your router
void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  lcd.setCursor(0, 0);
  
  lcd.print("Connecting to ");
  lcd.setCursor(0, 1);
  lcd.print(ssid);
  Serial.println(ssid);
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("WiFi connected - ESP IP address: ");
  lcd.setCursor(0, 2);
  lcd.print("WiFi connected");
  Serial.println(WiFi.localIP());
  lcd.setCursor(0, 3);
  lcd.print(WiFi.localIP());
}


void callback(String topic, byte* message, unsigned int length) {
  Serial.print("Message arrived on topic: ");
  Serial.print(topic);
  Serial.print(". Message: ");
  String messageTemp;
  
  for (int i = 0; i < length; i++) {
    Serial.print((char)message[i]);
    messageTemp += (char)message[i];
  }
  Serial.println();

  // Feel free to add more if statements to control more GPIOs with MQTT

  // If a message is received on the topic home/office/esp1/gpio2, you check if the message is either 1 or 0. Turns the ESP GPIO according to the message
  if(topic=="sauna/heater"){
      Serial.print("Changing GPIO 4 to ");
      if(messageTemp == "1"){
        digitalWrite(heater, HIGH);
        //lcd.setCursor(0, 2);
       // lcd.print("Sauna Heater is on!");
       heateron=1;
        Serial.print("On");
      }
      else if(messageTemp == "0"){
        digitalWrite(heater, LOW);
      //  lcd.setCursor(0, 2);
       // lcd.print("Sauna Heater is off");
        heateron=0;
        Serial.print("Off");
      }
  }
  if(topic=="sauna/light"){
      Serial.print("Changing GPIO 5 to ");
      if(messageTemp == "1"){
        digitalWrite(light, HIGH);
        Serial.print("On");
      }
      else if(messageTemp == "0"){
        digitalWrite(light, LOW);
        Serial.print("Off");
      }
  }




 if(topic=="sauna/message"){
   
   if(messageTemp != NULL)
  {
    Serial.println ("not equal to NULL");
    messageText=messageTemp;
  }
  
  
   
  }

  
  Serial.println();
}

// This functions reconnects your ESP8266 to your MQTT broker
// Change the function below if you want to subscribe to more topics with your ESP8266 
void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
     /*
     YOU  NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
     To change the ESP device ID, you will have to give a unique name to the ESP8266.
     Here's how it looks like now:
       if (client.connect("sauna_node")) {
     If you want more devices connected to the MQTT broker, you can do it like this:
       if (client.connect("ESPOffice")) {
     Then, for the other ESP:
       if (client.connect("ESPGarage")) {
      That should solve your MQTT multiple connections problem

     THE SECTION IN loop() function should match your device name
    */
    if (client.connect("sauna_node")) {
      Serial.println("connected");  
      // Subscribe or resubscribe to a topic
      // You can subscribe to more topics (to control more LEDs in this example)
      client.subscribe("sauna/heater");
      client.subscribe("sauna/light");
      client.subscribe("sauna/message");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// The setup function sets your ESP GPIOs to Outputs, starts the serial communication at a baud rate of 115200
// Sets your mqtt broker and sets the callback function
// The callback function is what receives messages and actually controls the LEDs
void setup() {
  dht.begin();
  pinMode(light, OUTPUT);
  pinMode(heater, OUTPUT);
   heateron=0;
  digitalWrite(heater, LOW);
 digitalWrite(light, LOW);
   lcd.begin();
  lcd.backlight();
  lcd.clear();
  Serial.begin(115200);
  setup_wifi();
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);
}

// For this project, you don't need to change anything in the loop function. 
// Basically it ensures that you ESP is connected to your broker
void loop() {

  int motion;
  if (!client.connected()) {
    reconnect();
  }
  if(!client.loop())
     /*
     YOU  NEED TO CHANGE THIS NEXT LINE, IF YOU'RE HAVING PROBLEMS WITH MQTT MULTIPLE CONNECTIONS
     To change the ESP device ID, you will have to give a unique name to the ESP8266.
     Here's how it looks like now:
       client.connect("sauna_node");
     If you want more devices connected to the MQTT broker, you can do it like this:
       client.connect("ESPOffice");
     Then, for the other ESP:
       client.connect("ESPGarage");
      That should solve your MQTT multiple connections problem

     THE SECTION IN recionnect() function should match your device name
    */
    client.connect("sauna_node");
    
  now = millis();
  // Publishes new temperature and humidity every 10 seconds
  if (now - lastMeasure > 10000) {
    lastMeasure = now;
    // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor)
    float h = dht.readHumidity();
    // Read temperature as Celsius (the default)
    float t = dht.readTemperature();
    // Read temperature as Fahrenheit (isFahrenheit = true)
    float f = dht.readTemperature(true);

    // Check if any reads failed and exit early (to try again).
    if (isnan(h) || isnan(t) || isnan(f)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    // Computes temperature values in Celsius
    float hic = dht.computeHeatIndex(t, h, false);
    static char temperatureTemp[7];
    dtostrf(hic, 6, 2, temperatureTemp);
    
   
    
    static char humidityTemp[7];
    dtostrf(h, 6, 2, humidityTemp);

    // Publishes Temperature and Humidity values
    client.publish("/sauna/temperature", temperatureTemp);
    client.publish("/sauna/humidity", humidityTemp);
    lcd.clear();
    Serial.print("Humidity: ");
    lcd.setCursor(0, 0);
    lcd.print("Humidity: ");
    Serial.print(h);
    lcd.print(h);
    lcd.print("%");
    lcd.setCursor(0, 1);
    lcd.print("Temperature: ");
    Serial.print(" %\t Temperature: ");
    Serial.print(t);
    lcd.print(hic);
    Serial.print(" *C ");
    lcd.print(" C");
    Serial.print(f);
    Serial.print(" *F\t Heat index: ");
    Serial.print(hic);
    Serial.println(" *C ");
  
  lcd.setCursor(0, 3);
   
   lcd.print(messageText);


if (heateron==0)
{
lcd.setCursor(0, 2);
        lcd.print("Sauna Heater is off");
}
  
if (heateron ==1)
{
lcd.setCursor(0, 2);
        lcd.print("Sauna Heater is on!");
}


   
motion = digitalRead(2);
if (motion == 1)
{
  client.publish("sauna/motion", "1"); // means on
}
else
{
  client.publish("sauna/motion", "0"); // means off
}


 
//maybe add } back here



    
  }
}

It sounds like your I2C bus is behaving badly. Validate your pull up resistor values and if connected to +3.5. Your display should be connected to 5V. If all is OK slow down the I2C from the ESP, it can run quite fast. Note: I2C is an open drain configuration so the +5 from the display controller (PFC85xx) does not backfeed but the LCD board probably has pull up resistors that may have to be removed.

Thanks for getting back to me,

I'll check what pull up resisistors I have.

How would I go about slowing down the i2c?

gilshultz:
It sounds like your I2C bus is behaving badly. Validate your pull up resistor values and if connected to +3.5. Your display should be connected to 5V. If all is OK slow down the I2C from the ESP, it can run quite fast. Note: I2C is an open drain configuration so the +5 from the display controller (PFC85xx) does not backfeed but the LCD board probably has pull up resistors that may have to be removed.

I've had a check, and I don't have any pull up resistors, is this a problem?

I've tried adding a 10k pullup resistor to DHT22, still stops responding after around 5 mins

I also tried powering the DHT22 with 5v (rather than 3.3) still the same issue

I've now replaced the DHT22, and still have the same issue.

Maybe the display is causing the issue or I have bad ESP8266??

I've now set the serial speed to 9600, and still the same issue.

I also tried disconnecting the LCD, still the DHT22 stops responding after a few mins.

I guess it must be the esp8266 or dodgy code??

I've now changed the esp8266 fro another, and still have same issue, so I guess the problem must be in my code somewhere???

The pull up resistors are important on I2C buses. By definition the drivers are open drain or open collector, they sink current but cannot source it. The logic 1 is derived in hardware by the pull up resistor. On slowing down I was talking about the I2C speed, it is programmable in the device you have. Changing to 9600 does nothing but slow down the console speed. Baud rate is automatically set when programming and switched back when your software does the software begin. The garbage you see on the monitor is data being sent at the programming baud rate, not your terminal baud.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.