Sobald du die zuvor aufgeführte Datei "IOT-Temperatur-Thingspeak" heruntergeladen hast, kannst du diese in der Arduino IDE öffnen. Bevor du nun das Programm an dem zuvor verdrahteten ESP ausprobieren kannst, müssen an den jeweiligen Stellen noch Änderungen vorgenommen werden (WiFi Name/Passwort und API-Key).

Nachfolgend erkläre ich dir die einzelnen Programmzeilen, sodass du den Code verstehst und selbst Änderungen nach deinen Wünschen vornehmen kannst.

//Bibliotheken für die Internetverbindung einbinden
#include <WiFi.h>
#include <HTTPClient.h>

//Bibliotheken für den Dallas Sensor einbinden
#include <OneWire.h>
#include <DallasTemperature.h>
Hier werden die zuvor heruntergeladenen Bibliotheken in das Programm eingebunden. Sollte in diesen Zeilen eine Fehlermeldung auftreten, so überprüfe, ob du die Bibliotheken auch wirklich heruntergeladen hast und das richtige Board "ESP32 Dev Module" ausgewählt ist.


//Jetzt wird definiert, dass wir den Daten-Bus des Dallas an Pin 32 anschließen
#define ONE_WIRE_BUS 32

//Anschließend wird mit dem Wert ein Objekt oneWire der Klasse OneWire erzeugt
OneWire oneWire(ONE_WIRE_BUS);

//Jetzt wird ein Objekt sensors der Klasse DallasTemperatur mit dem Datenbus gebildet
DallasTemperature sensors(&oneWire);

//Temperatur und Luftfeuchte Variablen die später beschrieben und an Thingpeak gesendet werden
String temperatur = "";
//String luftfeuchte = ""; Erweiterung der Luftfeuchte
In diesem Ausschnitt werden die nötigen Deklarationen zur Verwendung des Sensors gemacht. Zuerst wird der Pin 32 für den Datenbus definiert. Anschließend wird ein Objekt mit dem Namen "oneWire" aus der Klasse "OneWire" gebildet, wobei der Pin für den Datenbus übergeben wird. Dazu wird auch noch ein Objekt "sensors" aus der Klasse "DallasTemperature" gebildet, welches die Referenz für das Objekt "oneWire" übergeben bekommt.
Zuletzt wird dann noch die Variablen für die Temperatur angelegt.

Hier wurde auch schon ein Tipp für die später kommende Aufgabe mit dem DHT11 Sensor, welcher auch die Luftfeuchtigkeit misst, versteckt.



//Hier musst du den WLAN Name des Netzwerkes und das jeweilige Passwort ergänzen
const char* ssid = "GEBE_HIER_DEIN_NETZWERKNAME_EIN";
const char* password = "GEBE_HIER_DEIN_NETZWERK_PASSWORD_EIN!";

//Dies ist der Server Name für Thingspeak
const char* serverName = "http://api.thingspeak.com/update";

//Hier musst du deinen API Key ergänzen
String apiKey = "GEBE_HIER_DEIN_API_KEY_EIN";
Wie in den Kommentaren schon geschrieben, musst du hier deine Netzwerkdaten (Name und Passwort) sowie deinen API-Key eingeben.


//Dies ist der Zähler, wie oft der ESP32 schon neu hochgefahren (aufgewacht) ist (Stichwort DEEP-Sleep)
RTC_DATA_ATTR int bootCount = 0;
In diesem Projekt wird zusätzlich auch ein Augenmerk auf die Effizienz gelegt. Dafür wird der ESP immer wenn dieser nicht benötigt wird, also gerade kein Messwert aufgenommen werden soll, in den sogenannten Deep-Sleep (Tiefschlaf) versetzt. Dies hat den Hintergrund, dass die WiFi Verbindung viel Strom verbraucht (bis zu 170 mA) und im Deep-Sleep nur noch ein Prozessor des ESPs läuft, welcher den Stromverbrauch auf ca. 50 µA senkt. 
Die Variable "bootCount" ist dabei die Variable, welche die Anzahl der Neustarts zählt.


//Umrechnung von μs auf s (Sekunden) weil der Deep Sleep in μs eingestellt wird
int umrechnung_us_zu_s = 1000000;

