Nodemcu + dht22 + mqtt + deep sleep

Salve a tutti,
vorrei realizzare un sensore di temperatura e umidità che mi invii i dati via mqtt e funzioni in deep sleep per risparmiare sui consumi (l’intenzione è in un secondo step di usare una batteria). Purtroppo però dht.readtemperature e dht.readhumidity mi ritornano sempre nan. La cosa strana è che se elimino il deep sleep, e semplicemente leggo ogni 30 secondi, tutto funziona correttamente. Ci sono limitazioni nella libreria Adafruit dht22 1.3.0 per caso?

Questo è il codice non funzionante:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

#define wifi_ssid "xxxx"
#define wifi_password "xxx"

#define mqtt_server "xxxx"
#define mqtt_user "xxx"
#define mqtt_password "xxx"

#define humidity_topic "sensor/humidity"
#define temperature_topic "sensor/temperature"

#define DHTTYPE DHT22
#define DHTPIN  4

WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE); 

// Time to sleep (in seconds)
const int sleepTimeS = 10; //600;

void setup() {
  
  Serial.begin(115200);
  dht.begin();
  
  setup_wifi();
  
  client.setServer(mqtt_server, 1883);
  
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  // Wait a few seconds between measurements.
  delay(2000);
  
  float t = dht.readTemperature();
  float h = dht.readHumidity();
    
  if (isnan(t) || isnan(h)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  
  Serial.print("New temperature:");
  Serial.println(String(t).c_str());
  client.publish(temperature_topic, String(t).c_str(), true);
  
  Serial.print("New humidity:");
  Serial.println(String(h).c_str());
  client.publish(humidity_topic, String(h).c_str(), true);

  // Going to sleep...
  Serial.println("Going into deep sleep for 10 seconds");
  ESP.deepSleep(sleepTimeS * 1000000);
}


void loop() {

}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

mentre questo funziona correttamente:

#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <Adafruit_Sensor.h>
#include <DHT.h>

#define wifi_ssid "xxx"
#define wifi_password "xxx"

#define mqtt_server "xxx"
#define mqtt_user "xxx"
#define mqtt_password "xxx"

#define humidity_topic "sensor/humidity"
#define temperature_topic "sensor/temperature"

#define DHTTYPE DHT22
#define DHTPIN  4

WiFiClient espClient;
PubSubClient client(espClient);
DHT dht(DHTPIN, DHTTYPE); 

long lastMsg = 0;

void setup() {
  Serial.begin(115200);
  
  dht.begin();
  
  setup_wifi();
  
  client.setServer(mqtt_server, 1883);
}

void loop() {
  if (!client.connected()) {
    reconnect();
  }
  client.loop();
  
  // Wait a few seconds between measurements.
  delay(2000);
  
  long now = millis();
  if (now - lastMsg > 30000) {
    lastMsg = now;
    float t = dht.readTemperature();
    float h = dht.readHumidity();

    if (isnan(t) || isnan(h)) {
      Serial.println("Failed to read from DHT sensor!");
      return;
    }

    Serial.print("New temperature:");
    Serial.println(String(t).c_str());
    client.publish(temperature_topic, String(t).c_str(), true);

    Serial.print("New humidity:");
    Serial.println(String(h).c_str());
    client.publish(humidity_topic, String(h).c_str(), true);

  }
}

void setup_wifi() {
  delay(10);
  // We start by connecting to a WiFi network
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(wifi_ssid);

  WiFi.begin(wifi_ssid, wifi_password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }

  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}

void reconnect() {
  // Loop until we're reconnected
  while (!client.connected()) {
    Serial.print("Attempting MQTT connection...");
    // Attempt to connect
    // If you do not want to use a username and password, change next line to
    // if (client.connect("ESP8266Client")) {
    if (client.connect("ESP8266Client", mqtt_user, mqtt_password)) {
      Serial.println("connected");
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

grazie 1000

nel primo codice la lettura del dht (e anche tutto il resto) la fai nel setup... che viene eseguito una sola volta....
mentre nel secondo correttamente la lettura (e tutto il resto) viene fatta nel loop :slight_smile:

ho letto che è necessario fare così per utilizzare il deepsleep, in quanto al risveglio dopo lo sleep, viene eseguito solo il setup... sbaglio?

mi sa di si :slight_smile:

prova a leggere questo se ti può essere utile...

Molto interessante quel link, purtroppo peró non risponde al mio problema con la libreria dht :frowning:

in che senso?
riposta il programma modificato che non ti funziona