Labortagebuch - Arduino - Raspberry Pi
19.12.2025 - ESP32 - SD-Card - Data Logger - DS18B20
1. Der Temperatursensor DS18B20
2. ESP32 - OLED-Display
3. ESP32 - DS18B20 - Webserver
Temperatursensor DS18B20
Der DS18B20 ist ein digitaler Temperatursensor mit einer einstellbaren Auflösung von 9-12bit und eine Messgenauigkeit von ±0.5°C im Bereich von -10°C bis +85°C (außerhalb dieses Temperaturbereiches wird es ungenauer). Standardmßig ist beim Einschalten 12 Bit eingestellt. Angesprochen wird der DS18B20 über den sogenannten ‚One-Wire-Bus‘. Der Begriff One-Wire kommt daher, weil man den Sensor mit nur einer Datenleitung (und GND) ohne zusätzliche Spannungsversorgung betreiben kann. Die benötigte Spannung beträgt 3,3 V bis 5 V. Der Sensor verbraucht bei aktiver Temperaturumwandlung nur 1 mA.
Es gibt zwei Ausführungen. Einmal ist es die Ausführung TO-92 (üblich für Transistoren), dann gibt es die andere in Form einer wasserdichten Sonde, die nützlicher ist, wenn etwas weit entfernt, unter Wasser oder unter der Erde gemessen wird.
Wasserdichte Sonde
TO-92 Gehäuse
Als erstes überprüfen wir den Temperatursensor über die Ausgabe der Werte im seriellen Monitor. Dazu müssen zwei Bibliotheken zur Verfügung gestellt werden. Dieses sind:
1. OneWire.h von der Seite https://github.com/PaulStoffregen/OneWire
2. DallasTemperature.h für den Temperatursensor.
Die Downloadseite ist: https://github.com/milesburton/Arduino-Temperature-Control-Library
Die beiden Libraries können auch direkt hier heruntergeladen werden:
One-Wire-Library(21,7 kB) und
Library für DS18B20-Temperatursensor (38,5 kB)
1. ESP32 - DS18B20 - Ausgabe auf dem seriellen Monitor
Die Verkabelung
Sketch - ESP32 - DS18B20 - serieller Monitor

#include <OneWire.h>
#include <DallasTemperature.h>
const int SensorDataPin = 2;
OneWire oneWire(SensorDataPin);
DallasTemperature sensors(&oneWire);

void setup() {
Serial.begin(115200);
sensors.begin();}

void loop() {
sensors.requestTemperatures();
float temperature_Celsius = sensors.getTempCByIndex(0);
float temperature_Fahrenheit = sensors.getTempFByIndex(0);
Serial.print("Temperatur: ");
Serial.print(temperature_Celsius);
Serial.println(" ºC");
Serial.print("Temperatur: ");
Serial.print(temperature_Fahrenheit);
Serial.println(" ºF");
Serial.println("");
delay(10000);}

Achtung:
Es gibt eine Fehlermeldung, wenn der Temperatursensor während des Hochladens angeschlossen ist. Es reicht dann, wenn man beim Hochladen den +-Pol trennt und dann wieder anschließt, wenn der Sketch hochgeladen ist. Bei einem ESP8266 ist dies nicht nötig. Einen Grund dafür konnte ich nicht finden.

Die Datei kann hier heruntergeladen werden:
Sketch zur seriellen Anzeige von DS18B20
Ausgabe der Werte im seriellen Monitor
2. ESP32 - OLED-Display - SSD1306 - Test
Das OLED-Display SSD1306