//Intervall in Sekunden wo der ESP neue Werte schicken soll und in der Stromsparmodus gehen soll ("schlafen")
int schlafzeit_in_s = 15;

//die 15s sollte nicht unterschritten werden, da ThingSpeak bei den kostenlosen Profilen maximal alle 15s
//einen Wert emfängt. Bei einer längeren Unterschreitung kannst du von ThinkSpeak ausgeschlossen werden
Der Deep-Sleep wird hier mit einem Timer gesteuert, d.h. der ESP geht periodisch immer für eine bestimmte Zeit in den "Tiefschlaf" und wacht dann nach Ablauf dieser Zeit automatisch wieder auf. Dabei wird die Zeit bis zum nächsten aufwachen in Mikrosekunden angegeben. Dafür wird "umrechnung_us_zu_s" gespeichert, welcher den Faktor von einer Million von µs zu s angibt. Damit kann mit "schlafzeit_in_s" einfach die Zeit des Deep-Sleep in Sekunden angegeben werden.
Wichtig dabei ist, dass die Zeit von 15 Sekunden nicht unterschritten wird, da bei einem kostenlosen Account auf ThingSpeak ein kürzeres Intervall nicht zulässig ist.


//Methode um Temperatur zu lesen
String readDallasTemperature()
{
  //Sensor wird auf eine Abfrage vorbereitet
  sensors.requestTemperatures();

  //Lese Temperatur in Celsius (default)
  float temperatur = sensors.getTempCByIndex(0); //By Index, da auch mehrer Sensoren auf dem Bus sein können
  //Lese Temperatur in Fahrenheit:
  //float t = sensors.getTempFByIndex(0);
  //Wenn nichts gelesen werden kann:
  if(isnan(temperatur))
  {
    Serial.println("Es konnte keine Temperatur von dem Dallas-Sensor empfangen werden!");
    return "--";
  }
  else //Wenn Wert Gelesen wurde
  {
    Serial.println("Die Temperatur beträgt:");
    Serial.print(temperatur);
    Serial.print("°C");
    return String(temperatur); //Es wird die Temperatur als String zurückgegeben
  }
}
Nun folgt die String Methode, also der Ablauf welcher aufgerufen werden kann und eine Zeichenkette (String) zurückgibt. Die obere Methode liest beispielsweise die Temperatur aus. Falls dies nicht geklappt hat, wird "--" zurückgegeben und "Es konnte keine Temperatur von dem Dallas-Sensor empfangen werden!", auf dem seriellen Monitor ausgegeben. Konnte die Temperatur hingegen erfolgreich gelesen werden, wird diese als String zurückgegeben und ebenfalls auf dem seriellen Monitor ausgegeben.


