Arduino mit DS18B20 Temperatursensor

Ich hatte zunächst meine Heizungsverteiler der Fußbodenheizung per Raspberry Pi Zero und den DS18B20 erfasst. Das Ganze habe ich bereits hier einmal beschrieben. Der Raspberry Pi Zero wird per USB-Kabel bzw. Ladekabel mit Strom versorgt. Ich war daher auf der Suche nach einer mobileren Variante. D.h. eine Stromversorgung per Batterie oder Akku. Dabei bin ich auf das NodeMCU Board gestoßen. Das Board besitzt u.a. einen WLAN-Chip womit es bequem ins Netzwerk eingebunden werden kann.

Auch hier habe ich mir noch Klemmen, eine Aufputzdose, Kabel, die Temperatur-Sensoren und einen 4,7 kΩ Widerstand geholt.
Die Verkabelung ist ähnlich dem des Raspberry Pi Zero. Zwischen dem roten und dem gelben Kabel des Sensors muss der Widerstand geschaltet werden. Das rote Kabel kommt an einen 3V Pin. Das schwarze Kabel G Pin (Ground) und das gelbe Kabel kommt an Pin D1.

Die Stromversorgung passiert jetzt per Powerbank. Hier hatte ich noch eine Alten rumliegen. In dem Fall ist ein alter Powerbank wichtig bzw. eine ohne Überladungsschutz. Hintergrund ist, dass ich den NodeMCU zeitweise in einen Ruhemodus (Deepsleep) versetze damit er noch sparsamer ist. Aber neuere Powerbanks haben einen Überladungsschutz und sie versorgen dann den NodeMCU nicht mehr mit Strom wenn er kurzzeitig aufwachen möchte. Mit meiner aktuellen Einstellung läuft das Module ca. 4 Wochen.

Das NodeMCU Module muss man zunächst mit dem entsprechenden Programm-Code flashen. Dazu benötigt man die Arduino IDE. Diese besorgt man sich am besten von der Arduino-Seite und nicht aus dem Windows-Store.
Dann muss man unter „Datei“ -> „Voreinstellungen“ eine zusätzliche Boardverwalter-URL eintragen:

http://arduino.esp8266.com/stable/package_esp8266com_index.json

Danach muss unter „Werkzeuge“ -> „Board“ -> „Boardverwalter“ das esp8266 Module gesucht und installiert werden. Anschließend nur noch unter „Werkzeuge“ -> „Board“ das „NodeMCU 1.0 (ESP-12E Module“ gewählt werden. Damit sollte unter „Werkzeuge“ das NodeMCU Board mit den entsprechenden Konfigurationsdaten aktiv sein. Damit kann das Programmieren los gehen.

#include <ESP8266WiFi.h>
#include <DallasTemperature.h>
#include <OneWire.h>
#include <WiFiClient.h>
#include <PubSubClient.h>

const char* ssid = "TOLLESSID";
const char* password = "SICHERESPASSWORT";

const char* mqttServer = "SERVERHOST";
const int mqttPort = 1883;
const char* mqttUser = "YourMqttUser";
const char* mqttPassword = "YourMqttUserPassword";
 
WiFiClient espClient;
PubSubClient client(espClient);

#define ONE_WIRE_BUS D1                          //D1 pin of nodemcu

OneWire oneWire(ONE_WIRE_BUS);
 
DallasTemperature sensors(&oneWire);            // Pass the oneWire reference to Dallas Temperature.

char temperatureC1String[7];
char temperatureC2String[7];
char temperatureC3String[7];
char temperatureC4String[7];
 
void setup() {
 
  Serial.begin(9600);
  sensors.begin();
 
  WiFi.begin(ssid, password);
 
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.println("Connecting to WiFi..");
  }
  Serial.println("Connected to the WiFi network");
 
  client.setServer(mqttServer, mqttPort);
  client.setCallback(callback);
 
}

void getTemperature() {
  float tempC;
  do {
    sensors.requestTemperatures(); 
    tempC = sensors.getTempCByIndex(0);
    dtostrf(tempC, 2, 2, temperatureC1String);
    Serial.println("T:");
    Serial.println(temperatureC1String);
    delay(1000);
    
    tempC = sensors.getTempCByIndex(1);
    dtostrf(tempC, 2, 2, temperatureC2String);
    Serial.println("T:");
    Serial.println(temperatureC2String);
    delay(1000);

    tempC = sensors.getTempCByIndex(2);
    dtostrf(tempC, 2, 2, temperatureC3String);
    Serial.println("T:");
    Serial.println(temperatureC3String);
    delay(1000);

    tempC = sensors.getTempCByIndex(3);
    dtostrf(tempC, 2, 2, temperatureC4String);
    Serial.println("T:");
    Serial.println(temperatureC4String);
    delay(1000);
        
  } while (tempC == 85.0 || tempC == (-127.0));
}
 
void callback(char* topic, byte* payload, unsigned int length) {
 
  Serial.print("Message arrived in topic: ");
  Serial.println(topic);
 
  Serial.print("Message:");
  for (int i = 0; i < length; i++) {
    Serial.print((char)payload[i]);
  }
 
  Serial.println();
  Serial.println("-----------------------");
 
}
 
void loop() {
  //client.loop();

  getTemperature();

  while (!client.connected()) {
    Serial.println("Connecting to MQTT...");
 
    if (client.connect("ESP8266Client", mqttUser, mqttPassword )) {
 
      Serial.println("connected");  
 
    } else {
 
      Serial.print("failed with state ");
      Serial.print(client.state());
      delay(2000);
 
    }
  } 
  
  if(client.connected()){
    Serial.print("connected...");
    client.publish("/heizung/kueche", temperatureC1String);
    client.publish("/heizung/bad", temperatureC2String);
    client.publish("/heizung/stube", temperatureC3String);
    client.publish("/heizung/diele", temperatureC4String);
  }
  delay(5000);
  ESP.deepSleep(300e6); 
}

Einige Dinge gilt es noch zu beachten. Es muss die Bibliothek PubSubClient installiert werden. Dazu über „Werkzeuge“ -> „Bibliotheksverwalter“ diese einfach suchen und installieren.

#define ONE_WIRE_BUS D1

Der Wert dieser Variable entspricht dem Pin an welchem euer gelbes Kabel hängt.

ESP.deepSleep(300e6); 

Und dies ist der Ruhemodus bzw. DeepSleep. Dieser Wert entspricht 5 Minuten. Ihr müsst dazu noch ein Kabel zwischen dem D0-Pin und dem RST-Pin verbinden. Damit kann das Module erst aus dem Ruhezustand wieder geweckt werden.

Bei meiner Lösung sende ich die Daten an ein MQTT-Server. Dieser läuft auf meinem NUC als Docker-Container. Da lag eine kleine Schwierigkeit in der Herstellung der Verbindung. Es muss der Hostname verwendet werden. Eine IP klappt in der Konstellation nicht.
Die Daten die an den MQTT gesendet werden, werden von meiner FHEM-Instanz ausgewertet.

define myBroker MQTT IPADRESSE:1883
define mqtt_heizung_bad MQTT_DEVICE
attr mqtt_heizung_bad IODev myBroker
attr mqtt_heizung_bad transmission-state
attr mqtt_heizung_bad userattr subscribeReading_temperatur
attr mqtt_heizung_bad subscribeReading_temperatur /heizung/bad

(Diese Seite enthält Affiliate-Links - Datenschutz)