Das Herzstück des Moduls ist ein leistungsstarker Single-Chip-CMOS-OLED-Treibercontroller – SSD1306, der die gesamte RAM-Pufferung übernimmt. Außerdem reicht die Betriebsspannung des SSD1306-Controllers von 1,65 V bis 3,3 V, was ihn ideal für die Schnittstelle mit 3,3-V-Mikrocontrollern wie dem ESP32 macht.
Ein OLED-Display benötigt im Gegensatz zu einem LCD-Zeichendisplay keine Hintergrundbeleuchtung, da es sein eigenes Licht erzeugt. Dies erklärt den hohen Kontrast, den extrem weiten Betrachtungswinkel und die Fähigkeit des Displays, tiefe Schwarzwerte anzuzeigen .
Das Fehlen einer Hintergrundbeleuchtung reduziert den Stromverbrauch erheblich. Ein typisches OLED-Display verbraucht im Durchschnitt etwa 20 mA.
Unabhängig von der Größe des OLED-Displays enthält der SSD1306-Treiber einen 1 KB großen Graphic Display Data RAM (GDDRAM), der das auf dem Bildschirm anzuzeigende Bitmuster speichert. Dieser 1 KB große Speicherbereich ist in 8 Seiten (von 0 bis 7) unterteilt. Jede Seite hat 128 Spalten/Segmente (Block 0 bis 127). Und jede Spalte kann 8 Datenbits (von 0 bis 7) speichern. Die folgende SKizze zeigt den Aufbau.
Jedes Bit stellt ein einzelnes OLED-Pixel auf dem Bildschirm dar, das programmgesteuert ein- oder ausgeschaltet werden kann.
Weitere Infos zum SSD1306-OLED-Display

Das OLED-Display benötigt keine Hintergrundbeleuchtung, was in dunklen Umgebungen einen sehr schönen Kontrast ergibt. Darüber hinaus verbrauchen die Pixel nur dann Energie, wenn sie eingeschaltet sind, so dass das OLED-Display im Vergleich zu anderen Displays weniger Strom verbraucht. Das Modell hat vier Pins und kommuniziert mit dem Arduino über das I2C-Kommunikationsprotokoll.
Für die Steuerung des OLED-Displays benötigt man 2 Bibliotheken. Dieses sind:
1.Adafruit_GFX.h und
2.Adafruit_SSD1306.h
Die Libraries kann man mit Hilfe des Library-Managers der Arduino-IDE installieren. Diese Library-Dateien können aber auch hier heruntergeladen werden:
1. Adafruit_SSD1306.h(39,4 kB) und
2. Adafruit_GFX.h(346 kB)

Eine sehr gute Info über die Möglichkeiten des SSD1306-Displays mit unterschiedlichen Libraries findet man auf der folgenden Seite:
Hartmut Waller-Seite
Es gibt noch weitere ausführliche Darstellungen mit umfangreichen Beispielen. Als erstes wäre da die Internetseite randomnerdtutorials
1. Für den Mikrocontroller ESP32 randomnerdtutorials
2. für den Arduino randomnerdtutorials

3. für den ESP32 lastminuteengineers

4. für den ESP32 esp32io

Verkabelung des OLED-Displays am ESP32

Befehle der Library Adafruit_SSD1306

Schlüsselwort Parameter Aktion
begin(Parameter); SSD1306_SWITCHCAPVCC,Adresse in Hexadetimal z.B. 0x3C OLED-Display starten
dim(Parameter); true, false Bildschirm dunkler schalten
width(); Bildschirmbreite feststellen
height(); Bildschirmhöhe feststellen
clearDisplay(); Bildschirm löschen
setRotation(Drehrichtung); 0=keine Drehung
1=Drehung um 90Grad im Uhrzeigersinn drehen
2=180Grad drehen
3=270Grad im Uhrzeigersinn drehen
Bildschirm drehen
fillScreen(Farbe); Bildschirmhintergrundfarbe festlegen
drawPixel(x-Achse,y-Achse,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) einzelnen Pixel zeichnen
display; Bildschirm anzeigen
setTextSize(Parameter); Werte von 1 bis 8 Textgröße
drawLine(StartX,StartY,EndX,EndY,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) Linie zeichnen
drawFastVLine(StartX,StartY,Breite,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) Vertikale Linie zeichnen
drawFastHLine(StartX,StartY,Breite,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) Horizontale Linie zeichnen
drawRect(StartX,StartY,Breite,Höhe,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) Rechteck zeichnen
drawRoundRect(StartX,StartY,Breite,Höhe,Eckenradius,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) abgerundetes Rechteck zeichnen
fillRect(StartX,StartY,Breite,Höhe,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) ausgefülltes Rechteck zeichnen
fillRoundRect(StartX,StartY,Breite,Höhe,Eckenradius,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) ausgefülltes, abgerundetes Rechteck zeichnen
drawCircle(MittelpunktX,MittelpunktY,Radius,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) Kreis zeichnen
fillCircle(MittelpunktX,MittelpunktY,Radius,Farbe); Farbe: White(SSD1306_WHITE) BLACK(SSD1306_BLACK) Ausgefüllten Kreis zeichnen
setCursor(x-Achse,y-Achse); Cursor setzen
print("Text"); Text schreiben
Das OLED-Display SSD1306

