Archiv für den Monat: August 2017

Batteriegestütztes Internet-of-Things-Device: ESP8266 Wemos D1-mini Temperatursensor mit WLAN und MQTT

Ich habe für das ChaosBBQ einen kleinen Workshop vorbereitet, bei dem man sich ein kleines IoT-Device selbst zusammenlöten kann. Die Idee war, dass es möglichst lange mit einfachen Batterien läuft. Daher habe ich ein paar Aspekte darin verarbeitet, die im Umgang mit Internet-of-Things („Internet der Dinge“) häufig verwendet werden:

  • Wemos D1.mini, ein Breakout-Board mit dem ESP8266-Chip
  • Programmierung mit der Arduino IDE
  • Kommunikation mit WLAN
  • Protokoll MQTT zur Kommunikation mit einem MQTT-Broker, um die gemessenen Temperatur-Werte zu übermitteln

Hier der kurze Überblick über die benötigten Utensilien:

  • Wemos D1.mini
  • Stiftleisten (sind meistens mitgliefert
  • 4.7 kOhm Widerstand
  • Temperatursensor DS18B20
  • Batteriebox (alternativ auch eine 3er-Box aus Conrad/Völkner/Reichelt/….
  • Nicht abgebildet: Lötkolben, Lötzinn, etwas kleine Kabel

Hier der Wemos D1.mini im Detail:

Als Trick zum einfach festlöten der Stiftleisten steckt man am besten die reinen Leisten mit den reinen Stiften umgedreht in ein Breadboard:

Hier noch Kabel, Temperatursensor und der Widerstand:

Okay ein wenig Standard-Lötzinn braucht man zum Löten doch noch:

Die Stiftleisten auf den Wemos D1.mini anlöten:

Die zweite Seite ist eigentlich optional, da nur eine Seite für den Sensor verwendet wird. Aber da wir schon mal dabei sind…

Von der Batteriebox aus muss noch die Stromversorgung angelötet werden. Dazu den nun mit den Stiftbuchsen bestückten Wemos D1.mini im Breadboard belassen und bei „3V3“ den Pluspol und bei „G“ den Minuspol anlöten.

Sofern nicht-aufladbare Batterien verwendet werden (wie in diesem Beispiel), so sollte man die Gesamtspannung bei 3 Volt belassen. Daher den dritten Batteriehalter mit einem Stück Draht überbrücken (hier in weiß). Verwendet man stattdessen Akkus, so liefern diese jeweils nur 1.2 Volt je Zelle und daher werden insgesamt 3.6 Volt benötigt. Mit 2.4 Volt wollte der ESP8266 partout nicht starten…

Damit der ESP8266 aus dem DeepSleep, in den wir ihn später schicken wollen, sich auch selbst wieder aufwecken kann, benötigt dieser noch eine Drahtbrücke zwischen D0 und RST (hier in blau). WICHTIG: Zur Programmierung muss diese Drahtbrücke wieder entfernt werden, daher diese dafür entfernen und – ganz wichtig – die Verbindung NICHT LÖTEN.

Fehlt noch der Temperatursensor selbst und ein Widerstand. Der Temperatursensor sollte mit der flachen Seite zum Chip liegen. Dann gehört das linke Bein in D5, die Mitte in D6 und das rechte Bein in D7. Nachdem man den Sensor eingesteckt hat, wird noch ein Widerstand zwischen 3V3 und dem mittleren Bein, also D6 benötigt. Dieser fungiert als „Pull-Up“ und stellt damit die Protokollfähigkeit sicher. Sollte der Sensor öfter sehr merkwürdige Werte (z.B. -127 °C) liefern, ist wahrscheinlich der Widerstand etwas herausgerutscht.

Damit der Sensor seine Daten auch verschickt, brauchen wir noch ein Programm, welches wir mit der Arduino IDE auf den ESP8266 aufspielen. Hierzu beachten, dass unter „Boards“ auch der Wemos D1.mini ausgewählt ist.

Voraussetzungen für die Arduino Umgebung:

Neueste Arduino Umgebung herunterladen und installieren (Stand Dezember 2017 ist das 1.8.5)

In den Voreinstellungen diese Boardverwalter-URL einfügen. Falls schon eine dort steht, kann man mit dem Knopf rechts daneben noch mehr hinzufügen.

Unter Werkzeuge -> Board -> Boardverwalter (erster Eintrag) sollte man dann nach „esp“ suchen und den Eintrag ESP8266 installieren.

Die OneWire-Bibliothek, die wir im Programm verwenden, muss unter Sketch -> Bibliothek einbinden -> Bibliotheken verwalten hinzugefügt werden.

Dasselbe muss auch für die DallasTemperature-Library geschehen.

Die verwendete AsyncMQTTClient-Bibliothek gibt es leider nicht fertig in Arduino hinterlegt, hier muss die Bibliothek als ZIP-Datei hinzugefügt werden. Sketch -> Bibliothek einbinden -> .ZIP-Bibliothek einbinden.

Diese URL hinzufügen (oder alternativ jede neueres Release vom async-mqtt-client, welches auf github von marvinroger liegt).

https://github.com/marvinroger/async-mqtt-client/archive/v0.8.1.zip

Dasselbe mit der Library ESPAsyncTCP, auf welche die async-mqtt-client basiert:

https://github.com/me-no-dev/ESPAsyncTCP/archive/master.zip

Im nachfolgenden Programm müssen noch die WLAN-SSID, das WLAN-Passwort, die IP des MQTT-Servers und der Topic-„Pfad“ und ggf. der Topic-„Name“ geändert werden.

// Wemos D1 board, connected to a battery box and a DS18B20 temperature sensor
//
 
// For temperature reading
// Libraries needed:
// * OneWire
// * DallasTemperature
//
// Pinout: https://wiki.wemos.cc/products:d1:d1_mini
// D0 = GPIO16 --> Connect D0 to RST for Deep Sleep-Wakeup
 
#include <OneWire.h> 
#include <DallasTemperature.h>
 
const char* ssid = "ENTER_YOUR_SSID_HERE";
const char* password = "ENTER_YOUR_WLAN_PASS_HERE";
 
#define DEVICENAME "maintopic/devicename"
#define TOPIC DEVICENAME"/temperature"
#define ONLINETOPIC DEVICENAME"/online"
#define MQTTSERVER IPAddress(37, 187, 106, 16) // test.mosquitto.org = 37.187.106.16
const int sleepTimeS = 300; // Reduce this value for debugging. Increase if you want more battery life
 
#define VCCPIN D7
#define ONE_WIRE_BUS D6
#define GNDPIN D5
 
OneWire oneWire(ONE_WIRE_BUS); 
DallasTemperature sensors(&oneWire);
 
float tempC;
 
// For WLAN & MQTT
#include <ESP8266WiFi.h>
#include <AsyncMqttClient.h>
AsyncMqttClient mqttClient;
uint16_t packetId1Pub;
bool packet1Ack = false;
 
bool ready = false;
 
char *ftoa( double f, char *a, int precision)
{
 long p[] = {0,10,100,1000,10000,100000,1000000,10000000,100000000};
 
 char *ret = a;
 long heiltal = (long)f;
 itoa(heiltal, a, 10);
 while (*a != '\0') a++;
 *a++ = '.';
 long desimal = abs((long)((f - heiltal) * p[precision]));
 itoa(desimal, a, 10);
 return ret;
}
 
void onMqttPublish(uint16_t packetId) {
  Serial.println("** Publish acknowledged **");
  Serial.print("  packetId: ");
  Serial.println(packetId);
  if (packetId == packetId1Pub) {
    packet1Ack = true;
  }
  if (packet1Ack) {
    ready = true;
  }
}
 
void onMqttConnect(bool sessionPresent) {
  char buf[7];
  packetId1Pub = mqttClient.publish(TOPIC, 1, true, ftoa(tempC, buf, 2));
}
 
void setup() {
  pinMode(GNDPIN, OUTPUT);
  pinMode(VCCPIN, OUTPUT);
  digitalWrite(GNDPIN, LOW);
  digitalWrite(VCCPIN, HIGH);
  Serial.begin(115200); 
  Serial.println("ESP-Temperature-Reader-and-MQTT-Poster-via-WiFi"); 
  // Start up the sensors library 
  sensors.begin(); 
}
 
void loop() {
  // Send the command to get temperature readings 
  Serial.println("Requesting Temperature"); 
  sensors.requestTemperatures();
 
  // You can have more than one DS18B20 on the same bus.  
  // 0 refers to the first IC on the wire 
  Serial.println("Requesting Temperature from Device 0"); 
  tempC = sensors.getTempCByIndex(0);
 
  Serial.println("Connecting to WIFI"); 
  // Connect to WiFi
  WiFi.begin(ssid, password);
  int timeout = 0;
  while (WiFi.status() != WL_CONNECTED) {
    timeout++;
    if (timeout>20) {
        // WIFI isn't available after 10 seconds -> abort mission, mission's a failure
        initiateDeepSleep();
      }
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.println("WiFi connected");
 
  // Print the IP address
  Serial.println(WiFi.localIP());
 
  // Publish result to MQTT
  mqttClient.onConnect(onMqttConnect);
  mqttClient.onPublish(onMqttPublish);
  mqttClient.setServer(MQTTSERVER, 1883);
  mqttClient.setKeepAlive(5).setCleanSession(false).setWill(ONLINETOPIC, 2, true, "no"); // .setCredentials("user", "pass").setClientId(DEVICENAME);
  Serial.println("Connecting to MQTT...");
  mqttClient.connect();
 
  timeout = 0;
  while (!ready) {
    delay(250);
    timeout++;
    if (timeout > 40)
    {
        // MQTT isn't available after 10 seconds -> abort mission, mission's a failure
        initiateDeepSleep();
    }
    Serial.print(".");
  }
  Serial.println("");
  initiateDeepSleep();
}
 
void initiateDeepSleep()
{
  ESP.deepSleep(sleepTimeS * 1000000);
  delay(100); 
}

Die Gesamtpräsentation mit allen Informationen von dieser Webseite könnt ihr hier auch noch herunterladen:

IoT Temperatursensor Präsentation ODP

IoT Temperatursensor Präsentation PDF