• In diesem Beitrag werden wir ein Smarthome-Thermometer basteln. Als Temperaturfühler dient ein DS18B20. Das Gehirn des Projektes ist ein ESP8266 D1 Mini. Inspiriert wurde ich durch den Beitrag von @Gauweiler42 in der Community. RE: Problem mit OneWire DS18B20

    Funktionbeschreibung

    Die Temperatur wird in einem beliebig einstellbaren Intervall abgefragt. Und im seriellen Monitor ausgegeben. Danach findet die Übergabe der Temperatur an die eigene Smarthome-Umgebung statt. Das kann einerseits über MQTT geschehen, über eine GET-Request oder jede beliebige andere Art von Datenübertragung. In diesem Tutorial behandle ich nur die Übertragung via GET-Request.

    Verdrahtung

    Die erste Hürde ist das Auslesen der Temperatur am D1 Mini. Hierzu nutze ich wie bereits erwähnt einen DS18B20 Temperaturfühler. Den Fühler gibt es in verschiedenen Ausführungen. Mit Kabel, ohne Kabel, als Stab, als Knopf, … es gibt unterschiedliche Bauformen - dabei wird aber jedes Mal auf den OneWire-Bus zurückgegriffen. Der DS18B20 hat drei Adern. VCC - GND und DQ - wobei DQ die Datenleitung darstellt.

    Beschreibung Wert
    Stromversorgungsbereich 3,0V bis 5,5V
    Messbereich -10°C bis +85°C

    Die Verdrahtung für dieses Projekt sieht wie folgt aus:

    D1 Mini DS18B20
    5V VCC
    G GND
    D4 DQ

    d1_mini_ds18b20.png

    Die Farben der Drähte entsprechen den Farben der Drähte in der Realität. Bei einem DS18B20 in Form eines Fühlers ist die Verdrahtung identisch.

    Es gibt neben Fühlern und Knöpfen auch sog. Shields als steckbare oder verlötbare Aufsätze für den D1 Mini. Bei einem Shield spart man sich die Verdrahtung, weil man das Shield einfach auf den D1 Mini stecken kann. So bekommt man ein noch kompakteres Thermometer.

    Hier ist ein Warenkorb, mit den Produkten die ihr für euer Thermometer verwenden könnt.

    Basic-Code

    Folgender Code gibt die Temperatur jede Sekunde über den seriellen Monitor aus:

    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 2
    
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    
    //Messintervall in Sekunden
    int wait = 5;
    
    //Temperatur
    float temperature;
    
    
    void push(){
    
      //Hier soll der Wert an die Smarthome-Umgebung übertragen werden
    
    }
    
    void setup(){
      
      Serial.begin(115200);
      wait = wait * 1000;
      sensors.begin();
    
    }
    
    void loop(){
    
      sensors.requestTemperatures();
      Serial.print(sensors.getTempCByIndex(0));
      Serial.println(" °C");
      temperature = sensors.getTempCByIndex(0);
      push();
      delay(wait);
    
    }
    

    Quelle: makesmart.net @dieterh

    Die Ausgabe sieht folgendermaßen aus:

    22.75 °C
    22.75 °C
    22.75 °C
    22.75 °C
    

    Mit der Variable wait kann der Messintervall in Sekunden eingestelt werden. Der Sensor gibt den Messwert alle 5 Sekunden im seriellen Monitor zurück.

    //Messintervall in Sekunden
    int wait = 5;
    

    Dieser Code kann bereits für das eigene Projekt verwendet werden.


    Einbidung in das Smarthome - Homebridge

    Folgenden Codeschnipsel dient als Ausgangslage zur Einbindung in das eigene Smarthome-System. Ich habe mich für die Variante via GET-Request entschieden. Als Smarthome-Plattform nutze ich Homebridge.

    GET-Request

    Als Plugin für Homebridge könnte das Plugin homebridge-http-webhooks verwendet werden. Die Konfiguration für das Plugin sieht wie folgt aus:

    {
    	"platform": "HttpWebHooks",
     	"webhook_port": "51828",
     	"sensors": [
      	{
       		"id": "temperatur",
        	"name": "Sensor name 5",
       		"type": "temperature"
      		}
     	]
    }
    

    Der Code auf dem D1 Mini muss dementsprechend mit einer GET-Request ausgestattet werden:

    /*
        WLAN TERMOMETER GET-Request
        GET-Request an einen HTTP-Server
        Created by cooper, 2020
        makesmart.net
    */
    
    #include <ESP8266WiFi.h>
    #include <ESP8266HTTPClient.h>
    #include <WiFiClient.h>
    #include <OneWire.h>
    #include <DallasTemperature.h>
    #define ONE_WIRE_BUS 2
    
    OneWire oneWire(ONE_WIRE_BUS);
    DallasTemperature sensors(&oneWire);
    
    HTTPClient sender;
    WiFiClient wifiClient;
    
    // WLAN-Daten
    const char* ssid = "WLAN_SSID";
    const char* password = "WLAN_PASSWD";
    
    //Messintervall in Sekunden
    int wait = 5;
    
    //Temperatur
    float temperature;
    
    
    void push(){
    
      //Hier wird der Wert an die Smarthome-Umgebung übertragen
      
      if (sender.begin(wifiClient, "http://makesmart-server:51828/?accessoryId=temperatur&value=" + String(temperature))){
    
        // HTTP-Code der Response speichern
        int httpCode = sender.GET();
       
    
        if (httpCode > 0) {
          
          // Anfrage wurde gesendet und Server hat geantwortet
          // Info: Der HTTP-Code für 'OK' ist 200
          if (httpCode == HTTP_CODE_OK) {
    
            // Hier wurden die Daten vom Server empfangen
    
            // String vom Webseiteninhalt speichern
            String payload = sender.getString();
    
            // Hier kann mit dem Wert weitergearbeitet werden
           	// ist aber nicht unbedingt notwendig
            Serial.println(payload);
            
            
            
          }
          
        }else{
          // Falls HTTP-Error
          Serial.printf("HTTP-Error: ", sender.errorToString(httpCode).c_str());
        }
    
        // Wenn alles abgeschlossen ist, wird die Verbindung wieder beendet
        sender.end();
        
      }else {
        Serial.printf("HTTP-Verbindung konnte nicht hergestellt werden!");
      }
    
    }
    
    
    void setup() {
      Serial.begin(115200);
      
      WiFi.begin(ssid, password);
    
      while (WiFi.status() != WL_CONNECTED) {
        delay(200);
        Serial.print(".");
      }
    
      Serial.println("Verbunden!");
      wait = wait * 1000;
      sensors.begin();
      
    }
    
    
    void loop() {
      
      sensors.requestTemperatures();
      Serial.print(sensors.getTempCByIndex(0));
      Serial.println(" °C");
      
      temperature = sensors.getTempCByIndex(0);
      push();
      delay(wait);
    
    }
    

    Und schon hat man die aktuelle Temperatur in HomeKit eingebunden und kann sie für Automationen oder Benachrichtigungen verwenden. Have Fun!

    76299308-0FFE-4D5C-804D-4EE2A9AFA138.jpeg

    Bildschirmfoto 2020-06-12 um 10.49.04.png

    ESP8266 HTTP-GET Request
    Tutorial: ESP8266 Deep-Sleep


  • Ich verstehe nur Bahnhof … 😄 Ich glaub ich muss mich mal in das Thema einlesen. Klingt nach was für mich hehe


  • @dieterh Kann ich dir nur wärmstens empfehlen. Macht mega Bock und ist auch eigentlich gar nicht so schwer. Also wenn du das mit Homebridge und Homekit etc jetzt meinst 🙂


  • Hi! Kann man dich irgendwie kontaktieren? Will selbst HomeBridge aufsetzen und ein ähnliches Setup mit einem YL-69 aufsetzen, um Bodenfeuchtigkeit etc. von meinen Topfpflanzen zu kriegen.
    Allerdings hab ich da einige Anfängerfragen… 😄
    Würde mich über eine Antwort freuen!


  • Hey @paddel,

    naja da gibt es mehrere Möglichkeiten. 🙂 Du kannst mir hier direkt über mein Profil eine PN schicken (wenn du registriert bist), oder am besten einfach öffentlich ein neues Thema erstellen, so haben mehrere Leute Zugriff und können dir weiterhelfen. 👌 Einfach die Kategorie nehmen in die es am besten passt, wahrscheinlich aber Homebridge, oder 😄

    Weiß ja nicht genau um was es geht. Aber solltest bestimmt fündig werden 🐵 - ansonsten freu ich mich auf deine PN 😎


  • @cooper Danke für die schnelle Antwort!

    Einmal ein paar Randdaten:
    Ich möchte HomeBridge in meiner Wohnung zum laufen kriegen.
    Habe überlegt, das in einen Docker-Container auf einem RPi Zero W zu realisieren.
    Das sollte kein Problem darstellen.

    Nun studiere ich aber Informatik, und habe viel zu wenig Ahnung von ETechnik. 😄
    Hatte mal in einem Praktikum ein OS für einen ATMega644 geschrieben, aber es ist nichts hängen geblieben. ^^
    Und wenn man gerade anfängt will man ungern zu wenig bestellen. Denke das verstehst du!

    Als erstes wollte ich einen Feuchtigkeitssensor per WLAN einbinden.
    Nach ein wenig Recherche, habe ich folgendes Setup skizziert:

    • RPi Zero W mit HomeBridge als Docker Container
    • Feuchtigkeitssensor (YL-69) an einem D1 Mini
    • Damit der D1 Mini nicht immer am Strom hängen soll, wollte ich zB ein Battery / LiPo Shield nutzen

    Jetzt habe ich aber verschiedene Implementierungen gesehen (MQTT zB), aber gefühlt war deine die einzige mit einer GET-Request, welche mir deutlich besser gefällt.
    Kurze Verständnisfrage: D1 schickt GET-Request mit Temperatur an den Server und entsprechend wird dort ein Wert verändert, welcher durch HomeBridge in HomeKit landet. Korrekt?

    Glaubst du, das reicht an Hardware?
    Ich habe wenig Ahnung von Limitations der Mikrocontroller. Weißt du, ob ich den Sensor und potentiell das Battery Shield einfach übereinander stecken könnte?

    Danke dir!


  • Kurze Verständnisfrage: D1 schickt GET-Request mit Temperatur an den Server und entsprechend wird dort ein Wert verändert, welcher durch Homebridge in HomeKit landet. Korrekt?

    Korrekt. In dem Fall brauchst du auf dem D1 Mini direkt die Temperatur. Die Temperatur wird so wie sie ist an Homebridge übergeben. Meinetwegen 22.5 als Float.
    http://makesmart-server:51828/?accessoryId=temperatur&value=22.5
    Die Einheit wiederum kommt von deiner Homebridge bzw. von HomeKit, das weiß ich ehrlich gesagt gerade nicht.


    Glaubst du, das reicht an Hardware?

    Auf jeden Fall! Der D1 Mini ist was das angeht absolut ausreichend für den Zweck, da brauchst du dir absolut keine Sorgen machen, aus dem Datenblatt kannst du dir die wichtigsten Daten mal entnehmen - ESP8266 D1 Mini Datenblatt.


    Und was deinen Sensor angeht, sollte sich das 1:1 übertragen lassen. Das verwendete Plugin unterstützt das ganze auf jeden Fall mal.

    Auszug aus homebridge-http-webhooks

    {
       "id": "sensor6",
       "name": "Sensor name 6",
       "type": "humidity"
     }
    

    Weißt du, ob ich den Sensor und potentiell das Battery Shield einfach übereinander stecken könnte?

    Mit den passenden Header-Pins sollte das denke ich aufreden Fall gehen.


    Was dir noch helfen könnte, wäre mein Tutorial bzgl. Deep-Sleep, kannst ja mal einen Blick reinwerfen.

    ESP8266 Deep Sleep Tutorial - ist zwar für einen ESP01-S aber die Pin-Bezeichnungen sowie der Code sind 1:1 die selben. GPIO16 und RST findest du ebenfalls am D1 Mini - denke da sollte es auch weniger Probleme geben.

    ESP8266 D1 Mini Pinout - Pinbelegeung


    Ich würde dich bloß bitten, wenn es jetzt noch tiefer ins Detail geht in den einzelnen Bereichen, dann bitte ein neues, eigenes Thema zu eröffnen.
    Ich antworte dann da. Dann kann man das immer Häppchenweise behandle. 🙂

    Liebe Grüße


  • Hallo,
    Ich wollte das Projekt nachbauen, bei der Ausgabe über den seriellen Monitor wird mir -127 Grad angezeigt

    Kann mir jemand helfen ?

    Vielen Dank


  • @julian Entweder ist der Sensor defekt oder die Verdrahtung passt nicht.
    Hast du D4 genommen oder einen anderen Pin.


  • @cooper Hat sich schon erledigt, es lang an den Kontakt der PINs


  • Servus

    bin auch neu in dem Thema und total fasziniert.

    nur weis ich grad nicht wo der Get Request code hinsoll …
    wo soll ich den genau einbinden ?

    zudem hab ich das Problem, das auf der Homebridge beim HTTP Plugin kein Webcode zum scannen angezeigt wird. verweist mich immer auf die einstellungen bzw Konfig

    Danke schon mal

    Tottie78


  • Warum kommt beim flashen des ESP8266 die Fehlermeldung ?

    DS18B20:67:19: error: call to ‘HTTPClient::begin’ declared with attribute error: obsolete API, use ::begin(WiFiClient, url)

    67 | if (sender.begin(“http://192.168.178.69:51828/?accessoryId=temperatur&value=” + String(temperature))){

      |       ~~~~~~~~~~~~^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    

    exit status 1

    call to ‘HTTPClient::begin’ declared with attribute error: obsolete API, use ::begin(WiFiClient, url)


  • @tottie78
    Hatte das selbe Problem mit der aktuellen IDE
    Du musst WiFi Client mitverwenden

    Bei den anderen includes:
    #include <WiFiClient.h>

    Nach HTTPClient sender ; noch das :
    WiFiClient client; einfügen

    Und „Client“ noch bei
    if (sender.begin(…… einfügen damit es so aussieht:

    If (sender.begin(client, „http://ipDerHomebridge:Port/?accessory=derNameDesSensors&value=„ + String(temperature))){

    Seither läufts bei mir

    Liebe Grüße


  • @intruder Auch wenn es verspätet kommt vielen Dank! Hab den Sketch mal mit deinen Angaben geupdated! 🙂 Danke

Ähnliche Themen

  • 3
  • 54
  • 1
  • 1
  • 9