SCL: Serial Clock pin. Used for providing clock pulse for I2C Communication.
SDA: Serial Data pin. Used for transferring Data through I2C Communication.
VCC: Verbindung zum 3,3V oder 5V Pin
GND: Verbindung mit dem GND-Pin des ESP32

Die Daten
Auflösung: 128x64
Winkel: >160o
Spannunsversorgung: 3,3V, 5V
Größe: 2,7 x 2,8cm
Für die Kontrolle sind nur 2 Pins nötig
Temperaturbereich: -30oC - 70oC
Test-Programm
Im folgenden einfachen Sketch wird der Text Hello, world! auf dem OLED-Display ausgegeben.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#define SCREEN_WIDTH 128 // OLED display width, in pixels
#define SCREEN_HEIGHT 64 // OLED display height, in pixels
// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

void setup() {Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);}
Serial.println("Hello, world!");
delay(2000);
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.println("Hello, world!");
display.display(); }

void loop() {}

Sketch zur Ausgabe von Hello, world!
Verschiedene geometrische Formen
Die Beispiele zusammengefasst stammen von mehreren Internet-Seiten. Dieses sind:

1. randomnerdtutorials.com/esp32-ssd1306-oled-display-arduino-ide/
2. www.electronicwings.com/esp32/128x64-oled-graphic-display-interfacing-with-esp32
3. microcontrollerslab.com/oled-esp32-arduino-ide/
4. circuitdigest.com/microcontroller-projects/displaying-text-and-characters-oled-module-with-esp32


Die beste Seite ist meiner Meinung nach die folgende:
5. lastminuteengineers.com/oled-display-esp32-tutorial/


Sketch zur Ausgabe von Hello World!
Erläuterung der einzelnen Code-Zeilen
Im folgenden einfachen Sketch wird der Text Hello, world! auf dem OLED-Display ausgegeben.

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

Die Adafruit_SSD1306.h - Library wird für das eigentliche OLED Display benötigt und steuert den Controller am Display an. Die zweite Library (Adafruit_GFX.h) ist die Grafik Library, die z. B. einen String einfach am Display anzeigt und im Hintergrund berechnet, welche Pixel angesteuert werden müssen, um diesen String richtig am Display anzeigen zu können.

#define SCREEN_WIDTH 128 // OLED-Display Breite, in Pixel
#define SCREEN_HEIGHT 64 // OLED-Display Höhe, in Pixel

// Declaration for an SSD1306 display connected to I2C (SDA, SCL pins)
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
Anschließend erstellen wir ein display-Objekt mit der Bibliothek Adafruit_SSD1306. Wir teilen ihm die Bildschirmgröße mit (128 Pixel Breite und 64 Pixel Höhe) und teilen ihm mit, dass wir I2C verwenden. Da unser OLED-Modul keinen Reset-Pin besitzt, übergeben wir -1, um anzuzeigen, dass wir keinen verwenden.

void setup() { Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) { // Address 0x3D for 128x64
Serial.println(F("SSD1306 allocation failed"));
for(;;);}
Anschließend starten wir mit display.begin() die Kommunikation mit dem OLED-Display. Das erste Argument versorgt den Bildschirm mit Strom, das zweite Argument legt die I²C-Adresse fest (die I²C-Adresse des Bildschirms ist normalerweise 0x3C.)

Serial.println("Hello, world!");
Ausgabe des Textes im seriellen Monitor

delay(2000);
display.clearDisplay();
Sobald das Display bereit ist, wird der Bildschirm mit display.clearDisplay() gelöscht. Damit ist der Bildschirm jetzt leer.

display.setTextSize(1);
Mit diesem Befehl wird die Textgröße festgelegt. Der kleinste Wert ist 1. Größere Zahlen (maximal 8) vergrößern den Text.

