Esp8266 und dht22 im deep sleep

Hallo,

ich habe mir einen batteriebetriebenen Sensor bestehend aus einem esp-01, einem “DHT22” (AM2320) und ds18b20 gebaut, den ich mit der Arduino IDE programmiere.
Um batterie zu sparen schicke ich den µC per “ESP.deepSleep (XXX);” schlafen. Alles funktioniert auch wie gewünscht ein paar Zyklen lang, aber dann kann der µC, leider nicht plausibel reproduzierbar, den dht22 nicht mehr auslesen. Das kann Stunden gut laufen oder nur ein paar Minuten.
Es muss mit dem deepsleep zusammenhängen, weil ohne lauft das ganze Wochenlang gut. Bei den ds18b20 Sensoren tritt das Problem nie auf, die werden immer sauber ausgelesen egal wieviele ich drannhänge.
Hat jemand eine Idee was ich ausprobieren könnte?
Hier noch mein Code

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

#define ssid      "XXX"
#define password  "XXX"
#define mqtt_server "192.168.0.201"

//---------------DHT-----------------------

#define DHTPIN 2     // what digital pin we're connected to
#define DHTTYPE DHT22   // DHT 22  (AM2302), AM2321
DHT dht(DHTPIN, DHTTYPE);

unsigned long currentMillis;
unsigned long previousMillis = 0;
const long interval = 5000;

//-----------------------------------------

WiFiClient espClient;

PubSubClient client(espClient);

//---------------1Wire---------------------
// Data wire is plugged into port 0 on the Arduino
#define ONE_WIRE_BUS 0
#define TEMPERATURE_PRECISION 11
// Setup a oneWire instance to communicate with any OneWire devices (not just Maxim/Dallas temperature ICs)
OneWire oneWire(ONE_WIRE_BUS);
// Pass our oneWire reference to Dallas Temperature.
DallasTemperature sensors(&oneWire);
int numberOfDevices; // Number of temperature devices found
DeviceAddress tempDeviceAddress; // We'll use this variable to store a found device addres
//-----------------------------------------

void setup() {
  Serial.begin(74880);

  dht.begin();

  // We start by connecting to a WiFi network

  Serial.println();
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

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

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

  client.setServer(mqtt_server, 1883);
  //client.setCallback(callback);
  //------------1Wire---------------------
  sensors.begin();
  // Grab a count of devices on the wire
  numberOfDevices = sensors.getDeviceCount();
  // locate devices on the bus
  Serial.print("Locating devices...");
  Serial.print("Found ");
  Serial.print(numberOfDevices, DEC);
  Serial.println(" devices.");
  for (int i = 0; i < numberOfDevices; i++)
  {
    // Search the wire for address
    if (sensors.getAddress(tempDeviceAddress, i))
    {
      Serial.print(" with address: ");
      printAddress(tempDeviceAddress);
      Serial.println();
      Serial.print("Setting resolution to ");
      Serial.println(TEMPERATURE_PRECISION, DEC);

      // set the resolution to TEMPERATURE_PRECISION bit (Each Dallas/Maxim device is capable of several different resolutions)
      sensors.setResolution(tempDeviceAddress, TEMPERATURE_PRECISION);

      Serial.print("Resolution actually set to: ");
      Serial.print(sensors.getResolution(tempDeviceAddress), DEC);
      Serial.println();
    }
  }
  //---------------------------------------
}


void loop() {

  if (!client.connected()) {
    reconnect();
  }

  currentMillis = millis();

  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;

    ds18b20_reading();
    dht22_reading();


    Serial.println("beginn DeepSleep");
    ESP.deepSleep (60000000);
  }
  client.loop();
}

void ds18b20_reading()
{
  // call sensors.requestTemperatures() to issue a global temperature
  // request to all devices on the bus
  Serial.print(F("Request DS18B20 temps..."));
  sensors.requestTemperatures(); // Send the command to get temperatures
  Serial.println(F("DONE"));
  ds18b20_shout();
}

void dht22_reading()
{
  //------------DHT22 Sensor 1-------------
  // Reading temperature or humidity takes about 250 milliseconds!
  // 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();

  // Check if any reads failed and exit early (to try again).
  if (isnan(h) || isnan(t)) {
    Serial.println("Failed to read from DHT sensor!");
    return;
  }
  // Compute heat index in Celsius (isFahreheit = false)
  float hic = dht.computeHeatIndex(t, h, false);

  Serial.print("Humidity h0: ");
  Serial.print(h);
  Serial.print(" %\t");
  Serial.print("Temperature t0: ");
  Serial.print(t);
  Serial.print(" *C ");
  Serial.print("Heat index t0: ");
  Serial.print(hic);
  Serial.println(" *C ");


  publish(PSTR("dht_hum_m0"), h);
  publish(PSTR("dht_temp_m0"), hic);
}

