ESP-01 mit Temperatursensor Dallas DS 18B20

Als Temperaturensor bietet sich der Dallas DS 18B20 an. Er ist preiswert und misst Temperaturen mit einer Genauigkeit von ±0,5°C. Das Schaltlayout:

 

 

Beachten: der ESP verträgt nur 3,3V Spannung und ist nicht 5V-tolerabel!

Um die 3,3V-Versorgung sicherzustellen habe ich ein AMS1117 Step-down Modul eingesetzt, das lt. Datenblatt 12V Eingangsspannung verträgt (lt. Anbieter nur 10V). Darüber kann ich die Schaltung an ein altes 5V-Steckernetzteil anschließen, das ich noch herumliegen habe.

Das ist noch nicht meine Traum-Konfiguration, aber für einen Indoor-Sensor, der an einer normalen Steckdose hängt, mag es gehen. Für den „Feldeinsatz“ draußen mit Batteriebetrieb muss ich mir noch etwas neues ausdenken, denn z.B. die LED an dem AMS1117 ist ein unnötiger Verbraucher.

Die Verbindungen:

ESP Dallas Spannungsversorgung
GND GND GND
3,3V 3,3V 3,3V
GPIO2 mittlerer Pin über Pullup (4,7kΩ) an +3,3V
CH_EN   über Pullup (4,7kΩ) an +3,3V

Das Programm ist ebenfalls nicht sehr kompliziert und die Bibliotheken sind leicht zu bekommen:

Download Code
// Code für eigenen Aufbau

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

#define INTERVAL 5 // Ableseintervall in Minuten
#define FAKTOR 60000 // 60.000 ms = 1 min

//**** Change this Data for your client/host ***************

#define WIFI_AP "AccesspointName"
#define WIFI_PASSWORD "yourpassword"

#define TOKEN "ESP8266_DALLAS_TOKEN" //Change for every new device!

char clientID[] = "DALLAS_Sensor_Bad"; //Change for every new device!
char mqttBroker[] = "192.168.xxx.yyy"; // Adresse des MQTT-Brokers
int subNetIP = xxx; //IP of subnet
int myIP = yyy; //set the last block of IP for every client
String myHostname = "sensor_bathroom";
char mqttSubject[] = "DALLAS/messen/temperatur";
//**********************************************************

// DALLAS
#define ONE_WIRE_BUS 2 // DS18B20 pin
OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature DS18B20(&oneWire);
float lastTemperature;

WiFiClient wifiClient;

PubSubClient client(wifiClient);

int status = WL_IDLE_STATUS;
unsigned long lastMessage;

void setup()
{
Serial.begin(115200);
delay(10);
InitWiFi();
client.setServer( mqttBroker, 1883 );
lastMessage = 0;
lastTemperature = -1;
}

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

if ( millis() - lastMessage > INTERVAL * FAKTOR ) { // Update and send only after 30 Seconds
sendMQTTMessage(getData());
lastMessage = millis();
}

client.loop();
}

float round(float t) { // Muss noch getestet werden!
int tmp = (int)t * 100;
int temp = tmp / 10;
if ((tmp % 10) >= 5) temp++;
return temp / 10.0;
}

String getData() {
float temp;
do {
DS18B20.requestTemperatures();
temp = DS18B20.getTempCByIndex(0);
Serial.print("Temperature: ");
Serial.println(temp);
} while (temp == 85.0 || temp == (-127.0));
String temperature = String(round(temp));
}

void sendMQTTMessage(String message) {
char payload[100];
message.toCharArray( payload, 100 );
client.publish( mqttSubject, payload );
Serial.println( payload );
}

void connectToWiFi() {
WiFi.begin(WIFI_AP, WIFI_PASSWORD);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("Connected to AccessPoint");
}

void InitWiFi()
{
Serial.println("Connecting to AccessPoint ...");
// attempt to connect to WiFi network
IPAddress ip(192, 168, subNetIP, myIP);
IPAddress gateway(192, 168, subNetIP, 1);
IPAddress subnet(255, 255, 255, 0);
IPAddress dns(192, 168, subNetIP, 1);
WiFi.config(ip, dns, gateway, subnet); // auf feste IP einstellen
WiFi.hostname(myHostname); //Hostnamen setzen
WiFi.persistent(false);
WiFi.mode(WIFI_OFF);
WiFi.mode(WIFI_STA);
connectToWiFi();
}

void reconnect() {
// Loop until we're reconnected
while (!client.connected()) {
status = WiFi.status();
if ( status != WL_CONNECTED) {
connectToWiFi();
}
Serial.print("Connecting to MQTT_Broker ...");
// Attempt to connect (clientId, username, password)
if ( client.connect(clientID, TOKEN, NULL) ) {
Serial.println( "[DONE]" );
} else {
Serial.print( "[FAILED] [ rc = " );
Serial.print( client.state() );
Serial.println( " : retrying in 5 seconds]" );
// Wait 5 seconds before retrying
delay( 5000 );
}
}
}

Es wird dabei vorausgesetzt, dass ein eigener Server einen MQTT-Broker bereitstellt, z.B. ein Raspberry Pi mit Mosquitto.

Das nächste Problem ist das Gehäuse. Den Aufbau als Breadboard-Aufbau aufzustellen schließt sich ja wohl per se aus, aber eine offene Platine ist nicht Ehefrauen-kompatibel. Baut man alles in ein Gehäuse ein, heizen der ESP und der AMS1117 den Innenraum auf, so dass schon nach kurzer Zeit nur noch Fantasiewerte angezeigt werden. Dabei hatte ich das Gehäuse schon relativ großzügig in Bezug auf die Abmessungen gewählt.

Der nächste Schritt war, dass ich Lüftungslöcher in Boden und Deckel bohrte – aber auch das  reichte nicht aus. Letztlich musste der Sensor aus dem Gehäuse herausgeführt werden. Gegenüber der Variante mit Lüftungslöchern misst er nun ca. 5°C weniger und damit halbwegs realistische Temperaturen!

Man erkennt, dass das Gehäuse reichlich überdimensioniert ist, aber man benutzt, was man gerade herumliegen hat 🙂

Nachtrag:

Die Geschichte geht weiter: Ein Vergleich mit einem Laborthermometer (das noch aus meiner analogen Fotolaborzeit stammt) zeigt, dass immer noch eine zu hohe Temperatur angezeigt wird (ca. 2°C zuviel). Die einzige verbleibende Erklärung ist, dass sich der Sensor selbst erwärmt.

Der nächste Schritt wird also sein, das komplette Messsystem per DeepSleep auszuschalten, solange nicht gemessen wird. Das heißt, dass entweder ein anderer ESP-Typ zum Einsatz kommen muss, da der GPIO16 beim ESP-01 nicht herausgeführt wurde, oder ich muss eine Leitung direkt an den Prozessor-Chip anlöten… Das wird allerdings eine sehr fummelige Angelegenheit!

… aber es geht 🙂

ESP-01 mit Temperatursensor Dallas DS 18B20

Beitragsnavigation


Ein Gedanke zu „ESP-01 mit Temperatursensor Dallas DS 18B20

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.