display.setTextColor(WHITE);
Hier wird die Textfarbe in weiß(WHITE) eingestellt.

display.setCursor(0, 10);
Der Cursor wird an die Stelle x=0 und y=10 gesetzt.

display.println("Hello, world!");
Mit println() wird der Text oder der Inhalt einer Variablen an die angegebene Stelle geschrieben. mit println() wird eine neue Zeile erzeugt, mit print() dagegen nicht.

display.display(); }
Mit display.display() wird der Bildschirm aktualisiert. Er zeigt alles an, was mit print() und println() angegeben wurde.

void loop() {}

Hier können einige Sketche heruntergeladen werden, die die Möglichkeiten der Darstellung mit dem OLED-Display SSD1306 zeigen.

Zunächst werden im folgenden Sketch alle 2-dimensionalen geometrischen Formen nacheinander dargestellt, einmal nur mit Umrandung und dann ausgefüllt.
Sketch: Geometrische Objekte nacheinander

Die geometrischen Objekte werden nebeneinander auf einem Window dargestellt:
Sketch: Geometrische Objekte nebeneinander

Als nächstes werden verschiedenen Objekte wie Texte, Zahlen usw. hintereinander ausgegeben:
Sketch: Ausgabe von verschiedenen Objekten

Hier werden verschiedene Möglichkeiten der Programmierung dargestellt
Sketch: Umfangreiche Bewegungen und Animationen

Auch Animationen sind möglich. Hier bewegt sich ein Stern von links nach rechts:
Sketch: Animation mit dem SSD1306

Die Adafruit GFX-Bibliothek ermöglicht die Verwendung alternativer Schriftarten neben den integrierten. Sie bietet die Wahl zwischen Serif, Sans Sans und Mono. Jede Schriftart ist in Fettdruck, Kursivschrift und verschiedenen Größen verfügbar.
Die Größen werden durch die jeweilige Schriftart bestimmt: setTextSize(). Diese Methode funktioniert nicht mit diesen Schriftarten. Die Schriftarten sind in den Schriftgrößen 9, 12, 18 und 24 Punkt verfügbar und enthalten außerdem 7-Bit-Zeichen (ASCII-Codes) (im Schriftnamen als 7b bezeichnet). Eine gute Einführung bzgl. der Schriftarten findet man bei:
Randomnerdtutorials-Seite
Sketch: Verschiedene Schriftarten
Grafiken können auch ausgegeben werden. Dazu muss das Bild im BMP-Format vorliegen und mit einem OLED-Bildkonverter in ein Byte-Array umgewandelt werden. Dieses Array besteht aus Zahlen, die jedes einzelne Pixel im Bild repräsentieren. Dazu gibt es spezielle Software, die dies macht. Auf folgenden zwei Internetseiten wird dieser Vorgang umfassend dargestellt. Randomnerdtutorials-Seite
lastminuteengineers-Seite
Sketch: Marilyn Monroe - Bitmap
Hier beginnt die Ausgabe der Werte des Temperatursensors DS18B20 auf dem OLED-Display SSD1306
Im Folgenden sollen die Temperaturwerte des DS18B20-Sensors auf dem OLED-Display SSD1306 ausgegeben werden. Die Verkabelung des Displays erfolgt wie oben im Bild gezeigt. Also:
SSD1306 ESP32
GND GND
VCC 3,3 oder 5V
SDA GPIO 21
SCL GPIO 22

Für den Temperatursensor gilt:
DS18B20 ESP32
GND GND
VCC 3,3 oder 5V
DATA GPIO 2

Der SKetch für die Ausgabe kann hier heruntergeladen werden.
Sketch: Anzeige der Werte auf dem SSD1306

#include < Wire.h >
#include <: Adafruit_GFX.h >
#include < Adafruit_SSD1306.h >
#include < OneWire.h %gt;
#include < DallasTemperature.h >
const int SensorDataPin = 2;
OneWire oneWire(SensorDataPin);
DallasTemperature sensors(&oneWire);
Adafruit_SSD1306 display = Adafruit_SSD1306(128, 64, &Wire, -1);