void ds18b20_shout()
{
  for (uint8_t i = 0; i < numberOfDevices; i++)
  {
    char  buffer [20];
    Serial.print("Temp device (index) ");
    Serial.print(i);
    Serial.print(F(" is: "));
    Serial.println(sensors.getTempCByIndex(i));
    Serial.print(F(" with ID: "));
    if (sensors.getAddress(tempDeviceAddress, i))
    {
      printAddress(tempDeviceAddress);
    }
    Serial.println();
    sprintf(buffer, ("temp_index_esp01m0_%d"), i);
    publishRam(buffer, sensors.getTempCByIndex(i));
    // Serial.println(buffer);

  }
}

// function to print a device address
void printAddress(DeviceAddress deviceAddress)
{
  for (uint8_t i = 0; i < 8; i++)
  {
    if (deviceAddress[i] < 16) Serial.print("0");
    Serial.print(deviceAddress[i], HEX);
  }
}

void publish(const char* str, float val)
{
  char buffer[20];
  char message_buff[30];
  strncpy_P(message_buff, str, sizeof(message_buff));
  dtostrf(val, 1, 1, buffer);
  client.publish(message_buff, buffer);
}

void publishRam(const char* str, float val)
{
  char buffer[20];
  dtostrf(val, 1, 1, buffer);
  client.publish(str, buffer);
}

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("ESP8266_m0")) {
      Serial.println("connected");
      //--------------------!!!MQTT subsribe!!!-------------------------------------

      //client.subscribe("inTopic");
      //client.subscribe("Farb_hue");

      //-------------------------------------------------------------------------
    } else {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 5 seconds");
      // Wait 5 seconds before retrying
      delay(5000);
    }
  }
}

// ===========================================================
// Callback Funktion von MQTT. Die Funktion wird aufgerufen
// wenn ein Wert empfangen wurde.
// ===========================================================
/*void callback(char* topic, byte * payload, unsigned int length) {
  // Zähler
  int i = 0;
  // Hilfsvariablen für die Convertierung der Nachricht in ein String
  char message_buff[100];

  Serial.println("Message arrived: topic: " + String(topic));
  Serial.println("Length: " + String(length, DEC));

  // Kopieren der Nachricht und erstellen eines Bytes mit abschließender \0
  for (i = 0; i < length; i++) {
    message_buff[i] = payload[i];
  }
  message_buff[i] = '\0';

  // Konvertierung der nachricht in ein String
  String msgString = String(message_buff);
  Serial.println("Payload: " + msgString);
  } */

Grüße

Bitte poste den Link zu der von Dir verwendeten DHT-Bibliothek. Einige Versionen sind so Arduino ATmega-spezifisch programmiert, dass sie auf anderen Plattformen nicht korrekt funktionieren und das Timing nicht richtig einhalten.

Ich benutze diese hier, habe auch schon ältere probiert, das ERgebniss war gleich GitHub - adafruit/DHT-sensor-library: Arduino library for DHT11, DHT22, etc Temperature & Humidity Sensors

Was ich nicht verstehe ist der Unterschied wenn der µC aus dem deep sleep erwacht oder wenn ich einfach einen Reset durchführe.
Wenn der Fehler bei mir Auftritt muss ich den Sensor von der Batterie nehmen und wieder anschließen dann funktioniert wieder alles normal...
Vielleicht hat ja jemand Lust schnell mal einen Testaufbau mit esp8266, dht22 und "deepsleep" zu realisieren, um zu sehen ob das Problem dort auch Auftritt?

Grüße

Schau mal da: http://www.esp8266.com/viewtopic.php?f=32&t=8114&start=20
Eventuell funktionierts ja damit...

Meiner Erfahrung nach ist der DHT etwas sensible was das WLAN-Signal des ESP angeht:
Wenn der Sensor zu dicht am ESP sitzt, wird der DHT beeinflusst (macht sich bei mir in mit einer erheblichen Fehlmessung bemerkbar, die ich kompensieren muss).

Bei mir liegt der Abstand bei ca. 3cm (geht nicht anders, weil der ganze Sensor in einer ehemaligen Fieberthermometerhülle verbaut ist...).

Vielleicht schiesst der ESP den DHT ab?

Danke für den link,

ich habe das mal jetzt so umgesetzt wie beschrieben und den "DHTPIN" vor dem "deep sleep" als output zu deklarieren und auf "LOW" zu setzen.
Falls das nicht hilft habe ich noch folgendes gefunden: http://www.esp8266.com/viewtopic.php?f=29&t=8534
Jetzt heißt es abwarten :sleeping:

Grüße

Ich benutze diese hier, habe auch schon ältere probiert, das ERgebniss war gleich GitHub - adafruit/DHT-sensor-library: Arduino library for DHT11, DHT22, etc Temperature & Humidity Sensors

Dies ist zumindest eine gute Library, die auch mit dem ESP8266 verwendet werden kann.

Ich weiss nicht ob's hier hilft.
Ich habe ähnliches mit einem DHT und einem normale Mini gemacht.
Da nehme ich vor dem Sleep dem DHT die Spannung weg und wenn er aufwacht
kommt die Spannung wieder aber ich lasse ihm (dem DHT) noch 200mS bis zur Messung.
Das klappt schon sein Jahren so.

Ulli