void setup() 
{
  //Der Serialle Monitor (oben rechts das Symbol mit der Lupe) wird auf eine Bound-Rate von 115200 eingestellt
  Serial.begin(115200);

  ++bootCount; //Die Variable zum Zählen wie oft gebootet wurde eins hochzählen
  Serial.println("Boot number: " + String(bootCount));

  //Der Dallas Sensor wird initalisieren 
  sensors.begin();
In diesem Ausschnitt startet die Funktion "void setup()", diese wird in normalen Programmen ohne Deep-Sleep nur einmalig ausgeführt und anschließend in die "void loop()" Funktion übergegangen. Aufgrund der Deep-Sleep Funktion wird jedoch bei jedem neu-booten nur einmalig die setup() Funktion ausgeführt und die loop() Funktion gar nicht erreicht.
Dabei wird zunächst der serielle Monitor mit einer Baud-Rate von 115200 initialisiert, danach der Zähler für die Anzahl der Neustarts plus eins hochgezählt und die Anzahl seriell ausgegeben.
Anschließend wird noch das zuvor erstellte Objekt "sensors" initialisiert.


  //Jetzt wird sich mit dem WLAN verbunden
  WiFi.begin(ssid, password);
  Serial.print("Verbinden mit ");
  Serial.println(ssid);
  delay(100);
  int counter = 0; //Zähler für Verbindungsaufbau
  while(WiFi.status() != WL_CONNECTED) //Ausführen solange nicht verbunden
  {
    counter++;
    delay(500);
    Serial.print(".");
    if(counter >= 5) //Wenn mehr als fünfmal die Verbindung nicht aufgebaut wurde: new verbinden
    {
      counter = 0;
      WiFi.disconnect();
      delay(100);
      WiFi.begin(ssid, password);
    }
  }
  Serial.println("");
  Serial.print("Erfolgreich verbunden mit der IP-Adresse: ");
  Serial.println(WiFi.localIP());
Hier wird der ESP nun mit den zuvor erstellten Konstanten ssid und password mit dem WiFi verbunden, und am Schluss die IP-Adresse der Gerätes ausgegeben.


  //Daten erfassen
  temperatur = readDallasTemperature(); //aktuelle Temperatur lesen und abspeichern
  //luftfeuchte = ReadDallasLuftfeuchte(); //Erwaeiterung für Luftfeuchte
Es folgen die beiden Zeilen, in denen die Temperatur und Luftfeuchtigkeit mit den zuvor erstellten Methoden ausgelesen werden und in die entsprechenden, ebenfalls zuvor erstellten, String-Variablen gespeichert werden.

Der Tipp hier bezieht sich auf einen Befehl, wie er aussehen könnte wenn der Dallas Sensor auch die Luftfeuchtigkeit messen könnte, so wie es der DHT11 kann.


  //senden der Daten an Thingspeak
  if(WiFi.status() == WL_CONNECTED) //Wenn die WiFi Verbindung noch steht dann führe folgendes aus
  {
    HTTPClient http; //neues Objekt http der Klasse HTTPClient
    
    http.begin(serverName); //Die oben initialisierte Domain "serverName" wird an http übergeben

    //Content-Type Header (nicht ändern)
    http.addHeader("Content-Type", "application/x-www-form-urlencoded");

    //Daten die gesandet werden einfügen                                    //Erweiterung durch Luftfeuchtigkeit:
    String httpRequestData = "api_key=" + apiKey + "&field1=" + temperatur; //+ "&field2=" + luftfeuchte;
    //Daten senden
    int httpResponseCode = http.POST(httpRequestData);

    Serial.print("HTTP Response (Antwort) code: ");
    Serial.println(httpResponseCode); //Gibt den HTTP Antwort Code zurück, wenn alles gut ist : "200"

    //Löscht das http Objekt wieder
    http.end();
  }
  else
  {
    Serial.println("WiFi-Verbindung getrennt!"); //Falls die WiFi Verbindung getrennt wurde
    Serial.println(WiFi.status());
  }
In diesem Bereich wird nun der Wert in "temperatur" an die ThingSpeak-Cloud geschickt. Hier solltest du nur Änderungen vornehmen, wenn du genau weißt, was du machst, da sonst die Verbindung zu der Cloud nicht mehr bestehen kann, dir aber keine Fehlermeldung angezeigt wird. Achten solltest du dabei auch auf den HTTP Response Code. Wenn dieser "200" beträgt hat die Übertragung fehlerfrei funktioniert. Auch hier wurde wieder ein Tipp für die DHT11 Erweiterung integriert.


  Serial.println("Tiefschlaf...");
  esp_sleep_enable_timer_wakeup(umrechnung_us_zu_s * schlafzeit_in_s); //Deep Sleep mit Timer initialisieren
  delay(100);
  esp_deep_sleep_start(); // ESP geht hier in den Stromsparmodus und wacht in schlafzeit_in_s Sekunden wieder auf

  Serial.println("Dieser Text ist total unnötig, da er niemals ausgegeben wird.");
}

void loop() 
{

}
Im letzten Teil wird nun der Tiefschlaf vorbereitet und ausgeführt. Dabei wird auf die ganz oben gespeicherten Variablen zurückgegriffen.
Wichtig: Da alles was unterhalb der Methode "esp_deep_sleep_start()" steht, nicht mehr ausgeführt wird, ist der Text danach nicht mehr für die Grundfunktion relevant. 
Die loop() Funktion ist so auch ohne Funktion, wird aber von der Arduino IDE formhalber so verlangt.


Außerdem MUSS ein 2,4 GHz Netzwerk verwendet werden, da der ESP32 nur dieses unterstützt.

Nachfolgend werden dir ein paar Änderungsaufgaben gestellt, wo du unter Beweis stellen kannst, wie gut du dieses Programm verstanden hast.

Zuletzt geändert: Mittwoch, 31. Januar 2024, 08:11