ESP8266 with DHT22 sending MQTT

Um einen Aussensensor eine gewisse Zeit mit einer Batterie betreiben zu können ist die Möglichkeit den Prozessor schlafen zu legen extrem wichtig. Und wenn man mit einem relativ großen Messinterval zufrieden ist, lässt sich noch mehr aus einem Akku herausholen. Der ESP8266 kann das sogar recht gut. Im Netz kann man durchaus Quellen finden, die biss zu 60 Minuten lange deep sleeps erwähnen. Mit ESP.deepSleep(sleep_uSec) lässt sich der ESP schlafen legen. Zusätzlich muss der Reset Pin mit GPIO16 verbunden werden.

Im deepsleep läuft nur noch die RTC vom Prozessor, der nach Ablauf der festgelegten Periode per GPIO16 den Reset Pin auf low zieht. Und so den geladenen Sketch (ja ich programmiere den ESP mit Arduino) neu ausführt. Code nach dem Aufruf des deep sleep wird nicht ausgeführt. Allerdings wird berichtet, dass ein delay(100); nötig ist um sicher in den deep sleep zu kommen.

Mit ESP.getResetReason() kann man als Klartext den Grund für den letzten Reset abfragen. Die Antwort lautet dann „Deep-Sleep Wake“, auch wenn der Reset Pin per Taster vor Ablauf der Schlafperiode getriggert wird.

Wichtig ist entweder die Brücke vor einem neu Programmieren auszulöten oder anders schaltbar zu machen. Damit man genug Zeit hat den neuen Sketch auf den ESP hoch zu laden. Alternativ kann man vor dem sleep ein delay von 30 Sekunden einbauen.

Update: Um den ESP zu wecken und ohne 30 Sekunden Pause programmierbar zu machen, die Brücke von D0 nach RST durch einen Widerstand mit ca. 470 Ohm ersetzen. Dann schafft auch der CH340 den ESP während dem Schlaf in den Reset zu ziehen. Falls es der ESP nur am PC schafft aus dem deepsleep aufzuwachen, aber nicht wenn er mit einer anderen Stromquelle versorgt wird, dann ist vermutlich der Widerstand zu groß.

Ich benutze shiftr.io als MQTT Broker um die Messages schön zu visualisieren. Das ganze ist aber ziemlich langweilig wenn alle Nodes nur alle 15 Minuten was senden. ;-)

Code

dht_deepsleep.ino
/*
  License TBD Christian Moll
*/
 
#include <ESP8266WiFi.h>
#include <WiFiClient.h>
 
#include "DHT.h"
#include <MQTTClient.h>
 
#define DHTTYPE DHT22
#define DHTPIN 4
 
#define FORCE_DEEPSLEEP
 
const char* host = "esp8266_room1"; // will also be used on shiftr.io
const char* ssid = "ssid";
const char* password = "password";
 
WiFiClient net;
MQTTClient mqtt;
 
DHT dht(DHTPIN, DHTTYPE);
 
unsigned int batt;
double battV;
 
void connect();
 
void setup(void){
 
  dht.begin();
 
  Serial.begin(115200);
  Serial.println();
  Serial.println("Booting Sketch...");
  WiFi.mode(WIFI_AP_STA);
  WiFi.begin(ssid, password);
 
  mqtt.begin("broker.shiftr.io", net);
 
  connect();
  Serial.printf("ready!");
}
 
void loop(void){
  if(!mqtt.connected()) {
    connect();
  }
 
  mqtt.loop();
  delay(30000); // time to make reprogramming possible
 
  batt = analogRead(A0);
  battV = mapDouble(batt, 0, 1023, 0.0, 6.6);
  float h = dht.readHumidity();
  float t = dht.readTemperature();
 
  // Check if any reads failed and exit early (to try again).
  if (!isnan(h) || !isnan(t)) {
    mqtt.publish("/room1/temp", String(t));
    mqtt.publish("/room1/humidity", String(h));
  }
 
  mqtt.publish("/room1/batt", String(battV));
  mqtt.publish("/room1/battRaw", String(batt));
  mqtt.publish("/room1/resetReason", ESP.getResetReason());
 
  #ifdef FORCE_DEEPSLEEP
    Serial.println("Force deepsleep 15min!");
    ESP.deepSleep(15 * 60 * 1000000);
    delay(100);
  #endif
  //handle deep sleep depending on battV
  if (battV < 3.3) {
    ESP.deepSleep(30 * 1000000); //send IFTTT low_bat warning
    delay(100);
  } else if (battV < 4.0) {
    ESP.deepSleep(2 * 1000000);
    delay(100);
  }
}
 
void connect() {
  while(WiFi.waitForConnectResult() != WL_CONNECTED){
    WiFi.begin(ssid, password);
    Serial.println("WiFi failed, retrying.");
  }
 
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());
 
  while (!mqtt.connect(host, "shiftr-thing", "shiftr-pass")) {
    Serial.print(".");
  }
  Serial.println("\nconnected!");
}
 
 
void messageReceived(String topic, String payload, char * bytes, unsigned int length) {
  Serial.print("incoming: ");
  Serial.print(topic);
  Serial.print(" - ");
  Serial.print(payload);
  Serial.println();
}
 
double mapDouble(double x, double in_min, double in_max, double out_min, double out_max)
{
  double temp = (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
  temp = (int) (4*temp + .5);
  return (double) temp/4;
}

Bilder

Cookies helfen bei der Bereitstellung von Inhalten. Durch die Nutzung dieser Seiten erklären Sie sich damit einverstanden, dass Cookies auf Ihrem Rechner gespeichert werden. Weitere Information