void setup() { Serial.begin(115200);
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);}
delay(2000); display.clearDisplay();
display.setTextColor(WHITE);}

void loop() { delay(5000);
display.setCursor(0,0);
display.setTextSize(1);
display.clearDisplay();
sensors.requestTemperatures();
float temperature_Celsius = sensors.getTempCByIndex(0);
float temperature_F = sensors.getTempFByIndex(0);
Serial.print("Temperatur = "); Serial.print(temperature_Celsius); Serial.println(" *C");
display.setTextSize(1);
display.setCursor(0,0);
display.print("Temperatur: ");
display.setTextSize(2);
display.setCursor(0,10);
display.print(temperature_Celsius);
display.print(" ");
display.setTextSize(1);
display.cp437(true);
display.write(167);
display.setTextSize(2);
display.print("C");
Serial.println();
display.display();
delay(2000);}
3. ESP32 - DS18B20 - Ausgabe der Daten im Webbrowser
Die Verkabelung bleibt wie bisher:
Data-Pin des Temperatursensors an Pin 2.
Die Verkabelung
Für die Formatierung der Webseite dient die Datei html.h. Diese muss sich im gleichen Ordner wie der Sketch befinden. Mit Hilfe des Befehls #include "html.h" wird diese eingebunden.
Die Datei html.h
const char html_page[] PROGMEM = R"rawSrting(
< !DOCTYPE html >
< html >
< style >
body {font-family: sans-serif;}
h1 {text-align: center; font-size: 30px;}
p {text-align: center; color: #4CAF50; font-size: 40px;}
</style >
< body >
< h1 > DS18B20 Temperaturanzeige mit ESP32 < /h1 >
< p>Temperatur: < span id="TempValue" >0 < /span>°C < /p >
< script >
setInterval(function() {
var xhttp = new XMLHttpRequest();
xhttp.onreadystatechange = function() {
if (this.readyState == 4 && this.status == 200) {
document.getElementById("TempValue").innerHTML = this.responseText;
} };
xhttp.open("GET", "readTemp", true);
xhttp.send();
},50);
< /script >
< /body >
< /html >
)rawSrting";
Arduino-Sketch

#include < OneWire.h >
#include < DallasTemperature.h >
#include < WiFi.h >
#include < WebServer.h >
#include "html.h"
#define DS18B20PIN 2 /* DataPin des DS18B20 verbunden mit Pin 2 des ESP32*/
OneWire oneWire(DS18B20PIN);
DallasTemperature sensor(&oneWire);
WebServer server(80);
float _temperature;
const char* ssid = "WLAN-Name";
const char* password = "WLAN-Passwort";
void MainPage() {
String _html_page = html_page;
server.send(200, "text/html", _html_page); /*Sendet den Code zum Webserver*/
} void Temp() {
String TempValue = String(_temperature); //Umwandlung in einen string
server.send(200, "text/plane", TempValue); //Sendet updated Temperaturwert zum Webserver
}
void setup(void){
Serial.begin(115200); /*Setzt die Baudrate auf 115200*/
WiFi.mode(WIFI_STA); /*Setzt WiFi in den STA Mode*/
WiFi.begin(ssid, password);
Serial.print("Connecting to ");
Serial.println(ssid);
delay(1000);
while(WiFi.waitForConnectResult() != WL_CONNECTED){Serial.print(".");}
Serial.print("Connected to ");
Serial.println(ssid);
Serial.print("Your Local IP address is: ");
Serial.println(WiFi.localIP()); /*Gibt die lokalw IP aus*/
sensor.begin();
server.on("/", MainPage); /*Zeigt diee Web/HTML Seite*/
server.on("/readTemp", Temp); /*Zeigt die updated Temperaturwert*/
server.begin(); /*Startet den Server*/
delay(1000);
} void loop(void){
sensor.requestTemperatures();
_temperature = sensor.getTempCByIndex(0); /* Liest die Temperatur */
Serial.print("Temperatur = ");
Serial.print(_temperature); /* Druckt die Temperatur im seriellen Fenster */
Serial.println("ºC");
server.handleClient();
delay(1000); }

Sketch: Anzeige der Werte des DS18B20 im Webbrowser
Die Datei html.h
Ausgabe im Webbrowser