ESP8266 Projekte – Pollux Labs https://polluxlabs.net Arduino, ESP32 & ESP8266 | Projekte & Tutorials Fri, 26 Jan 2024 14:51:57 +0000 de-DE hourly 1 https://wordpress.org/?v=6.4.4 https://polluxlabs.net/wp-content/uploads/2020/05/cropped-pollux-labs-p-32x32.png ESP8266 Projekte – Pollux Labs https://polluxlabs.net 32 32 Pflanzenbewässerung mit einem ESP8266 Webserver https://polluxlabs.net/esp8266-projekte/pflanzenbewaesserung-mit-einem-esp8266-webserver/ Wed, 24 Jan 2024 14:11:59 +0000 https://polluxlabs.net/?p=15654 Pflanzenbewässerung mit einem ESP8266 Webserver Weiterlesen »

]]>
In einem früheren Projekt habe ich eine automatische Pflanzenbewässerung mit einem Arduino UNO vorgestellt. In diesem Projekt hier gehst du einen Schritt weiter: Du baust ein Bewässerungssystem mit einem ESP8266 Webserver. Das bedeutet zunächst, dass du den aktuellen Feuchtigkeitswert der Pflanzenerde auf einer Webseite sehen kannst. Zusätzlich startet der ESP2866 die Wasserpumpe für eine festgelegte Zeit, sobald ein bestimmter Wert über- bzw. unterschritten wurde. Kurze Zeit später siehst du den neuen Wert auf der Webseite.

Die Webseite sieht hierbei – je nachdem, wie du das Diagramm einstellst – folgendermaßen aus:

Eine Art Tacho-Diagramm zeigt dir den aktuellen Feuchtigkeitswert an – grün eingefärbt ist hierbei die Spanne, in der die Erde feucht genug ist. Sobald der Feuchtigkeitssensor einen Wert übermittelt, der darüber liegt, startet die Wasserpumpe. Anschließend siehst du die Nadel auf der Anzeige wieder fallen.

Diese Bauteile benötigst du (jeweils eins):

Der Aufbau der Pflanzenbewässerung

Damit du ein 5V-Relais am ESP8266 betreiben kannst, benötigst du einen Spannungswandler, um die ausgehenden 3,3V auf 5V zu konvertieren. Auch den Feuchtigkeitssensor betreibst du dann mit 5V. Die Wasserpumpe benötigt zusätzliche Batterien, die über das Relais zugeschaltet werden. Orientiere dich beim Aufbau an folgender Skizze:

___STEADY_PAYWALL___

Pflanzenbewässerung mit dem ESP8266

Ein Hinweis zum Relais: Die Belegung der Pins kann bei deinem Modell variieren – achte darauf den richtigen Pin für das Signal mit deinem Arduino zu verbinden. Bitte schließe auch keine Wasserpumpe an, die mit Netzspannung betrieben wird – das ist für dieses Projekt zu gefährlich!

Der Sketch und weitere Dateien

Wie jedes andere Arduino- oder ESP8266-Projekt hat auch dieses einen Sketch – aber nicht nur das. Da du im Prinzip einen Webserver baust, benötigst du auch etwas HTML und CSS für die Webseite. Außerdem kommt hier noch JavaScript für das Tacho-Diagramm zum Einsatz.

Der Code hierfür ist in entsprechenden Dateien gespeichert, die du mit Hilfe von LittleFS auf deine ESP8266 überträgst und dort speicherst. Falls das noch neu für dich ist, findest du auf Pollux Labs ein entsprechendes LittleFS-Tutorial.

Derzeit (Jan. 2024) funktioniert LittleFS noch nicht mit der neuen Arduino IDE 2.x – deshalb musst du auf die ältere Version 1.8.19 zurückgreifen. Diese kannst du nach wie vor auf der offiziellen Download-Seite im Bereich Legacy IDE herunterladen.

Noch ein Hinweis: Dieses Projekt baut auf der Vorarbeit von Random Nerd Tutorials auf. Die nötigen Anpassungen in den HTML-, CSS- und JS-Dateien sowie den Sketch kannst du dir hier herunterladen. Wie du mit dem in der ZIP-Datei enthaltenen Ordner data umgehst, lernst du ebenfalls im oben verlinkten Tutorial.

Die benötigten Bibliotheken

Für den Sketch benötigst du eine Reihe von Bibliotheken:

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
#include "LittleFS.h"
#include <Arduino_JSON.h>

Die ersten beiden sollten bei dir schon vorinstalliert sein. Die drei Bibliotheken ESPAsyncTCP, ESPAsyncWebServer und Arduino_JSON findest du wie gewohnt in Bibliotheksmanager. Achte bei letzterer darauf, die Version von Arduino zu laden. Die ähnlich geschriebene Bibliothek ArduinoJson von Benoit Blanchon wäre für dieses Projekt die falsche.

Die JavaScript-Datei

Mit Hilfe von JavaScript erstellst du das Diagramm, auf dem der Feuchtigkeitswert angezeigt wird. Zum Einsatz kommt hierbei eine vorgefertigte Bibliothek, die alles beinhaltet, was du für dieses Projekt benötigst.

Öffne die Datei in einem Texteditor deiner Wahl. Wie du siehst, kannst du darin allerhand einstellen und an deine Vorlieben anpassen. Nähere Informationen findest du in der Dokumentation der Bibliothek. Zwei Stellen sind allerdings besonders wichtig und hängen von deinem Feuchtigkeitssensor und der Pflanze, die du gießen möchtest, ab.

Dein Sensor überträgt Messwerte in einem Bereich, den du vorab kurz ermitteln musst. Der Maximalwert ist 1024, der ausgegeben wird, wenn der Sensor nicht in der Erde steckt. Das ist sozusagen also der Wert für absolute Trockenheit. Den Minimalwert kannst du ermitteln, wenn du ihn längere Zeit in die feuchte Erde deiner Pflanze oder auch in ein Glas Wasser steckst. Sobald du die Pflanzenbewässerung aufgebaut und die Dateien sowie den Sketch übertragen hast, gibt dein ESP8266 diesen Wert im Seriellen Monitor aus. Bei mir sinkt der Wert kontinuierlich bis auf den Wert 680.

In der Datei script.js findest du zunächst die folgende Stelle. Dort kannst du den Minimal- und Maximalwert eintragen:

  minValue: 680,
  maxValue: 1024,

Außerdem kannst du ein Stück weiter unten noch die Skalenwerte festlegen, die auf dem Diagramm sichtbar sein sollen:

  majorTicks: [
      "680",
      "800",
      "900",
      "1024"
  ],

Und noch eine dritte Stelle ist interessant. Dort kannst du die Feuchtigkeitswerte innerhalb bestimmter Bereiche farblich kennzeichnen:

highlights: [
     {
      "from": 680,
      "to": 700,
      "color": "#346eeb"
     },  
     {
          "from": 700,
          "to": 800,
          "color": "#03C0C1"
      },
      {
        "from": 800,
        "to": 900,
        "color": "#ebd534"
      },
      {
        "from": 900,
        "to": 1024,
        "color": "#eb5834"
      }
  ],

Im obigen Beispiel sind das die Wert von 700 – 800, die grün eingefärbt sind, um zu signalisieren, dass hier die Erde eine optimale Feuchtigkeit hat. Welche Werte das bei dir sind, kannst du folgendermaßen leicht herausfinden:

Sobald du die Pflanzenbewässerung aufgebaut und die Dateien sowie den Sketch übertragen hast, gibt dein ESP8266 den aktuell gemessenen Feuchtigkeitswert im Seriellen Monitor aus. Stecke nun den Sensor in Erde, die so trocken ist, dass du sie jetzt bewässern würdest. Im Seriellen Monitor siehst du nun ersten Wert.

Gieße jetzt die Pflanze, bis sie feucht genug ist – im Seriellen Monitor siehst du nun deinen zweiten Wert. Trage diese Wert im JavaScript-Code ein, dieser Bereich wird dann grün markiert. Apropos grün: über den Hexadezimelwert hinter color kannst du selbst eine Farbe auswählen.

So könnte dann das Diagramm beispielsweise aussehen:

Die HTML-Datei

Das HTML für deine Webseite ist recht überschaubar:

<!DOCTYPE html>
<html>
  <head>
    <title>ESP8266 Pflanzenbewässerung</title>
    <meta name="viewport" content="width=device-width, initial-scale=1">
    <meta charset="utf-8">
    <link rel="icon" type="image/png" href="favicon.png">
    <link rel="stylesheet" href="https://use.fontawesome.com/releases/v5.7.2/css/all.css" integrity="sha384-fnmOCqbTlWIlj8LyTjo7mOUStjsKC4pOpQbqyi7RrhN7udi9RwhKkMHpvLbHG9Sr" crossorigin="anonymous">
    <link rel="stylesheet" type="text/css" href="style.css">
    <script src="http://cdn.rawgit.com/Mikhus/canvas-gauges/gh-pages/download/2.1.7/all/gauge.min.js"></script>
  </head>
  <body>
    <div class="topnav">
      <h1>ESP8266 Pflanzenbewässerung</h1>
    </div>
    <div class="content">
      <div class="card-grid">
        <div class="card">
          <p class="card-title">Feuchtigkeit</p>
          <canvas id="gauge-humidity"></canvas>
        </div>
      </div>
    </div>
    <script src="script.js"></script>
  </body>
</html>

Darin findest du den Seitentitle title sowie die Überschrift h1 und den card-title, die du nach Belieben benennen kannst. Außerdem werden noch via CDN (Content Delivery Network) ein externes CSS sowie ein Script für das Diagramm geladen. Wenn du nichts anpassen möchtest, kannst du diese Datei so lassen wie sie ist – das gilt auch für die CSS-Datei im Ordner data, auf die ich hier nicht eigens eingehe.

Wichtige Anpassungen im Sketch

Nun zum Kernstück des Projekts. Hier musst du ein paar wichtige Anpassungen vornehmen, damit deine Pflanzenbewässerung wie gewünscht funktioniert. Hinterlege zunächst deine WLAN-Daten:

const char* ssid = "DEIN NETZWERK";
const char* password = "DEIN PASSWORT";

Weiter geht es mit einer Variablen. Diese gibt den Intervall vor, in dem die Webseite (und damit die Messdaten des Feuchtigkeitssensors) aktualisiert werden sollen. Voreingestellt sind hier 30 Sekunden, du kannst diese Zeitspanne jedoch beliebig verlängern und verkürzen.

unsigned long timerDelay = 30000;

Zuletzt der Schwellenwert, bei dessen Erreichen die Wasserpumpe in Aktion treten soll. Du findest diese Angabe recht weit unten im Sketch im Loop:

if (humidity > 900) {
  Serial.println("Starte Pumpe.");
  digitalWrite(pumpPin, HIGH);
  delay(1000);
  digitalWrite(pumpPin, LOW);
}
else {
  digitalWrite(pumpPin, LOW);
}

Setzt dort für die voreingestellten 900 den Wert ein, den du in der trockenen Erde ermittelt hast. Wenn der Messwert darüber liegt, springt die Pumpe an. Ein Hinweis: In diesem Projekt gehe ich davon aus, dass die Werte mit der Trockenheit der Erde steigen. Falls das bei dir genau andersherum ist, passe die If-Abfrage mit dem Zeichen < und deinem Schwellenwert entsprechend an.

Falls die Erde nun also zu trocken ist, wird der Pin pumpPin auf HIGH gestellt und damit die Wasserpumpe eingeschaltet. Diese läuft dann für eine Sekunde (auch ein Wert, den du an deine Bedürfnisse anpassen solltest) und wird danach wieder ausgeschaltet.

Während des Pumpvorgangs läuft der Intervall von 30 Sekunden weiter. Das bedeutet, dass nach knapp 30 Sekunden wieder die Feuchtigkeit geprüft, auf der Webseite aktualisiert und bei Bedarf die Pumpe angeschaltet wird. Liegt bei einer Prüfung dann der Wert im zulässigen Bereich, bleibt die Pumpe aus.

Und das war es auch schon. Mit den richtigen Anpassungen sollte deine Pflanzenbewässerung nun automatisch deine Lieblingspflanze bewässern während du z.B. auf dem Smartphone die Feuchtigkeit der Erde überwachst. 🙂

Wie geht es weiter?

Natürlich gibt es noch einige Verbesserungen, die deiner Bewässerungsanlage hinzufügen könntest. Wie wäre z.B. mit einer WhatsApp-Nachricht, die dein ESP8266 schickt, wenn die Erde zu trocken ist? Eine andere Idee könnte auch ein Button auf der Webseite sein, der den Gießvorgang manuell startet.

Sicherlich fallen dir noch weitere Optimierungen ein – viel Erfolg dabei!

]]>
Dateien auf dem ESP8266 speichern mit LittleFS https://polluxlabs.net/esp8266-projekte/dateien-auf-dem-esp8266-speichern-mit-littlefs/ Wed, 17 Jan 2024 16:11:10 +0000 https://polluxlabs.net/?p=15632 Dateien auf dem ESP8266 speichern mit LittleFS Weiterlesen »

]]>
Für einige Projekte ist es praktisch, Dateien auf einem ESP8266 zu speichern – z.B. weil du Sensordaten sichern möchtest, oder auch die HTML-, CSS- und JavaScript-Dateien eines Webservers sauber ablegen möchtest. Hier kommt das Tool LittleFS ins Spiel, mit dem du das problemlos über die Arduino IDE erledigen kannst.

das Tool herunterladen und installieren

Ein Hinweis vorab: Aktuell (Jan. 2024) funktioniert LittleFS nicht mit der Arduino IDE ab Version 2.0 – für dieses Tutorial habe ich deshalb die Version 1.8.19 verwendet. Diese kannst du nach wie vor hier im Bereich Legacy IDE herunterladen.

Du findest die aktuelle Version von LittleFS auf GitHub. Aktuell ist das die Version ESP8266LittleFS-2.6.0.zip, die du mit einem Klick auf den Dateinamen herunterladen kannst.

Steuere nun den Ordner deines Sketchbooks an. Das ist der Ort, in dem all deine mit der Arduino IDE erstellten Sketches wiederum in eigenen Ordnern gespeichert werden. Falls du dir nicht sicher bist, findest du den Pfad zum Ordner in den Einstellungen der Arduino IDE:

Erstelle in deinem Sketchbook-Ordner einen neuen Ordner mit dem Namen tools und entpacke dort die LittleFS ZIP-Datei, die du gerade heruntergeladen hast. In deinem Ordner tools sollte nun der entpackte Ordner ESP8266LittleFS zu finden sein.

___STEADY_PAYWALL___

Wenn du fertig bist, starte die Arduino IDE neu. Öffne nun das Menü Werkzeuge – dort siehst du nun den Eintrag ESP8266 LittleFS Data Upload.

Dateien auf den ESP8266 hochladen

Jetzt, wo alles eingerichtet ist, kann es losgehen. Erstelle einen neuen Sketch und öffne den dazugehörigen Ordner – z.B. über den Menüpunkt Sketch > Sketch-Ordner anzeigen. Erstelle in diesem Ordner nun einen weiteren Ordner namens data.

Alle Dateien, die du später in diesem Ordner ablegst, werden mit dem gerade installierten Tool auf den ESP8266 geladen. Erstelle nun testweise eine einfache HTML-Datei mit folgendem Inhalt:

Wenn du das hier liest, funktioniert LittleFS. :)

Speichere diese Datei nun im Ordner data mit dem Namen test.txt ab. Später wirst du diese Datei in deinem Seriellen Monitor auslesen. Doch zunächst der Upload:

Wähle zunächst (falls noch nicht geschehen) im Menü Werkzeuge deinen ESP8266 aus. Anschließend kannst du im selben Menü unter Flash size die benötigte Größe für den Speicher einstellen. Für den folgenden Test musst du hier jedoch nichts umstellen.

Wähle anschließend den Menüpunkt ESP8266 LittleFS Data Upload. Nun wird die HTML-Datei im Ordner data übertragen – was nach wenigen Sekunden erfolgreich abgeschlossen sein sollte:

Die TXT-Datei anzeigen

Ob der Upload wirklich funktioniert hat, lässt sich natürlich am besten überprüfen, indem du nachschaust, ob du den Inhalt von test.txt auslesen kannst.

Füge hierfür den folgenden Code in deinen Sketch ein:

#include "LittleFS.h"
 
void setup() {
  Serial.begin(115200);
  
  if(!LittleFS.begin()){
    Serial.println("An Error has occurred while mounting LittleFS");
    return;
  }
  
  File file = LittleFS.open("/test.txt", "r");
  if(!file){
    Serial.println("Failed to open file for reading");
    return;
  }
  
  Serial.println("File Content:");
  while(file.available()){
    Serial.write(file.read());
  }
  file.close();
}
 
void loop() {

}

Lade nun den Sketch auf deinen ESP8266 und öffne den Seriellen Monitor. Um die Datei aufzurufen, drücke kurz den Reset-Button RST – nun sollte der Inhalt von test.txt in Seriellen Monitor erscheinen:

In diesem Tutorial hast du die Grundlagen von LittleFS gelernt. Du weißt nun, wo du die Dateien im Sketch-Ordner ablegen musst und wie du diese auf deinen ESP8266 hochlädst.

]]>
Nachrichten mit dem ESP8266 und ESP32 versenden https://polluxlabs.net/arduino-tutorials/nachrichten-mit-dem-esp8266-und-esp32-versenden/ Mon, 04 Sep 2023 14:15:55 +0000 https://polluxlabs.net/?p=14335 Nachrichten mit dem ESP8266 und ESP32 versenden Weiterlesen »

]]>
Möchtest du mit deinem ESP8266 oder ESP32 Nachrichten verschicken, um zum Beispiel eine Warnung von einem Bewegungsmelder oder Temperatursensor zu erhalten? In diesem Tutorial erfährst du gleich drei Möglichkeiten, wie du das umsetzen kannst – per Telegram, E-Mail und WhatsApp.

Inhalt diese Tutorials

Nachrichten per Telegram senden

Eine gängige Möglichkeit ist es, Nachrichten per Telegram zu senden – genauer gesagt an einen Telegram-Bot. Diese Nachrichten kannst du dann umgehend auf deinem Smartphone lesen. Auf Pollux Labs gibt es einige Projekte, die auf Telegram zurückgreifen, zum Beispiel einen Dash Button oder eine Fotofalle mit der ESP32-CAM. Für letzteres Projekt ist Telegram besonders interessant, denn es ist damit auch möglich, Bilder zu senden.

Zunächst benötigst du einen Telegram-Bot. Wie du diesen im Handumdrehen einrichtest, erfährst du in diesem Tutorial. Außerdem benötigst du die Bibliothek UniversalTelegramBot, die du im Bibliotheksverwalter der Arduino IDE findest. Achte darauf, die neueste Version zu installieren und die Bibliothek aktuell zu halten. Sollte die Version im Bibliotheksverwalter veraltet sein, findest du auf GitHub immer die neueste Version zum Download.

Hier der Beispiel-Sketch für deinen ESP8266. Dieser versendet nach dem Start des Boards eine Nachricht:

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

// Deine WLAN-Zugangsdaten
const char* ssid = "DEIN WLAN-NETZWERK";
const char* password = "DEIN PASSWORT";

// Dein Bot-Token
#define botToken "DEIN TOKEN"  // den Bot-Token bekommst du vom Botfather)

//Deine User ID
#define userID "DEINE USER ID"

WiFiClientSecure client;
UniversalTelegramBot bot(botToken, client);

void setup() {
  Serial.begin(115200);
  client.setInsecure();

  // Verbindung zum WLAN
  Serial.print("Verbinde mit mit: ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("Verbunden!");

  bot.sendMessage(userID, "Hier spricht dein ESP8266.", "");
}

void loop() {
}

Nach dem Upload sollte in deiner Telegram-App folgende Nachricht erscheinen:

Telegram-Nachricht vom ESP8266

So funktioniert der Sketch

Nachdem du die benötigten Bibliotheken eingebunden hast (die zwei ersten sind bereits vorinstalliert), musst du ein paar Daten ergänzen. Das sind deine WLAN-Zugangsdaten sowie dein Bot-Token und deine User-ID. Wenn du die beiden letzteren noch nicht hast, schau dir zunächst unser oben verlinktes Tutorial an.

Anschließend initialisierst du den WifiClient sowie den UniversalTelegramBot mit jeweiligen Instanzen:

WiFiClientSecure client;
UniversalTelegramBot bot(botToken, client);

Im Setup stellst du dann die Verbindung zu deinem WLAN her. Sobald die Verbindung steht, verwendest du die Funktion bot.sendMessage, um eine Nachricht an deinen Telegram-Bot zu senden:

bot.sendMessage(userID, "Hier spricht dein ESP8266.", "");

Der erste Parameter in dieser Funktion ist deine userID, die du zu Beginn des Sketchs hinterlegt hast – gefolgt von der Nachricht, die du senden möchtest. Und das war es im Prinzip auch schon! Du kannst dieses Muster nun für dein Projekt adaptieren, indem du die Nachricht zum Beispiel sendest, wenn eine bestimmte Temperatur überschritten wurde – als Inhalt der Nachricht könnte dann z.B. der aktuelle Messwert dienen.

Mit dem ESP32 eine Telegram-Nachricht senden

Natürlich kannst du statt des ESP8266 auch mit einem ESP32 oder einer ESP32-CAM Nachrichten per Telegram senden. Hierfür musst du nur eine Bibliothek austauschen. Statt ESP8266WiFI.h verwendest du WiFi.h.

#include <WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

Und: Um eine korrekte Nachricht zu senden, kannst du noch den Inhalt anpassen. 😉

bot.sendMessage(userID, "Hier spricht dein ESP32.", "");

E-Mails mit dem ESP8266 oder ESP32 versenden

Nach Telegram schauen wir uns den Klassiker der elektronischen Nachrichten an, E-Mails. In diesem Tutorial verwenden wir den Service Gmail, um die E-Mails zu versenden. Auch wenn du schon eine Adresse bei Gmail haben solltest, empfehlen wir fürs Experimentieren auf jeden Fall eine brandneue Mail-Adresse anzulegen. Sollte etwas schief laufen, z.B. eine Kontosperrung, weil dein ESP8266 versehentlich zahllose Mails in kurzer Abfolge versendet, ist deine private Mail-Adresse hiervon nicht betroffen.

___STEADY_PAYWALL___

Um eine neue Adresse anzulegen, rufe zunächst hier Gmail auf und klicke auf Konto erstellen. Sobald dein Konto eingerichtet ist, benötigst du ein App-Passwort, das dein ESP8266 verwenden kann. Um ein App-Passwort anzulegen, öffne dein Google-Konto und klicke auf den Menüpunkt Sicherheit. Klicke anschließend auf den Menü-Punkt Bestätigung in zwei Schritten und folge den Anweisungen, um diese Zwei-Faktor-Authentifizierung zu aktivieren – sie ist nämlich die Voraussetzung für ein App-Passwort.

Sobald du mit der Einrichtung fertig bist, öffne wieder Sicherheit > Bestätigung in zwei Schritten und scrolle ganz nach unten zum Eintrag App-Passwörter. Erstelle nun ein Passwort für E-Mail und wähle als Gerät Andere (benutzerdefinierter Name) aus. Anschließend kannst du einen Namen vergeben, also z.B. ESP8266 oder ESP32.

Das war es zunächst mit den Vorbereitungen, weiter geht es mit einem Beispielsketch, der eine E-Mail an dich versendet.

Eine E-Mail senden

Zunächst benötigst du eine Bibliothek, die du über den Bibliotheksverwalter installieren kannst: ESP Mail Client

Nach der Installation kannst du dich gleich dem Sketch zuwenden. Wir verwenden in diesem Tutorial den Sketch des Blogs RandomNerdTutorials, der ein sehr guter Startpunkt für dieses Thema ist. Im folgenden Sketch musst du nur ein paar Anpassungen machen. Trage an den folgenden Stellen deine Daten ein:

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID" //Dein WLAN-Name
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD" //Dein WLAN-Passwort
#define AUTHOR_EMAIL "YOUR_EMAIL@XXXX.com" //Deine Absendeadresse (die du bei Gmail angelegt hast)
#define AUTHOR_PASSWORD "YOUR_EMAIL_APP_PASS" //Dein App-Passwort
#define RECIPIENT_EMAIL "RECIPIENTE_EMAIL@XXXX.com" //Die Empfänger-Adresse

Der gesamte Sketch:

/*
  Rui Santos
  Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files.
  The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
  Example adapted from: https://github.com/mobizt/ESP-Mail-Client
*/

#include <Arduino.h>
#if defined(ESP32)
  #include <WiFi.h>
#elif defined(ESP8266)
  #include <ESP8266WiFi.h>
#endif
#include <ESP_Mail_Client.h>

#define WIFI_SSID "REPLACE_WITH_YOUR_SSID"
#define WIFI_PASSWORD "REPLACE_WITH_YOUR_PASSWORD"

/** The smtp host name e.g. smtp.gmail.com for GMail or smtp.office365.com for Outlook or smtp.mail.yahoo.com */
#define SMTP_HOST "smtp.gmail.com"
#define SMTP_PORT 465

/* The sign in credentials */
#define AUTHOR_EMAIL "YOUR_EMAIL@XXXX.com"
#define AUTHOR_PASSWORD "YOUR_EMAIL_APP_PASS"

/* Recipient's email*/
#define RECIPIENT_EMAIL "RECIPIENTE_EMAIL@XXXX.com"

/* Declare the global used SMTPSession object for SMTP transport */
SMTPSession smtp;

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status);

void setup(){
  Serial.begin(115200);
  Serial.println();
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED){
    Serial.print(".");
    delay(300);
  }
  Serial.println();
  Serial.print("Connected with IP: ");
  Serial.println(WiFi.localIP());
  Serial.println();

  /*  Set the network reconnection option */
  MailClient.networkReconnect(true);

  /** Enable the debug via Serial port
   * 0 for no debugging
   * 1 for basic level debugging
   *
   * Debug port can be changed via ESP_MAIL_DEFAULT_DEBUG_PORT in ESP_Mail_FS.h
   */
  smtp.debug(1);

  /* Set the callback function to get the sending results */
  smtp.callback(smtpCallback);

  /* Declare the Session_Config for user defined session credentials */
  Session_Config config;

  /* Set the session config */
  config.server.host_name = SMTP_HOST;
  config.server.port = SMTP_PORT;
  config.login.email = AUTHOR_EMAIL;
  config.login.password = AUTHOR_PASSWORD;
  config.login.user_domain = "";

  /*
  Set the NTP config time
  For times east of the Prime Meridian use 0-12
  For times west of the Prime Meridian add 12 to the offset.
  Ex. American/Denver GMT would be -6. 6 + 12 = 18
  See https://en.wikipedia.org/wiki/Time_zone for a list of the GMT/UTC timezone offsets
  
  config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
  config.time.gmt_offset = 1;
  config.time.day_light_offset = 0;
  */

  /* Declare the message class */
  SMTP_Message message;

  /* Set the message headers */
  message.sender.name = F("ESP");
  message.sender.email = AUTHOR_EMAIL;
  message.subject = F("ESP Test Email");
  message.addRecipient(F("Sara"), RECIPIENT_EMAIL);
    
  /*Send HTML message*/
  /*String htmlMsg = "<div style=\"color:#2f4468;\"><h1>Hello World!</h1><p>- Sent from ESP board</p></div>";
  message.html.content = htmlMsg.c_str();
  message.html.content = htmlMsg.c_str();
  message.text.charSet = "us-ascii";
  message.html.transfer_encoding = Content_Transfer_Encoding::enc_7bit;*/

   
  //Send raw text message
  String textMsg = "Hallo Mensch!";
  message.text.content = textMsg.c_str();
  message.text.charSet = "us-ascii";
  message.text.transfer_encoding = Content_Transfer_Encoding::enc_7bit;
  
  message.priority = esp_mail_smtp_priority::esp_mail_smtp_priority_low;
  message.response.notify = esp_mail_smtp_notify_success | esp_mail_smtp_notify_failure | esp_mail_smtp_notify_delay;


  /* Connect to the server */
  if (!smtp.connect(&config)){
    ESP_MAIL_PRINTF("Connection error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());
    return;
  }

  if (!smtp.isLoggedIn()){
    Serial.println("\nNot yet logged in.");
  }
  else{
    if (smtp.isAuthenticated())
      Serial.println("\nSuccessfully logged in.");
    else
      Serial.println("\nConnected with no Auth.");
  }

  /* Start sending Email and close the session */
  if (!MailClient.sendMail(&smtp, &message))
    ESP_MAIL_PRINTF("Error, Status Code: %d, Error Code: %d, Reason: %s", smtp.statusCode(), smtp.errorCode(), smtp.errorReason().c_str());

}

void loop(){
}

/* Callback function to get the Email sending status */
void smtpCallback(SMTP_Status status){
  /* Print the current status */
  Serial.println(status.info());

  /* Print the sending result */
  if (status.success()){
    // ESP_MAIL_PRINTF used in the examples is for format printing via debug Serial port
    // that works for all supported Arduino platform SDKs e.g. AVR, SAMD, ESP32 and ESP8266.
    // In ESP8266 and ESP32, you can use Serial.printf directly.

    Serial.println("----------------");
    ESP_MAIL_PRINTF("Message sent success: %d\n", status.completedCount());
    ESP_MAIL_PRINTF("Message sent failed: %d\n", status.failedCount());
    Serial.println("----------------\n");

    for (size_t i = 0; i < smtp.sendingResult.size(); i++)
    {
      /* Get the result item */
      SMTP_Result result = smtp.sendingResult.getItem(i);

      // In case, ESP32, ESP8266 and SAMD device, the timestamp get from result.timestamp should be valid if
      // your device time was synched with NTP server.
      // Other devices may show invalid timestamp as the device time was not set i.e. it will show Jan 1, 1970.
      // You can call smtp.setSystemTime(xxx) to set device time manually. Where xxx is timestamp (seconds since Jan 1, 1970)
      
      ESP_MAIL_PRINTF("Message No: %d\n", i + 1);
      ESP_MAIL_PRINTF("Status: %s\n", result.completed ? "success" : "failed");
      ESP_MAIL_PRINTF("Date/Time: %s\n", MailClient.Time.getDateTimeString(result.timestamp, "%B %d, %Y %H:%M:%S").c_str());
      ESP_MAIL_PRINTF("Recipient: %s\n", result.recipients.c_str());
      ESP_MAIL_PRINTF("Subject: %s\n", result.subject.c_str());
    }
    Serial.println("----------------\n");

    // You need to clear sending result as the memory usage will grow up.
    smtp.sendingResult.clear();
  }
}

So funktioniert der sketch

Weiter oben hast du bereits die Stellen kennengelernt, die du anpassen musst, damit der Sketch funktioniert. Außerdem kannst du noch deine Zeitzone einstellen, um der E-Mail den richtigen Timestamp zu geben:

  config.time.ntp_server = F("pool.ntp.org,time.nist.gov");
  config.time.gmt_offset = 1;
  config.time.day_light_offset = 0;

Der gmt_offset für Deutschland (also der Abstand zur Greenwich Mean Time) wäre in diesem Beispiel 1 – in der Winterzeit. Im Sommer sind es hingegen 2 Stunden.

Den Betreff und den Absender- bzw. Empfängernamen trägst du hier ein:

  /* Set the message headers */
  message.sender.name = F("ABSENDERNAME");
  message.sender.email = AUTHOR_EMAIL;
  message.subject = F("BETREFF");
  message.addRecipient(F("EMPFÄNGERNAME"), RECIPIENT_EMAIL);

Die eigentliche Nachricht findest du hier:

  //Send raw text message
  String textMsg = "Hallo Mensch!";

Hier kannst du, je nachdem was in deinem eigenen Projekt sinnvoll ist, natürlich auch Variablen mitsenden. Lade den Sketch mit deinen Anpassungen auf deinen ESP8266 oder ESP32. Im Seriellen Monitor kannst du mitverfolgen, wie die E-Mail versendet wird und schließlich im Posteingang deines Empfängers landet.

Der obige Sketch funktioniert sowohl für den ESP8266 als auch für den ESP32. Anpassungen sind beim Wechsel der Boards nicht nötig.

Eine WhatsApp-Nachricht mit dem ESP8266 und ESP32 versenden

Kommen wir zu dritten Möglichkeit, deinen ESP8266 oder ESP32 eine Nachricht versenden zu lassen: WhatsApp. Voraussetzung ist hier ein externer Service. Im Folgenden verwenden wir CallMeBot.com – eine kostenlose API, mit deren Hilfe du WhatsApp-Textnachrichten auf dein Smartphone senden kannst.

Hierfür ist keine aufwändige Registrierung nötig, du musst nur kurz deine Mobilfunknummer bei der API anmelden, um einen API-Key zu erhalten. Über den Link oben kannst du die offizielle Anleitung aufrufen – oder einfach die folgenden Schritte ausführen:

  • Füge über WhatsApp die folgende Nummer deinen Kontakten hinzu (den Kontaktnamen kannst du frei wählen): +34 644 71 81 99
  • Sende anschließend die folgende Nachricht an diese Nummer: I allow callmebot to send me messages
  • Du erhältst daraufhin eine Antwort mit deinem API-Key – und das war’s auch schon

Die Bibliothek zum Codieren der Nachrichten

Auch um Nachrichten per WhatsApp senden zu können, benötigst du eine Bibliothek, die du ganz schnell über den Bibliotheksverwalter installieren kannst: UrlEncode

Diese brauchst du, da die Nachrichten über eine URL übertragen werden – z.B. so:

https://api.callmebot.com/whatsapp.php?phone=+49123123123&text=Dieser+Text+ist+codiert&apikey=123123

Die Bibliothek, die du gleich installierst, übernimmt die Aufgabe, deinen Nachrichten-String in das richtige Format zu bringen. Öffne also den Bibliotheksverwalter und suche nach UrlEncode. Installiere anschließend die neueste Version.

die WhatsApp-Nachricht senden

Hier kommt der vollständige Sketch, um eine WhatsApp-Nachricht mit deinem ESP8266 zu verschicken:

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h>
#include <UrlEncode.h>

const char* ssid = "DEIN WLAN-NETZ";
const char* password = "DEIN WLAN-PASSWORT";

// Deutschland +49, Beispiel: +49176999888777
String phoneNumber = "DEINE MOBILFUNKNUMMER";
String apiKey = "DEIN API-KEY";

void sendMessage(String message) {

  // Daten, die gesendet werden
  String url = "http://api.callmebot.com/whatsapp.php?phone=" + phoneNumber + "&apikey=" + apiKey + "&text=" + urlEncode(message);
  WiFiClient client;
  HTTPClient http;
  http.begin(client, url);

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

  // HTTP Post request senden
  int httpResponseCode = http.POST(url);
  if (httpResponseCode == 200) {
    Serial.print("Message sent successfully");
  } else {
    Serial.println("Error sending the message");
    Serial.print("HTTP response code: ");
    Serial.println(httpResponseCode);
  }

  http.end();
}

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

  WiFi.begin(ssid, password);
  Serial.println("Connecting");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("");
  Serial.print("Connected to WiFi network with IP Address: ");
  Serial.println(WiFi.localIP());

  // WhatsApp-Nachricht
  sendMessage("Hier spricht dein ESP8266");
}

void loop() {
}

Zu Beginn des Sketchs hinterlegst du wieder deine WLAN-Zugangsdaten. Außerdem benötigst du deine eigene Mobilfunknummer, die du im internationalen Format (also z.B. für Deutschland mit einem +49 zu Beginn) hinterlegen musst. Zuletzt trägst du noch deinen API-Key ein, den du per WhatsApp-Nachricht empfangen hast:

const char* ssid = "DEIN WLAN-NETZ";
const char* password = "DEIN WLAN-PASSWORT";

// Deutschland +49, Beispiel: +49176999888777
String phoneNumber = "DEINE MOBILFUNKNUMMER";
String apiKey = "DEIN API-KEY";

Alles weitere im Sketch dient der Verbindung zu deinem WLAN und dem API-Request (in der Funktion sendMessage(String message)). Recht weit am Ende kannst du deine Textnachricht eingeben, die gesendet werden soll:

// WhatsApp-Nachricht
sendMessage("Hier spricht dein ESP8266");

Lade den Sketch auf deinen ESP8266. Nach dem Upload sollte innerhalb von wenigen Sekunden die entsprechende Nachricht auf deinem Smartphone erscheinen.

Die WhatsApp-Nachricht mit dem ESP32 senden

Wenn du statt eines ESP8266 einen ESP32 oder eine ESP32-CAM verwenden möchtest, musst du nur ein paar andere Bibliotheken zu Beginn des Sketchs einbinden:

#include <WiFi.h>
#include <HTTPClient.h>
#include <UrlEncode.h>

Den restlichen Sketch kannst du beibehalten ohne weitere Anpassungen. Beachte bitte, dass du mit CallMeBot nur reine Textnachrichten (die natürlich auch Variablen enthalten können) senden kannst. Bilder zu senden, funktioniert mit diesem Service leider nicht. Solltest du das vorhaben, verwende besser Telegram oder schaue dir einmal textmebot.com an – diese API ist allerdings kostenpflichtig.

Fazit

In diesem Tutorial hast du drei Methoden kennengelernt, mit denen du Nachrichten versenden kannst – per Telegram, E-Mail oder WhatsApp. Passende Projekte findest du auf Pollux Labs: Du könntest zum Beispiel die ESP8266 Wetterstation um Warnungen ergänzen, die du erhältst, sobald bestimmte Messwerte über- oder unterschritten werden.

]]>
ESP8266 Wetterstation mit Datenaufzeichnung und -visualisierung https://polluxlabs.net/esp8266-projekte/esp8266-wetterstation-mit-datenaufzeichnung/ https://polluxlabs.net/esp8266-projekte/esp8266-wetterstation-mit-datenaufzeichnung/#respond Mon, 07 Aug 2023 12:54:39 +0000 https://polluxlabs.net/?p=13977 ESP8266 Wetterstation mit Datenaufzeichnung und -visualisierung Weiterlesen »

]]>
Baue eine ESP8266 Wetterstation, die dir die aktuelle Temperatur, Luftfeuchtigkeit und den Luftdruck anzeigt sowie deine Daten speichert und visualisiert. Die aktuellen Messdaten erscheinen auf einem kleinen OLED-Display. Aber das ist nicht alles: Deine Messdaten speicherst du in einer Datenbank, um auf vergangene Messungen zugreifen und sie auswerten zu können.

Um deine Messdaten zu speichern, verwendest du die Datenbank InfluxDB, die sicher hervorragend dazu eignet, zeitgebundene Daten zu speichern und nebenbei auch noch die Visualisierung deiner Daten einfach und intuitiv ermöglicht. InfluxDB wird lokal auf einem Raspberry Pi laufen. Der ESP8266 sendet die Messdaten dorthin und InfluxDB speichert und visualisiert sie. Anzeigen lassen kannst du diese dir dann in einem Browser und auf einem Gerät deiner Wahl.

Die Software, die du für die ESP8266 Wetterstation benötigst, ist kostenlos verfügbar.

Inhalte dieses Projekts:

Diese Bauteile benötigst du für die ESP8266 Wetterstation:

Den DHT22 AM ESP8266 anschließen und verwenden

Der Temperatursensor DHT22 misst neben der Temperatur auch die Luftfeuchtigkeit. Um ihn an deinem ESP8266 anzuschließen, orientiere dich an der folgenden Skizze. Achte bitte auf den 10 kΩ Widerstand, den du zwischen dem Anschluss des DHT22 am Pin D4 des ESP8266 und Plus einsetzen musst.

Temperatursensor DHT22 am ESP8266

Übrigens: Falls du deinen ESP8266 noch nicht in der Arduino IDE verfügbar gemacht hast, findest du hier bei uns ein passendes Tutorial.

DIE PASSENDEN BIBLIOTHEKEN

Um deinen Sensor verwenden zu können, musst du zwei Bibliotheken installieren, von denen du jedoch nur eine im Sketch einbinden musst. Öffne deinen Bibliotheksmanager. Suche dort zunächst nach Adafruit Unified Sensor und installiere die aktuelle Version. Die Versionsnummern in den folgenden Screenshots können abweichen.

Arduino Bibliothek Adafruit Unified Sensor

Suche anschließend nach DHT sensor library und installiere die entsprechende Bibliothek.

Arduino Bibliothek DHT Sensor Library

DIE TEMPERATUR und Luftfeuchtigkeit MESSEN

Kopiere dir den folgenden Sketch und lade ihn auf deinen Arduino hoch:

#include "DHT.h"

#define DHTPIN D4
#define DHTTYPE DHT22

float tempDHT22;
float humidity;

DHT dht(DHTPIN, DHTTYPE);

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

void loop() {

  tempDHT22 = dht.readTemperature();
  humidity = dht.readHumidity();

  Serial.print("Temperatur: ");
  Serial.print(tempDHT22);
  Serial.println("*C");
  
  Serial.print("Luftfeuchtigkeit: ");
  Serial.print(humidity);
  Serial.println("%");
  
  Serial.println();
  delay(2000);
}

So funktioniert der Sketch: Nachdem du die Bibliothek eingebunden hast, legst du den Pin fest, an dem der Sensor angeschlossen ist. In unserem Sketch ist das der Pin D4.

In der nächsten Zeile legst du das Modell des Sensors fest – in unserem Fall also ein DHT22. Anschließend erstellst du ein Objekt der Bibliothek names dht, das später bei der Messung mit den Funktionen dht.readTemperature() und dht.readHumidity() zum Einsatz kommt.

Der Rest des Sketchs dürfte für dich kein Problem sein. Achte jedoch darauf, dass die Baudrate von Sketch und Seriellem Monitor übereinstimmt. Hinweis: Es kann auch sein, dass dein DHT22 auch ohne Widerstand funktioniert – oder auch nur ohne Widerstand.

Wenn du doch lieber den Sensor DHT11 verwenden möchtest, musst du nur eine Stelle im Sketch anpassen:

#define DHTTYPE DHT11

Wie du den “kleinen Bruder” des DHT22 – also den DHT11 – anschließt, erfährst du in der folgenden Skizze. Im weiteren Verlauf des Projekts verwenden wir jedoch weiterhin den DHT22.

Temperatursensor DHT11 am ESP8266

DEN BMP180 am ESP8266 anschließen und verwenden

Neben der Luftfeuchtigkeit und der Temperatur soll die ESP8266 Wetterstation auch den aktuellen Luftdruck messen. Hierfür eignet sich der Sensor BMP180. Da dieser auch die Temperatur messen kann, schauen wir uns gleich auch noch die Messunterschiede zwischen DHT11 und BMP180 an. Doch zunächst zum Anschluss – orientiere dich hierbei an der folgenden Skizze:

Sensoren DHT22 und BMP180 am ESP8266

Die benötigte Bibliothek

Neben der bereits vorinstallierten Bibliothek Wire (für die Kommunikation per I²C), benötigst du noch eine weitere, um die Daten des Sensors problemlos auslesen zu können.

Öffne also den Bibliotheksmanager in der Arduino IDE und suche nach BMP180. Du findest nun eine Bibliothek namens Adafruit BMP085 Library – das ist die richtige, auch wenn sie ein anderes Modell im Namen trägt. Der BMP085 war das Vorgängermodell des BMP180, was die Kommunikation angeht, jedoch mehr oder weniger baugleich.

Adafruit BMP085 Bibliothek

Die Temperatur und den Luftdruck messen

Nun erweiterst du den obigen Sketch um den Code für den BMP180:

#include "DHT.h"
#include "Wire.h"
#include "Adafruit_BMP085.h"

#define DHTPIN D4
#define DHTTYPE DHT22

Adafruit_BMP085 bmp;

float tempDHT22;
float tempBMP180;
float humidity;
float pressure;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();

  if (!bmp.begin()) {
    Serial.println("Sensor BMP180 nicht gefunden!");
    while (1) {}
  }
}

void loop() {

  tempDHT22 = dht.readTemperature();
  tempBMP180 = bmp.readTemperature();
  humidity = dht.readHumidity();
  pressure = bmp.readPressure();

  Serial.print("Temperatur DHT22: ");
  Serial.print(tempDHT22);
  Serial.println("*C");

  Serial.print("Temperatur BMP180: ");
  Serial.print(tempBMP180);
  Serial.println("*C");

  Serial.print("Luftfeuchtigkeit DHT22: ");
  Serial.print(humidity);
  Serial.println("%");

  Serial.print("Luftdruck BMP180: ");
  Serial.print(pressure/100);
  Serial.println("hPa");

  Serial.println();
  delay(2000);
}

Sobald du den Sketch auf deinen ESP8266 geladen hast, sollten im seriellen Monitor die vier Messdaten erscheinen.

Ausgabe der Wetterdaten im seriellen Monitor

In den allermeisten Fällen dürfte die Temperaturmessung des DHT22 und des BMP180 etwas auseinander liegen. Ein Blick in die jeweiligen Datenblätter verrät, dass beide Sensoren eine Genauigkeit von ±0,5°C haben – das ist eigentlich schon recht genau und für eine Wetterstation sicherlich genau genug. Für welchen Messwert du dich entscheidest, liegt nun bei dir – vielleicht hast du noch ein weiteres Thermometer zur Hand, das du als Referenz einsetzen kannst.

Im weiteren Verlauf dieses Projekts verwenden wir die Temperaturdaten des BMP180.

Das OLED-Display anschließen

Aktuell siehst du deine Messdaten nur im seriellen Monitor. Deshalb kommt nun ein Display zum Einsatz, auf dem du sie bequemer ablesen kannst. In diesem Projekt verwenden wir das handelsübliche OLED-Display Adafruit SSD1306 mit einer Größe von 128×64 px.

Erweitere also den Aufbau auf deinem Breadboard wie folgt:

Die fertig aufgebaute ESP8266 Wetterstation

Wie du siehst, sind sowohl der BMP180 als auch das OLED-Display per I²C (also an den Pins D1 und D2) am ESP8266 angeschlossen. Damit der Microcontroller beide Bauteile ansprechen kann, besitzen sie unterschiedliche Adressen – das OLED-Display mit 128×64 px die Adresse 0x3C und der BMP180 die Adresse 0x77.

Die benötigten Bibliotheken

Nun ist deine ESP8266 Wetterstation vollständig. Allerdings fehlt noch der Sketch, mit dem du deine Messdaten auf dem OLED-Display anzeigst. Auch für das Display benötigst du die Unterstützung von Bibliotheken, die du im Handumdrehen installierst. Öffne also wieder den Bibliotheksmanager und suche zunächst nach Adafruit SSD1306 und installiere die neueste Version. Falls du gefragt wirst, ob du auch zugehörige Erweiterungen installieren möchtest, bestätige das mit einem Ja.

Die zweite Bibliothek findest du mit einer Suche nach Adafruit GFX Library. Falls diese schon im Zuge der ersten Installation mitinstalliert wurde, brauchst du nichts weiter zu tun und kannst den Bibliotheksmanager schließen.

___STEADY_PAYWALL___

Messdaten auf dem Display anzeigen

Ersetze den Code auf deinem ESP8266 durch den folgenden erweiterten Sketch:

#include "DHT.h"
#include "Wire.h"
#include "Adafruit_BMP085.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define DHTPIN D4
#define DHTTYPE DHT22

Adafruit_BMP085 bmp;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

float tempDHT22;
float tempBMP180;
float humidity;
float pressure;

DHT dht(DHTPIN, DHTTYPE);

void setup() {
  Serial.begin(115200);
  dht.begin();

  if (!bmp.begin()) {
    Serial.println("Sensor BMP180 nicht gefunden!");
    while (1) {}
  }

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Display-Addresse: 0x3C für Groesse 128x64px
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }
  display.setTextSize(1);       //Schriftgröße
  display.setTextColor(WHITE);  //Schriftfarbe


  display.clearDisplay();
  display.display();
}

void loop() {

  tempDHT22 = dht.readTemperature();
  tempBMP180 = bmp.readTemperature();
  humidity = dht.readHumidity();
  pressure = bmp.readPressure();

  Serial.print("Temperatur DHT22: ");
  Serial.print(tempDHT22);
  Serial.println("*C");

  Serial.print("Temperatur BMP180: ");
  Serial.print(tempBMP180);
  Serial.println("*C");

  Serial.print("Luftfeuchtigkeit DHT22: ");
  Serial.print(humidity);
  Serial.println("%");

  Serial.print("Luftdruck BMP180: ");
  Serial.print(pressure / 100);
  Serial.println("hPa");
  Serial.println();

  display.clearDisplay();

  display.setCursor(10, 10);
  display.println("Temp.:  " + String(tempBMP180) + " *C");

  display.setCursor(10, 29);
  display.println("Luftf.: " + String(humidity) + " %");
  display.setCursor(10, 48);

  display.println("Luftd.: " + String(pressure/100) + " hPa");

  display.display();
  delay(2000);
}

Auf deinem OLED-Display sollten nun untereinander die Werte für Temperatur, Luftfeuchtigkeit und Luftdruck zu sehen sein, die alle zwei Sekunden aktualisiert werden.

Die Daten auf dem Raspberry Pi speichern und visualisieren

Messdaten auf einem Display sind eine tolle Sache – aber wenn du die Werte deiner Wetterstation über längere Zeit speichern und sie als Graphen anzeigen möchtest, musst du ein paar Schritte weiter gehen.

Im Folgenden richtest du deinen Raspberry Pi so ein, dass du ihn bequem von deinem Computer per SSH steuern kannst. Anschließend installierst du dort die Datenbank InfluxDB, in der deine Messwerte gespeichert werden. Praktischerweise bringt InfluxDB gleich eine Möglichkeit, die Daten ansprechend darzustellen. Doch eins nach dem anderen.

Das Betriebssystem auf dem Raspberry Pi installieren

Zunächst benötigst du ein entsprechend konfiguriertes Betriebssystem. Das lässt du auf eine Micro-SD-Karte schreiben, die du dann in deinen Raspberry Pi steckst.

Besonders einfach ist das mit dem kostenlosen Rasperry Pi Imager, den du hier herunterladen kannst. Wähle einfach die Version für dein Betriebssystem und starte den Download.

Download-Screen Raspberry Pi Imager

Öffne das Programm nach dem Download und wähle in der Oberfläche unter Betriebssystem -> Raspberry Pi OS (other) -> Raspberry Pi OS (64-bit).

Schließe als nächstes die Micro-SD-Karte, auf die du das Raspberry Pi OS installieren möchtest, an deinen Computer an. Wähle sie anschließend im Feld SD-Karte aus.

Bevor du jetzt auf den Button Schreiben klickst, wähle zunächst die erweiterten Einstellungen hinter dem Zahnrad-Symbol. Hier kannst du gleich den Hostnamen festlegen, SSH aktivieren und auch deine WLAN-Zugangsdaten hinterlegen. Das bedeutet, dass du deinen Raspberry Pi nicht mehr an einen Monitor anschließen musst, um diese Einstellungen vorzunehmen. Später reicht es, die Micro-SD-Karte und das Stromkabel einzustecken.

Wähle zunächst im oberen Bereich die folgenden Optionen:

Raspberry Pi Imager erweiterte Optionen

Anschließend legst du deinen Benutzernamen fest und hinterlegst deine WLAN-Zugangsdaten. Die Wahl deines Benutzernamen steht dir natürlich frei – in den folgenden Befehlen verwenden wir hier jedoch das gängige pi.

Raspberry Pi Imager erweiterte Optionen

Noch ein Stück weiter unten stellst du noch dein Land und deine Zeitzone ein:

Raspberry Pi Imager erweiterte Optionen

Und das war es. Speichere diese Einstellungen und klicke im Hauptmenü auf Schreiben.

Per SSH auf den Raspberry Pi zugreifen

Nachdem das Raspberry Pi OS auf der Micro-SD-Karte und schließlich in deinem Raspberry Pi gelandet ist, starte diesen, indem du das Stromkabel anschließt. Warte nun ein paar Minuten, bis er fertig gebootet hat.

Nun wirst du dich per SSH (Secure Shell) mit dem Raspberry Pi verbinden. SHH ist eine beliebte – und verschlüsselte – Verbindung zwischen zwei Geräten. Hierdurch kannst du auf sichere Art und Weise von deinem Computer auf den Raspberry Pi zugreifen, Software installieren – und später deine Wetterdaten auswerten. So richtest du die Verbindung ein:

MacOS & Linux

Bei diesen beiden Betriebssystemen brauchst du lediglich das Terminal. In Unix-basierten Betriebssystemen ist SSH nämlich schon vorinstalliert. Öffne also das Terminal und tippe den folgenden Befehl ein:

sudo ssh pi@raspberrypi.local

Hinweis: Falls du einen anderen Benutzer- und Hostnamen vergeben hast, passe den Befehl entsprechend an.

Wenn du nach deinem Passwort gefragt wirst, trage jenes, das du im Raspberry Pi Imager vergeben hast, ein und drücke Enter. Möglicherweise musst du auch noch mal mit einem yes bestätigen, dass du die Verbindung aufbauen möchtest. Wenn die Verbindung steht, siehst du die folgende Zeile in deinem Terminal:

Kommandozeile im Terminal

Um die Verbindung wieder zu beenden und deinen Raspberry Pi herunterzufahren, trage folgenden Befehl ins Terminal ein:

sudo poweroff

Windows

In Windows benötigst du eine Software, um dich per SSH zu verbinden – zum Beispiel PuTTY. Diese Programm kannst du hier herunterladen.

Installiere PuTTY auf deinem Computer, öffne es und trage die folgenden Daten in den Optionen/Einstellungen ein:

  • Host Name: raspberrypi
  • Port: 22
  • Connection type: SSH

Klicke anschließend auf Open/Öffnen. Bei der ersten Verbindung erscheint ein Dialog-Fenster, das dich davor warnt, dass du eine Verbindung zu einem unbekannten Host aufbaust. Diese kannst du mit einem Klick auf No schließen.

Logge dich als nächstes mit deinen Zugangsdaten, die du im Raspberry Pi Imager festgelegt hast, ein. Sobald die Verbindung steht, siehst du auch wieder die oben genannte Zeile. Um den Raspberry Pi auszuschalten, verwendest du ebenfalls.

sudo poweroff

INfluxDB 2 auf dem Raspberry Pi installieren

Jetzt wo deine Verbindung steht, kannst du die Datenbank InfluxDB installieren, um die Daten deiner ESP8266 Wetterstation zu speichern. Trage hierfür im Terminal bzw. in PuTTY den folgenden Befehl ein. Kopiere die folgenden Zeilen vollständig, füge sie ins Terminal ein und führe sie mit Enter aus.

wget -q https://repos.influxdata.com/influxdata-archive_compat.key
echo '393e8779c89ac8d958f81f942f9ad7fb82a25e133faddaf92e15b16e6ac9ce4c influxdata-archive_compat.key' | sha256sum -c && cat influxdata-archive_compat.key | gpg --dearmor | sudo tee /etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg > /dev/null
echo 'deb [signed-by=/etc/apt/trusted.gpg.d/influxdata-archive_compat.gpg] https://repos.influxdata.com/debian stable main' | sudo tee /etc/apt/sources.list.d/influxdata.list

sudo apt-get update && sudo apt-get install influxdb2

Nun läuft die Installation im Terminal. Ab und an wirst du um deine Zustimmung zur Installation von Erweiterungspaketen gefragt. Gib diese einfach durch Eingabe von Y und Enter.

Nachdem die Installation abgeschlossen ist, erscheint wieder die Zeile pi@raspberrypi:~$

Trage nun folgenden Befehl im Terminal ein, der dafür sorgt, dass InfluxDB beim Start des Raspberry Pi ebenfalls gestartet wird:

sudo service influxdb start

Anschließend prüfst du noch kurz, ob InfluxDB aktiv ist:

sudo service influxdb status

Im Terminal erscheint nun einiges an Text – darunter hoffentlich ein grünes active (running):

Ausgabe im Terminal, dass InfluxDB aktiv ist

Drücke q auf deiner Tastatur, um wieder zur Kommandozeile zurückzukehren.

Auf die Datenbank zugreifen

Um auf InfluxDB im Browser zugreifen zu können, benötigst du zunächst die IP-Adresse des Raspberry Pi. Diese findest du mit folgendem Befehl im Terminal heraus:

hostname -I

In der Antwort des Raspberry Pi siehst du ganz vorne die IP-Adresse, in unserem Fall die 192.168.0.129

Um nun InfluxDB zu starten, öffne in deinem Browser ein neues Tab oder Fenster und tippe deine IP-Adresse gefolgt vom Port :8086. Die Adresse sieht dann zum Beispiel so aus:

192.168.0.129:8086

In deinem Browser öffnet sich nun die Startseite von InfluxDB:

Startscreen InfluxDB auf dem Raspberry Pi

Nun kann es losgehen – klicke also auf Get started. Es folgt eine Seite, auf der du deine Zugangsdaten festlegst:

Trage deinen Benutzernamen unter Username ein und hinterlege ein sicheres Passwort. Unter Initial Organization Name kannst du ebenso deinen Benutzernamen eintragen – solange du nicht wirklich eine Arbeitsgruppe für die Wetterstation hast.

Unter Initial Bucket Name kannst du zum Beispiel ESP8266 Wetterstation eintragen. Unter diesem Namen findest du später die Datenbank für deine Wetterstation.

Bestätige deine Eingabe und klicke auf der folgenden Seite auf Quick Start:

Testweise die WLAN-Signalstärke übertragen

Anschließend findest du auf der Webseite die Kachel Arduino. Dahinter verbirgt sich eine Art Tutorial, wie du deinen ESP8266 einrichtest, um Daten an die Datenbank zu übertragen – hier die Stärke deines WLAN-Signals. Dieses Tutorial spielen wir im Folgenden teilweise durch, um einen Sketch zu erhalten, den du danach so erweitern kannst, dass er die Messdaten der Wetterstation überträgt.

Im Menü links findest du mehrere Punkte – da du den zweiten Punkt Prepare Arduino IDE (also den ESP8266 in der IDE verfügbar machen) bereits beim Aufbau der Wetterstation abgeschlossen hast, kannst du ihn gleich überspringen und auf Install Dependencies klicken.

Hier erhältst du Informationen zu einer Bibliothek, die du in der Arduino IDE installieren musst, um Daten an InfluxDB übertragen zu können. Öffne also den Bibliotheksmanager und suche nach InfluxDB. Im Tutorial heißt die erforderliche Bibliothek InfluxDB Client for Arduino – es kann aber gut sein, dass du nur eine Bibliothek namens ESP8266 Influxdb findest. Sollte das der Fall sein, installiere einfach diese stattdessen. Wenn du fertig bist, klicke auf Next.

Auf der nächsten Seite Initialize Client kannst du den Bucket auswählen, in den die Daten übertragen werden sollen:

Gleich darunter findest du Code, den du in einen leeren Sketch einfügen sollst. Erstelle also einen neuen Sketch, kopiere den zur Verfügung gestellten Code und füge ihn ein. Achte unbedingt darauf, dass du die leeren Funktionen Setup und Loop mit diesem Code überschreibst.

In diesem Beispiel-Sketch musst du noch deine WLAN-Zugangsdaten hinterlegen, damit dein ESP8266 mit dem Raspberry Pi kommunizieren kann:

  // WiFi AP SSID
  #define WIFI_SSID "YOUR_WIFI_SSID"
  // WiFi password
  #define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"

Trage also deine Daten ein und klicke im Tutorial wieder auf Next.

Es folgen wieder zwei Zeilen Code, die du in der Setup-Funktion unterhalb des dort schon vorhandenen Codes einfügen musst:

Der Sketch in diesem Tutorial überträgt die Stärke deines WLAN-Signals an die Datenbank. Die zwei Zeilen fügen den Datenpunkten zwei Tags hinzu – einmal das Gerät und einmal die SSID, also der Name deines WLAN-Netzwerks.

Gleich darunter findest du den Loop des Sketchs. Dieser ist aktuell noch leer – kopiere ihn dir also aus dem Tutorial und überschreibe damit die leere Loop-Funktion in deiner Arduino IDE. Im Loop wird jede Sekunde der Received Signal Strength Indicator (RSSI, also die Signalstärke des WLAN-Netzes) gemessen und in der InfluxDB hinterlegt.

Die zwei nächsten Punkte des Tutorials können wir überspringen. Hier geht es um Datenbank-Abfragen, die wir jedoch für unsere Zwecke nicht benötigen.

Der vollständige Beispiel-Sketch

Diese Copy & Paste Arbeit hat etwas Fingerspitzengefühl erfordert. Wenn alles an der richtigen Stelle gelandet ist, sollte dein Sketch wie folgt aussehen:

#if defined(ESP32)
#include <WiFiMulti.h>
WiFiMulti wifiMulti;
#define DEVICE "ESP32"
#elif defined(ESP8266)
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
#define DEVICE "ESP8266"
#endif

#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>

// WiFi AP SSID
#define WIFI_SSID "YOUR_WIFI_SSID"
// WiFi password
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"

#define INFLUXDB_URL "DEINE URL (ist vorausgefüllt)"
#define INFLUXDB_TOKEN "DEIN TOKEN (ist vorausgefüllt)"
#define INFLUXDB_ORG "DEINE ORG (ist vorausgefüllt)"
#define INFLUXDB_BUCKET "ESP8266 Wetterstation"

// Time zone info
#define TZ_INFO "UTC2"

// Declare InfluxDB client instance with preconfigured InfluxCloud certificate
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);

// Declare Data point
Point sensor("wifi_status");

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

  // Setup wifi
  WiFi.mode(WIFI_STA);
  wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to wifi");
  while (wifiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println();

  // Accurate time is necessary for certificate validation and writing in batches
  // We use the NTP servers in your area as provided by: https://www.pool.ntp.org/zone/
  // Syncing progress and the time will be printed to Serial.
  timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");


  // Check server connection
  if (client.validateConnection()) {
    Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());
  } else {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
  }

  // Add tags to the data point
  sensor.addTag("device", DEVICE);
  sensor.addTag("SSID", WiFi.SSID());
}

void loop() {
    // Clear fields for reusing the point. Tags will remain the same as set above.
    sensor.clearFields();
  
    // Store measured value into point
    // Report RSSI of currently connected network
    sensor.addField("rssi", WiFi.RSSI());
  
    // Print what are we exactly writing
    Serial.print("Writing: ");
    Serial.println(sensor.toLineProtocol());
  
    // Check WiFi connection and reconnect if needed
    if (wifiMulti.run() != WL_CONNECTED) {
      Serial.println("Wifi connection lost");
    }
  
    // Write point
    if (!client.writePoint(sensor)) {
      Serial.print("InfluxDB write failed: ");
      Serial.println(client.getLastErrorMessage());
    }
  
    Serial.println("Waiting 1 second");
    delay(1000);
    
    }

Die Daten visualisieren

Jetzt wird es Zeit, sich die übertragenen Daten einmal anzusehen. Öffne hierfür im Menü links den Data Explorer über das Symbol mit dem Koordinatensystem und dem Graphen.

Hier kannst du dir im unteren Bereich eine Abfrage (Query) basteln, die die Signalstärke als Graphen darstellt:

Wähle hierfür links deinen Bucket und im ersten Filter rechts daneben im Dropdown-Menü SSID und darunter den Wert, der dem Namen deines WLAN-Netzwerks entspricht. Rechts daneben sollte ein weiterer Filter aufgehen, in dem im Dropdown-Menü bereits _field vorausgewählt ist. Als einzigen Wert findest du darin rssi, also die Signalstärke. Wähle diesen Wert aus. Falls noch ein weiterer Filter rechts daneben aufgehen, kannst du diesen über das X in der Ecke schließen.

Um diese als Graphen anzuzeigen, musst du nur noch rechts auf Submit klicken. Nun sollte im oberen Bereich eine Graph entstehen – hier ein Beispiel, das schon einige Minuten lief:

Deine Abfrage kannst du natürlich zeitlich anpassen. Voreingestellt ist ein Zeitraum von einer Stunde (Past 1h). Über das entsprechende Dropdown kannst du auch andere Zeiträume einstellen.

Ganz oben findest du auch die Auswahl Custom Time Range – hierüber kannst du den Zeitraum noch genauer über einen Kalender einstellen. Sobald du deine Auswahl getroffen hast, klicke links neben dem Dropdown-Menü auf den Refresh-Button oder auf Submit. Über diese beiden Buttons kannst du den Graphen auch aktualisieren, um die aktuellen Daten miteinzubeziehen.

Du überträgst nun bereits Daten von deinem ESP8266 an deine Datenbank auf dem Raspberry Pi – wenn auch “nur” die Stärke des WLAN-Signals. Nun wird es Zeit, die Messdaten zu übertragen.

Die Daten der ESP8266 WEtterstation übertragen und anzeigen

Um statt des WLAN-Signals die Messdaten zu übertragen, fügst du den Sketch aus dem Tutorial und deinen bisherigen Sketch der Wetterstation zusammen – und änderst außerdem noch zwei kleinere Stellen im Code.

Kopiere hierfür Stück für Stück aus deinem Wetterstation-Sketch die verschiedenen Teile (Bibliotheken und Definitionen, Setup sowie Loop) und füge sie nacheinander in den Sketch des Tutorials ein. Wenn du das getan hast, sieht dein vollständiger Sketch wie folgt aus:

#if defined(ESP32)
#include <WiFiMulti.h>
WiFiMulti wifiMulti;
#define DEVICE "ESP32"
#elif defined(ESP8266)
#include <ESP8266WiFiMulti.h>
ESP8266WiFiMulti wifiMulti;
#define DEVICE "ESP8266"
#endif

#include <InfluxDbClient.h>
#include <InfluxDbCloud.h>

// WiFi AP SSID
#define WIFI_SSID "YOUR_WIFI_SSID"
// WiFi password
#define WIFI_PASSWORD "YOUR_WIFI_PASSWORD"

#define INFLUXDB_URL "DEINE URL (ist vorausgefüllt)"
#define INFLUXDB_TOKEN "DEIN TOKEN (ist vorausgefüllt)"
#define INFLUXDB_ORG "DEINE ORG (ist vorausgefüllt)"
#define INFLUXDB_BUCKET "ESP8266 Wetterstation"

// Time zone info
#define TZ_INFO "UTC2"

// Declare InfluxDB client instance with preconfigured InfluxCloud certificate
InfluxDBClient client(INFLUXDB_URL, INFLUXDB_ORG, INFLUXDB_BUCKET, INFLUXDB_TOKEN, InfluxDbCloud2CACert);

// Declare Data point
Point sensor("wifi_status");

#include "DHT.h"
#include "Wire.h"
#include "Adafruit_BMP085.h"
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

#define DHTPIN D4
#define DHTTYPE DHT22

Adafruit_BMP085 bmp;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

float tempDHT22;
float tempBMP180;
float humidity;
float pressure;

DHT dht(DHTPIN, DHTTYPE);

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

  // Setup wifi
  WiFi.mode(WIFI_STA);
  wifiMulti.addAP(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to wifi");
  while (wifiMulti.run() != WL_CONNECTED) {
    Serial.print(".");
    delay(100);
  }
  Serial.println();

  // Accurate time is necessary for certificate validation and writing in batches
  // We use the NTP servers in your area as provided by: https://www.pool.ntp.org/zone/
  // Syncing progress and the time will be printed to Serial.
  timeSync(TZ_INFO, "pool.ntp.org", "time.nis.gov");


  // Check server connection
  if (client.validateConnection()) {
    Serial.print("Connected to InfluxDB: ");
    Serial.println(client.getServerUrl());
  } else {
    Serial.print("InfluxDB connection failed: ");
    Serial.println(client.getLastErrorMessage());
  }

  // Add tags to the data point
  sensor.addTag("device", DEVICE);
  
  Serial.begin(115200);
  dht.begin();

  if (!bmp.begin()) {
    Serial.println("Sensor BMP180 nicht gefunden!");
    while (1) {}
  }

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {  // Display-Addresse: 0x3C für Groesse 128x64px
    Serial.println(F("SSD1306 allocation failed"));
    for (;;)
      ;
  }
  display.setTextSize(1);       //Schriftgröße
  display.setTextColor(WHITE);  //Schriftfarbe


  display.clearDisplay();
  display.display();
}

void loop() {
  tempDHT22 = dht.readTemperature();
  tempBMP180 = bmp.readTemperature();
  humidity = dht.readHumidity();
  pressure = bmp.readPressure();

  Serial.print("Temperatur DHT22: ");
  Serial.print(tempDHT22);
  Serial.println("*C");

  Serial.print("Temperatur BMP180: ");
  Serial.print(tempBMP180);
  Serial.println("*C");

  Serial.print("Luftfeuchtigkeit DHT22: ");
  Serial.print(humidity);
  Serial.println("%");

  Serial.print("Luftdruck BMP180: ");
  Serial.print(pressure / 100);
  Serial.println("hPa");
  Serial.println();

  display.clearDisplay();
  display.setCursor(10, 10);
  display.println("Temp.:  " + String(tempBMP180) + " *C");
  display.setCursor(10, 29);
  display.println("Luftf.: " + String(humidity) + " %");
  display.setCursor(10, 48);
  display.println("Luftd.: " + String(pressure / 100) + " hPa");

  display.display();

  // Clear fields for reusing the point. Tags will remain the same as set above.
  sensor.clearFields();

  // Store measured value into point
  sensor.addField("temp", tempBMP180);
  sensor.addField("humidity", humidity);
  sensor.addField("pressure", pressure/100);

  // Print what are we exactly writing
  Serial.print("Writing: ");
  Serial.println(sensor.toLineProtocol());

  // Check WiFi connection and reconnect if needed
  if (wifiMulti.run() != WL_CONNECTED) {
    Serial.println("Wifi connection lost");
  }

  // Write point
  if (!client.writePoint(sensor)) {
    Serial.print("InfluxDB write failed: ");
    Serial.println(client.getLastErrorMessage());
  }



  Serial.println("Waiting 1 second");
  delay(1000);
}

Im Code oben findest du zwei Änderungen, die wir uns jetzt näher anschauen. Zunächst streichst du den Tag SSID in der Setup-Funktion, da wir das nicht mehr brauchen. Übrig bleibt das device (also ESP8266) – hierüber können wir später im Data Explorer die Messdaten leichter finden.

// Add tags to the data point
sensor.addTag("device", DEVICE);

Außerdem müssen statt der Signalstärke unsere Messdaten für Temperatur, Luftfeuchtigkeit und -druck übertragen werden. Das geschieht im Loop mit folgendem Code:

  // Store measured value into point
  sensor.addField("temp", tempBMP180);
  sensor.addField("humidity", humidity);
  sensor.addField("pressure", pressure/100);

Hiermit werden die drei Felder (fields) mit den Namen temp, humidity und pressure in der Datenbank angelegt und mit den aktuellen Daten der Sensoren versorgt. Diese stammen aus unseren Variablen tempBMP180, humidity und pressure. Wie du siehst teilst du den Wert in der Variablen pressure noch durch 100, um statt Pascal (Pa) Hektopascal (hPa) zu erhalten.

Und das war auch schon alles. Achte darauf, dass deine korrekten WLAN-Zugangsdaten im Sketch eingetragen sind und lade ihn auf deinen ESP8266.

Die Daten im Data Explorer anzeigen

Als nächstes schaust du im Data Explorer nach, ob die Daten auch wie gewünscht deine Datenbank erreichen. Klicke hierfür links auf den entsprechenden Menüpunkt und erstelle deine Abfrage wie folgt:

Hier pickst du dir testweise die Temperatur über die Variable temp heraus. Wenn du deine Abfrage erstellt hast, klicke auf den Button Submit. Im oberen Bereich der Seite sollte nun ein Graph zu sehen sein – hier wieder ein Beispiel, das schon einige Zeit lief:

Wie du hier siehst begann die Aufzeichnung kurz nach 12 Uhr am 7. August 2023 mit Werten um die 24 °C. Gegen 12:20 Uhr brach die Verbindung zur Datenbank ab (die Wetterstation war aus) und begann wieder gegen 12:30 Uhr. Diese Zwischenzeit wird im Graphen als Verbindungslinie zwischen dem letzten erhaltenen und ersten wieder verfügbaren Datenpunkt dargestellt. Anschließend sank die Temperatur kontinuierlich von 25 °C auf circa 24,7 °C.

Hinweis: Auf der rechten Seite findest du den Punk Aggregate Function – hier kannst du einstellen, ob du von den Temperaturwerten den Durchschnitt (mean), den Median oder immer den letzten aktuellen Wert (last) sehen möchtest. Die letzte Option zeigt dir immer den aktuellen, tatsächlichen Wert an. Die beiden anderen glätten hingegen den Graphen, sodass Temperaturausschläge weniger ins Gewicht fallen.

Solange deine ESP8266 Wetterstation also läuft, werden Daten gesammelt. Auf diese kannst du entweder über das Dropdown (z.B. Past 1h) oder spezifisch über den Punkt Custom Time Range zugreifen. Es gibt allerdings noch eine weitere spannende Funktion: ein Dashboard.

Die Messdaten auf einem Dashboard anzeigen

Um die aktuelle Abfrage auf einem Dashboard zu speichern, das dir einen schnellen Überblick verschafft, klicke zunächst im Menü links auf den entsprechenden Button:

Klicke anschließend rechts auf den Button Create Dashboard und anschließend auf New Dashboard. Auf der folgenden Seite kannst du oben einen Namen für das Dashboard vergeben, zum Beispiel ESP8266 Wetterstation:

Anschließend kannst du über den Button Add Cell eine Kachel hinzufügen – zum Beispiel den gerade gesehenen Temperaturverlauf. Du landest nach deinem Klick wieder in der Ansicht des Data Explorers, nur das du diesmal hier die Abfrage für die neue Temperatur-Kachel erstellst.

Vergib zunächst wieder ganz oben einen Namen, zum Beispiel Temperaturverlauf. Anschließend wählst du im unteren Bereich wieder die Variable temp aus.

Alles, was jetzt noch fehlt ist ein Klick auf das Häkchen oben rechts – und schon landest du wieder auf deinem Dashboard, das nun den Temperaturverlauf enthält.

Im oberen Bereich findest du den Button Set Auto Refresh – hierüber kannst du einstellen, in welchem Intervall das Dashboard und damit auch der Graph aktualisiert werden soll.

Apropos Graph, du kannst auf dem Dashboard auch die aktuelle Temperatur anzeigen lassen. Klicke hierfür wieder auf Add Cell und erstelle die bekannte Abfrage erneut. Sobald du auf Submit geklickt hast, erscheint wieder dein Temperaturverlauf. Oben links findest du ein Dropdown-Menü, in dem du die Anzeige anpassen kannst. Wähle hier den Eintrag Gauge.

Nun siehst du nicht mehr den Verlauf, sondern die aktuelle Temperatur:

Vergib dieser Kachel wieder einen Namen und klicke abschließend auf das Häkchen rechts oben. Nun landest du wieder in deinem Dashboard mit den zwei Kacheln zur Temperatur.

Mit deinen beiden anderen Messwerten zu Luftdruck und -feuchtigkeit kannst du genauso verfahren. Noch ein letzter Hinweis zu den Kacheln: Über den Button Customize kannst du die Anzeige noch anpassen, was besonders beim Luftdruck sinnvoll ist. Stelle hier unter Thresholds einen Bereich von 900 bis 1100 ein, damit der Zeiger auch etwas zum Anzeigen hat. Ebenso kannst du dem Wert noch ein Suffix vergeben – hier also hPa.

Warnungen per Nachricht senden

Möchtest du Nachrichten an dich oder jemand anderes senden, wenn ein bestimmter Messwert über- oder unterschritten wird? Im folgenden Tutorial erfährst du, wie du mit dem ESP8266 oder ESP32 Nachrichten per Telegram, WhatsApp und E-Mail verschickst.

]]>
https://polluxlabs.net/esp8266-projekte/esp8266-wetterstation-mit-datenaufzeichnung/feed/ 0
ESP8266 Deep Sleep – So legst du deinen ESP schlafen https://polluxlabs.net/arduino-tutorials/esp8266-deep-sleep-so-legst-du-deinen-esp-schlafen/ Fri, 12 May 2023 06:20:19 +0000 https://polluxlabs.net/?p=13867 ESP8266 Deep Sleep – So legst du deinen ESP schlafen Weiterlesen »

]]>
Der ESP8266 ist ein vielseitiger und preiswerter Mikrocontroller mit integrierter WiFi-Funktionalität. Eine seiner bemerkenswertesten Funktionen ist jedoch der Deep-Sleep-Modus, der es ermöglicht, den Stromverbrauch drastisch zu senken, wenn der Mikrocontroller nicht aktiv ist. Dies ist besonders nützlich in batteriebetriebenen IoT-Projekten, in denen die Energieeffizienz entscheidend ist.

So kann dein ESP zum Beispiel alle 20 Minuten aufwachen, einen Sensorwert übermitteln und sich dann wieder schlafen legen. In diesem Tutorial erfährst du, wie du dabei vorgehst und wie den Deep-Sleep-Modus programmierst.

Benötigte Materialien

Für einen ersten Test ohne Sensoren benötigst du nicht viel:

  • Ein ESP8266 Modul (z.B. NodeMCU oder Wemos D1 Mini)
  • Ein USB-Kabel zum Programmieren
  • Arduino IDE

Übrigens – falls du es noch nicht weißt – bei uns erfährst du, wie du deinen ESP8266 mit der Arduino IDE programmierst.

Verkabelung für den ESP8266 Deep Sleep

Die gute Nachricht, du benötigst nur ein einziges Kabel: Um den Deep-Sleep-Modus zu nutzen, muss der RESET-Pin des ESP8266 mit dem D0-Pin verbunden werden. Entweder verwendest du hier ein Female-Female-Kabel, das du direkt an die Pins des ESP steckst – oder du verwendest ein Breadboard. Mehr musst du für den Schlafmodus nicht tun.

Der Sketch

Lege in der Arduino IDE einen neuen Sketch an und füge den folgenden Code ein und lade ihn auf deinen ESP8266.

void setup() {
  // Beginne die serielle Kommunikation mit einer Baudrate von 9600
  Serial.begin(9600);

  // Ausgabe einer Nachricht, wenn der ESP8266 aufwacht
  Serial.println("Der ESP8266 ist aufgewacht!");
}

void loop() {
  // Warte ein wenig, bevor der ESP8266 in den Deep-Sleep-Modus wechselt
  delay(2000);

  // Ausgabe einer Nachricht, bevor der ESP8266 in den Deep-Sleep-Modus wechselt
  Serial.println("Der ESP8266 geht in den Deep-Sleep-Modus...");

  // Gib dem ESP8266 Zeit, die Nachricht zu senden, bevor er in den Deep-Sleep-Modus geht
  delay(100);

  // ESP8266 in den Deep-Sleep-Modus versetzen
  // Die Zeit ist in Mikrosekunden angegeben
  // 1 Sekunde = 1.000.000 Mikrosekunden
  // In diesem Fall wird der ESP8266 alle 10 Sekunden aufwachen
  ESP.deepSleep(10e6);
}

Nun sollte dein ESP8266 alle 10 Sekunden für 2 Sekunden aufwachen.

]]>
Countdown zum nächsten SpaceX Raketenstart https://polluxlabs.net/esp8266-projekte/countdown-zum-naechsten-spacex-raketenstart/ Sat, 20 Mar 2021 16:18:28 +0000 https://polluxlabs.net/?p=4485 Countdown zum nächsten SpaceX Raketenstart Weiterlesen »

]]>
Wenn du an einen Raketenstart denkst, kommt dir bestimmt vieles in den Sinn. Sicherlich auch der obligatorische Countdown. Wie wäre es, wenn du daheim die Sekunden zum nächsten Launch einer Rakete von SpaceX herunterzählst?

Elon Musks Weltraumunternehmen betreibt eine API, von der du unter anderem die Daten des nächsten Starts beziehen kannst. Hierfür benötigst du nur einen ESP8266. Den Countdown kannst du stilecht auf einem 7-Segment Display darstellen. Und für die Beleuchtung beim Lift-off eignet sich ein NeoPixel LED-Ring.

Fortgeschrittene

1 – 2 Stunden

ca. 15 €

Für dieses Projekt benötigst du (Mengen s. Beschreibung):

Noch ein Hinweis vorab: Genau auf die Sekunde wirst den Lift-off der Rakete leider nicht treffen. Das liegt weniger an deinem Projekt, sondern daran, dass die meisten Raketen nicht ganz pünktlich sind. 😉 Zumindest haben wir bei unseren Tests beobachtet, dass der tatsächliche Start von der Angabe in der API immer um ein paar Sekunden abweicht.

Grundlegende Tutorials

In diesem Projekt kommt einiges zum Einsatz, für das du auf Pollux Labs passende Tutorials findest:

Schaue zunächst in die oben genannten Tutorials, wenn du ein paar der Themen noch nicht kennst oder erfahren möchtest, wie du ein 7-Segment Display oder den NeoPixel LED-Ring anschließt.

Im Folgenden konzentrieren wir uns auf den Start der nächsten Rakete von SpaceX – bzw. auf die Daten, die du hierfür benötigst.

Die SpaceX API

SpaceX betreibt eine sehr große Datenbank, aus der du dich kostenlos bedienen darfst. Hier findest du beispielsweise Daten zu Raketen, Modulen und Startrampen – aber natürlich auch zu vergangenen und kommenden Raketenstarts. Du findest sogar die aktuelle Position des Tesla Roadsters, der in den Orbit geschossen wurde.

SpaceX Roadster im Orbit
Foto: SpaceX

All diese Daten kannst du über eine API abrufen und weiterverarbeiten – und zwar auch mit deinem ESP8266. Für dieses Projekt benötigst du also die Daten zum nächsten Raketenstart. Diese findest du unter folgender Adresse:

https://api.spacexdata.com/v4/launches/next

Wenn du diese URL in deinem Browser aufrufst, findest eine ganze Menge Daten im JSON-Format. Unter anderem auch den Zeitpunkt des nächsten SpaceX-Starts als Unixzeit. In diesem Fall der 24.3.2021 um 9:58 MEZ.

"date_unix":1616576280

Diese URL verwendest du in deinem Sketch, um mit Hilfe der aktuellen Uhrzeit die Dauer bis zum nächsten Start – und somit den Countdown – zu berechnen.

Die Daten abrufen

Du findest den gesamten Sketch am Ende des Projekts. An dieser Stelle steigen wir direkt beim Abruf der Daten von der SpaceX API ein.

Hierfür hinterlegst du zunächst zu Beginn des Sketchs die URL der API und den Port, der für die sichere Übertragung via HTTPS zuständig ist: 443.

const char* host = "https://api.spacexdata.com/v4/launches/next";
const int httpsPort = 443;

Als nächstes kommt der Loop. Hier erstellst du zunächst die Instanz http von HTTPClient und verbindest dich mit der API:

HTTPClient http;
client.connect(host, httpsPort);
http.begin(client, host);

Danach prüfst du, ob die Verbindung steht und speicherst die JSON-Daten, die du von der API erhältst, in der Variablen payload. Anschließend dekodierst du sie und “ziehst” dir die oben genannte Zeitangabe als Unixtime. Diese Zeitangabe speicherst du in der Variablen launchTime.

if (http.GET() == HTTP_CODE_OK) {
  String payload = http.getString();
  DynamicJsonDocument doc(3072);
  deserializeJson(doc, payload);

  launchTime = doc["date_unix"]; //Startzeit speichern

Als nächstes berechnest du den Countdown. Hierfür benötigst du natürlich auch die aktuelle Uhrzeit. Diese hast du weiter oben im Sketch schon ermittelt und in der Variablen currentTime gespeichert (Schaue hierfür in den vollständigen Sketch).

countdown = launchTime - currentTime;

Den SpaceX Countdown anzeigen

Jetzt lässt du deinen Countdown laufen, bis die Startzeit erreicht wurde:

while (countdown != 0) {

Du zeigst zunächst die Sekunden, die es noch bis zum Start dauert, auf dem Display an. Hier kommt eine Funktion ins Spiel, die du im vollständigen Sketch findest:

drawDigits(countdown);

Danach ziehst du vom Wert in der Variablen countdown eine Sekunde ab und wartest mit deinem delay auch genau diese eine Sekunde, bevor du die nächste Zahl anzeigst.

countdown -= 1;
delay(1000);

Wenn der While-Loop ausgelaufen ist, die Variable countdown also eine Null enthält, löschst du das Display, startest dafür den LED-Ring und lässt ihn z.B. eine halbe Stunde angeschaltet.

lc.clearDisplay(0);

for (int i = 0; i < 12; i++) {
  pixels.setPixelColor(i, pixels.Color(255, 0, 0));
  pixels.show();
  delay(1);
}

delay(1800000); //30 Minuten

In diesem Beispiel leuchten alles LEDs auf dem Ring in einem satten Rot auf. Du kannst dir aber natürlich auch etwas raffinierteres überlegen!

Spacex Countdown ESP8266
Ein möglicher Aufbau für das Projekt

Und das war es auch schon! Zuletzt noch ein Hinweis: Wenn dein Delay am Ende des Sketchs ausgelaufen ist, folgt die nächste Abfrage der SpaceX API. Möglicherweise liegen dann aber noch keine neuen Daten vor. Bis das soweit ist, kann es mitunter einige Stunden oder auch Tage dauern – du könntest deinen ESP8266 also auch erst einmal gar keine neue Abfrage stellen lassen.

Sketch als .txt anschauen

#include <ESP8266WiFi.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClientSecure.h>

WiFiClientSecure client;

//NTP
#include <NTPClient.h>
#include <WiFiUdp.h>
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

//SpaceX API URL und Port
const char* host = "https://api.spacexdata.com/v4/launches/next";
const int httpsPort = 443;

//WLAN Zugangsdaten
const char* ssid = "NETWORK";
const char* password =  "PASSWORD";

//Variablen
long launchTime;
long currentTime;
long countdown;

//7-Segment-Display
#include <LedControl.h>
LedControl lc = LedControl(12, 15, 13, 1); //12=D6=DIN, 15=D8=CLK, 13=D7=CS
const int NUM_DIGITS = 8;

//NeoPixel LED-Ring
#include <Adafruit_NeoPixel.h>

int leds = 12; //Anzahl der LEDs
int ledPin = 14; //14=D5, Pin, an dem der NeoPixel angeschlossen ist

Adafruit_NeoPixel pixels = Adafruit_NeoPixel(leds, ledPin, NEO_GRB + NEO_KHZ800);

void getCurrentTime() {

  timeClient.update();
  currentTime = timeClient.getEpochTime();
  
  Serial.print("Current Time= ");
  Serial.println(currentTime);
}

void drawDigits(int num) {
  for (int i = 0; i < NUM_DIGITS ; i++) {
    lc.setDigit(0, i, num % 10, false);
    num /= 10;
    if (num == 0)
      return;
  }
}

void setup() {
  Serial.begin(115200);
  client.setInsecure();

  //Einstellungen des 7-Segment-Displays
  lc.shutdown(0, false);
  lc.setIntensity(0, 8);
  lc.clearDisplay(0);

  //Einstellungen des NeoPixels
  pinMode (ledPin, OUTPUT);
  pixels.begin();
  pixels.setBrightness(255); //Helligkeit: 0 (aus) - 255

  for (int i = 0; i < 12; i++) {
    pixels.setPixelColor(i, pixels.Color(0, 0, 0));
    pixels.show();
    delay(1);
  }

  WiFi.begin(ssid, password); //Mit dem WLAN verbinden

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting to WiFi...");
  }
  delay(1000);
  Serial.println("Hello, world!");
}

void loop() {
  if ((WiFi.status() == WL_CONNECTED)) {

    getCurrentTime();

    HTTPClient http;
    client.connect(host, httpsPort);
    http.begin(client, host);

    if (http.GET() == HTTP_CODE_OK) {
      String payload = http.getString();
      DynamicJsonDocument doc(3072);
      deserializeJson(doc, payload);

      launchTime = doc["date_unix"]; //Startzeit speichern
      Serial.print("Launch Time: ");
      Serial.println(launchTime);

      countdown = launchTime - currentTime; //Countdown = Startzeit - aktuelle Zeit
    } else {
      Serial.print("Error on HTTP request (SpaceX): ");
      Serial.println(http.GET()); //Error Code
    }
  }

  while (countdown != 0) { //Solange die Startzeit nicht erreicht wurde
    Serial.print("Time Until Launch: ");
    Serial.println(countdown);
    drawDigits(countdown);
    countdown -= 1;
    delay(1000);
  }

  Serial.println("LAUNCH!"); // Startzeit = aktuelle Zeit
  lc.clearDisplay(0);

  for (int i = 0; i < 12; i++) {
    pixels.setPixelColor(i, pixels.Color(255, 255, 0));
    pixels.show();
    delay(1);
  }

  delay(1800000);
}
]]>
Erhalte eine Nachricht aufs Smartphone, wenn die Post da ist https://polluxlabs.net/esp8266-projekte/erhalte-eine-nachricht-aufs-smartphone-wenn-die-post-da-ist/ Wed, 06 Jan 2021 12:20:49 +0000 https://polluxlabs.net/?p=4657 Erhalte eine Nachricht aufs Smartphone, wenn die Post da ist Weiterlesen »

]]>
Gehst du ab und an vergeblich zum Briefkasten? Das ist jetzt vorbei! Dieses Projekt sendet dir eine Telegram-Nachricht aufs Smartphone, sobald der Briefträger die Post gebracht hat.

Hierfür verwenden wir einen Wemos D1 Mini und einen PIR-Bewegungsmelder. Du kannst aber natürlich auch einen anderen ESP8266 verwenden. Ebenso kannst du zum Beispiel ein Radarmodul verwenden, um die Bewegung im Briefkasten festzustellen.

Da wir im Briefkasten keine Steckdose haben, verwenden wir eine Powerbank für die Stromversorgung und versetzen den Microcontroller die meiste Zeit in Tiefschlaf. Eine Bedingung gibt es allerdings: Der D1 Mini bzw. ESP8266 muss sich mit deinem WLAN verbinden können – dieses sollte also bis zu deinem Briefkasten reichen.

Fortgeschrittene

1 – 2 Stunden

ca. 15€

Für dieses Projekt benötigst du (Mengen s. Beschreibung):

Angebot
AZDelivery ESP32 D1 Mini NodeMCU WiFi Modul + Bluetooth Internet Entwicklungsboard kompatibel mit Arduino inklusive E-Book!
AZDelivery ESP32 D1 Mini NodeMCU WiFi Modul + Bluetooth Internet Entwicklungsboard kompatibel mit Arduino inklusive E-Book!
✅ Unser D1 ESP32 ist kompatibel mit der Arduino-IDE, Lua und MicroPython und NodeMCU.
10,99 €
Haobase 100x 1N4007 DO-41 Gleichrichter Diode 1A 1000V
Haobase 100x 1N4007 DO-41 Gleichrichter Diode 1A 1000V
Sperrspannung: 1000 V.; Nennstrom: 1A.; Diodengröße: Ca. 4,5 mm (L) x 2,5 mm (D)...
4,90 €
Widerstand 1 K Ohm, 20 Stück, Metallschicht 0.6W 1% Metallfilm Widerstände
Widerstand 1 K Ohm, 20 Stück, Metallschicht 0.6W 1% Metallfilm Widerstände
Bauform Axial 207; Toleranz +/- 1%; Abmessungen D: 2,5mm L: 6,8mm; 0,6W Belastbarkeit bei...
AZDelivery Breadboard Kit - 3X Jumper Wire m2m/f2m/f2f + 3er Set MB102 Breadboard kompatibel mit Raspberry Pi inklusive E-Book!
AZDelivery Breadboard Kit - 3X Jumper Wire m2m/f2m/f2f + 3er Set MB102 Breadboard kompatibel mit Raspberry Pi inklusive E-Book!
✅ Steckbrett für schnellen Aufbau elektronischer Schaltungen mit 830 Kontakten.; ✅...
9,99 €

Alternativ kannst du auch einen NodeMCU ESP8266 und/oder ein Radarmodul verwenden:

Vorbereitungen

Ein paar Dinge musst du eventuell vorab erledigen – wie, erfährst du in diesen Tutorials: Richte dir zunächst einen Telegram-Bot ein, um Nachrichten vom D1 Mini auf deinem Smartphone erhalten zu können. Außerdem musst du deinen D1 Mini bzw. ESP8266 in deiner Arduino IDE verfügbar machen, um ihn von dort aus programmieren zu können.

Das Projekt aufbauen

Montiere zunächst alle Teile wie folgt auf deinem Breadboard.

Aufbau auf dem Breadboard
Aufbau auf dem Breadboard

Schauen wir zunächst auf die Verbindung der Pins D0 und RST: Hiermit kannst du deinen Microcontroller aufwecken, wenn von D0 ein Signal an RST gesendet wird. In diesem Projekt soll dieses Signal jedoch vom Bewegungssensor kommen. Damit es also nicht fälschlicherweise doch vom Pin D0 gesendet wird, verwenden wir eine Diode, die Strom von diesem Pin blockiert (achte beim Einbau auf die Richtung des weißen Rings). Falls du keine Diode zur Hand hast, sollte das Projekt behelfsweise auch mit einer einfachen Drahtbrücke funktionieren.

Noch ein Hinweis: Solange die beiden Pins miteinander verbunden sind, kannst du keinen Sketch hochladen. Hierfür musst du die Verbindung zunächst trennen.

Das Wecksignal für den D1 Mini

Du weckst deinen Microcontroller also über ein HIGH am Reset-Pin auf. Hierfür benötigst du allerdings einen eindeutigen Wechsel von LOW auf HIGH. Wenn du deinen PIR-Sensor direkt an den Reset-Pin anschließt, erhältst du kein korrektes Signal, was zu mehreren Resets hintereinander führen kann – oder einfach nicht funktioniert, wie in unseren Tests.

___STEADY_PAYWALL___

In Anlehnung an dieses Tutorial verbauen wir einen NPN-Transistor (BC547), der uns dabei hilft, ein eindeutiges Signal vom PIR-Sensor an den Reset-Pin des D1 Mini zu übertragen. Sollte das bei dir trotzdem zu ungewollten Neustarts (also Aufwachen) führen, wird im verlinkten Tutorial auch noch ein Aufbau mit einem Kondensator beschrieben, der dir weiterhelfen könnte.

Mehr über NPN-Transistoren erfährst du in diesem Artikel. In diesem Tutorial erfährst du mehr über den Bewegungssensor HC-SR501.

Der Sketch

Kommen wir also zum Code. Zunächst benötigst du ein paar Bibliotheken, die du zu Beginn des Sketchs einbindest. Falls noch nicht geschehen, installiere im Bibliotheksmanager die jeweils neueste Version.

#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

Anschließend folgen einige Definitionen und Konstanten für deine Zugangsdaten zum WLAN und zu deinem Telegram Bot. Zur Erinnerung: Wie du die benötigten Daten für Telegram erhältst, erfährst du im oben genannten Tutorial.

//Deine WLAN-Zugangsdaten
const char* ssid = "NETWORK";
const char* password = "PASSWORD";

//Dein Bot-Token
#define botToken "BOT-TOKEN"  // den Bot-Token bekommst du vom Botfather)

//Deine User ID
#define userID "USER-ID"

Im letzten Schritt vor der Setup-Funktion erstellst du eine Instanz von WiFiClientSecure und initialisierst mit dieser die Verbindung zum Telegram-Bot.

WiFiClientSecure client;
UniversalTelegramBot bot(botToken, client);

Die Setup-Funktion

Im Sketch für dieses Projekt benötigst du nur die Setup-Funktion, die nach dem Start des Wemos D1 Mini abläuft. Hier startest du die Internet-Verbindung und sendest die Nachricht, dass die Post da ist, an dein Smartphone (also an deinen Telegram-Bot). Zuletzt legst du deinen Microcontroller wieder schlafen.

Sobald er ein neues Signal von deinem Bewegungsmelder erhält, wacht er wieder auf und durchläuft das Setup erneut. Wie du siehst, benötigst du also keinen Loop.

Zuerst konfigurierst du den client, den du oben erzeugt hast, startest den Seriellen Monitor und gibst dort die Nachricht aus, dass dein D1 Mini aufgeweckt wurde:

client.setInsecure();
Serial.begin(115200);
Serial.println("Awake");

Anschließend stellst du die Verbindung zu deinem WLAN-Netzwerk her:

Serial.print("Connecting to WiFi: ");
Serial.println(ssid);

WiFi.mode(WIFI_STA);
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {
  Serial.print(".");
  delay(500);
}

Serial.println("");
Serial.println("Connected!");

Zuletzt sendest du eine Nachricht an deinen Telegram-Bot mit der Funktion bot.sendMessage() – wartest 2 Sekunden und legst den D1 Mini wieder schlafen:

bot.sendMessage(userID, "Your mail has arrived!", "");

delay(2000);
Serial.println("Going to sleep");
ESP.deepSleep(0);

Für den Tiefschlaf verwendest du die Funktion ESP.deepSleep() mit dem Parameter 0. Diese Null sorgt dafür, dass dein Microcontroller ohne zeitliches Limit in den Schlaf versetzt wird – das heißt er wird erst wieder durch ein Signal vom Bewegungssensor aufgeweckt.

Und das war es auch schon – eigentlich ganz einfach. Hier nun der gesamte Sketch zum Rauskopieren.

//Libraries
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

//WiFi Credentials
const char* ssid = "NETWORK";
const char* password = "PASSWORD";

//Telegram Bot Credentials
#define botToken "BOT-TOKEN"
#define userID "USER-ID"

WiFiClientSecure client;
UniversalTelegramBot bot(botToken, client);

void setup() {
  client.setInsecure();
  Serial.begin(115200);
  Serial.println("Awake");

  //Connecting to WiFi
  Serial.print("Connecting to WiFi: ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(500);
  }

  Serial.println("");
  Serial.println("Connected!");

  bot.sendMessage(userID, "Your mail has arrived!", "");

  delay(2000);
  Serial.println("Going to sleep");
  ESP.deepSleep(0);
}

void loop() {
}

Wie geht es weiter?

Du hast nun einen Post-Melder mit dem Bewegungssensor HC-SR501. Je nachdem, wie dein Briefkasten beschaffen ist, kann ein Radar-Modul die bessere Wahl sein.

Vielleicht fallen dir aber auch noch ganz andere Lösungen ein, um zu erkennen, dass dein Briefkasten geöffnet wurde. Nerdiger und ambitionierter wäre zum Beispiel eine Variante, die KI nutzt. Auf Pollux Labs kannst du die Grundlagen von Künstlicher Intelligenz auf Microcontrollern lernen.

]]>
Gute oder schlechte Nachrichten? Mit einer Sentimentanalyse findest du es heraus. https://polluxlabs.net/esp8266-projekte/pruefe-die-nachrichten-mit-einer-sentimentanalyse/ Mon, 23 Nov 2020 17:12:21 +0000 https://polluxlabs.net/?p=4243 Gute oder schlechte Nachrichten? Mit einer Sentimentanalyse findest du es heraus. Weiterlesen »

]]>
In diesem Projekt lädst du dir mit einem ESP32 aktuellen Schlagzeilen aus dem Internet und findest mit einer Sentimentanalyse heraus, ob sie positiv oder negativ sind. Ein NeoPixel LED-Ring zeigt dir dann an, ob die Nachrichtenlage gerade gut (grün), schlecht (rot) oder etwas dazwischen ist.

Fortgeschrittene

1 – 2 Stunden

ca. 12 €

Für dieses Projekt benötigst du (Mengen s. Beschreibung):

Die Basics

Vieles, was in diesem Projekt zum Einsatz kommt, haben wir bereits in Tutorials beschreiben. Wenn du etwas davon noch nicht kennst, wirf zunächst dort einen Blick hinein:

Im Folgenden konzentrieren wir uns darauf, mit einer Sentimentsanalyse herauszufinden, ob eine Nachricht gut oder schlecht ist – und das dann mit dem NeoPixel anzuzeigen.

Was ist eine Sentimentanalyse?

Für einen Menschen ist es normalerweise kein Problem zu beurteilen, ob die Stimmung (Sentiment) einer Aussage positiv, negativ oder irgendetwas dazwischen ist. Für einen Computer ist das etwas schwieriger, aber trotzdem möglich – mit den richtigen Algorithmen und Wörterbüchern.

Hierfür liest der Computer einen Text ein und beurteilt die Wörter und Wortzusammenhänge, die er dort vorfindet. Im Hintergrund steckt immer ein Wörterbuch, in dem Begriffe von Menschen bewertet wurden: Pech und Trauer sind negative Begriffe, Glück und Positiv hingegen – positive.

Aber so einfach ist es leider nicht: Oft steckt die Bedeutung einer Aussage nicht in einem einzelnen Wort, sondern in einer Wendung, die aus mehreren Wörtern besteht. Positiv mag zwar in den meisten Fällen etwas Gutes sein, wenn jedoch jemand auf ein Virus positiv getestet wurde, ist genau das Gegenteil der Fall.

Mehr über dieses spannende Thema findest du auf Wikipedia.

Der Aufbau des Projekts

Du musst im Prinzip nur deinen NeoPixel mit deinem ESP32 wie folgt verbinden:

NeoPixelESP32
VCC3v3
GNDGND
DI14

Natürlich kannst du hierfür einfach ein Breadboard verwenden. Etwas mehr Stimmung verleihst du mit einer Kugel und einem Sockel aus dem 3D-Drucker. Passende Plastikkugeln* findest du für wenig Geld im Bastelladen oder auf Amazon.

Die Schlagzeilen laden

Für dieses Projekt lädst du dir zunächst die aktuellen Schlagzeilen von einer kostenlosen API. Hierfür bietet sich der Service newsapi.org an. Erstelle dir dort zunächst einen kostenlosen Account, um deinen API Key zu erhalten, den du für die Abfrage der Nachrichten benötigst.

Danach kannst du z.B. länderspezifische Top Headlines abfragen, die dir als JSON zur Verfügung gestellt werden. Du kannst die Nachrichten jedoch auch nach Ländern, Suchbegriffen und Quellen filtern. Da die Sentimentanalyse, die wir später verwenden, kein Deutsch versteht, verwenden wir hier die Top Headlines der USA.

___STEADY_PAYWALL___

Die URL für den API Call lautet dann wie folgt – wobei du <<API-KEY>> durch deinen eigenen API Key ersetzen musst.

http://newsapi.org/v2/top-headlines?country=us&apiKey=<<API-KEY>>

Mit dieser Abfrage erhält dein ESP32 Daten im JSON-Format, die er – wie im oben genannten Tutorial beschrieben – mit der Bibliothek ArduinoJson verarbeiten und der Sentimentanalyse weitergeben kann.

Übrigens: Wenn du die aktuellen Nachrichten zum Corona-Virus analysieren möchtest, verwende die folgende URL (Covid ist in englischen Medien gängiger als Corona).

http://newsapi.org/v2/everything?q=covid&apiKey=<<API-KEY>>

Die Stimmung der Schlagzeilen bestimmen

Hier kommt eine weitere kostenlose API ins Spiel: meaningcloud.com – auch hier benötigst du einen kostenlosen Developer Account, der dir eine begrenzte (aber hier ausreichende) Anzahl von Abfragen zur Verfügung stellt. Für diesen Service benötigst du ebenfalls einen API Key, den du in der Abfrage-URL hinterlegen musst.

Diese URL sieht folgendermaßen aus:

http://api.meaningcloud.com/sentiment-2.1?key=<<API-KEY>>&of=json&txt=<<TEXT>>&lang=en

Wie du siehst, übergibst du die Schlagzeilen von newsapi.org in der URL an die API. Diese steckt in der Variable article, allerdings mit Leerzeichen zwischen den Wörtern, was in einer URL natürlich nicht funktioniert. Deshalb ersetzt du diese Leerzeichen wie folgt durch ein %20:

article.replace(" ", "%20");

Nun kannst du die URL für die Sentimentanalyse flexibel zusammenbauen:

http://api.meaningcloud.com/sentiment-2.1?key=<<API-KEY>>&of=json&txt=" + article + "&lang=en

Im Sketch passiert das in einem For-Loop insgesamt 15 Mal – für die 15 neuesten Schlagzeilen.

Die Ergebnisse der Sentimentanalyse

Jetzt wird es spannend: Die API spielt eine ganze Menge Daten im JSON-Format zurück, in denen uns hier aber nur die Stimmung der Schlagzeile interessiert. Hierfür gibt es fünf Werte:

Sehr positivP+
PositivP
NeutralNEU
NegativN
Sehr negativN+

Darüberhinaus gibt es noch den Wert NONE – falls keine Stimmung ermittelt werden konnte. Jedem dieser Werte ordnest du im Sketch eine Zahl zu: von 2 für P+ bis zu -2 für N+. Hier das Beispiel für eine sehr positive Schlagzeile:

if (score_tag == "P+") {
  sentiment += 2;
}

Diese Zahlen addierst du miteinander und erhältst dadurch einen Wert – den aktuellen Zustand der Welt. 😉

Den Gesamtwert als Farbe ausgeben

Theoretisch könnte sich der Gesamtwert der 15 Schlagzeilen zwischen -30 und +30 bewegen. In den meisten Fällen reicht jedoch eine Skala von -5 bis +5.

Diesen 11 Werten innerhalb der Skala ordnest du Farben zu, die du als RGB-Werte anlegst – und lässt deinen NeoPixel LED-Ring dann in der Farbe des Gesamtwerts leuchten. Wir haben uns für ein Farbspektrum von Rot zu Grün entschieden – mit Gelb in der Mitte für den neutralen Wert Null:

int minus5[] = {255, 0, 0};
int minus4[] = {255, 51, 0};
int minus3[] = {255, 102, 0};
int minus2[] = {255, 153, 0};
int minus1[] = {255, 204, 0};
int neutral[] = {255, 255, 0};
int plus1[] = {204, 255, 0};
int plus2[] = {153, 255, 0};
int plus3[] = {102, 255, 0};
int plus4[] = {51, 255, 0};
int plus5[] = {0, 255, 0};

Wenn du selbst die Farben bestimmten möchtest, eignet sich hierfür der Color Picker von Google.

Im Sketch fehlt nun nur noch etwas Code, um entsprechend des Gesamtwerts der Sentimentanalyse eine Farbe auszugeben. Für den Wert -4 zum Beispiel:

switch (sentiment) {
  case -4:
    for (int i = 0; i < 12; i++) {
      pixels.setPixelColor(i, minus4[0], minus4[1], minus4[2]);
      pixels.show();
    }
    break;

Alle Werte von -5 und darunter (sowie +5 und darüber) fängst du davor schon mit einer If-Abfrage ab:

if (sentiment <= -5) {
  for (int i = 0; i < 12; i++) {
    pixels.setPixelColor(i, minus5[0], minus5[1], minus5[2]);
    pixels.show();
  }

Ganz am Ende des Sketchs fügst du noch einen Delay ein, der bestimmt, wann die nächste Abfrage der Schlagzeilen und die Sentimentanalyse erfolgen soll – z.B. alle 30 Minuten:

delay(1800000);

Hier nun der gesamte Sketch:

Sketch als .txt anschauen

//Libraries
#include <ArduinoJson.h>
#include <WiFi.h>
#include <HTTPClient.h>
#include <Adafruit_NeoPixel.h>

//Pin for the NeoPixel
int ledPin = 14;

//Initiate NeoPixel
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(12, ledPin, NEO_GRB + NEO_KHZ800);

//Colors
int minus5[] = {255, 0, 0};
int minus4[] = {255, 51, 0};
int minus3[] = {255, 102, 0};
int minus2[] = {255, 153, 0};
int minus1[] = {255, 204, 0};
int neutral[] = {255, 255, 0};
int plus1[] = {204, 255, 0};
int plus2[] = {153, 255, 0};
int plus3[] = {102, 255, 0};
int plus4[] = {51, 255, 0};
int plus5[] = {0, 255, 0};


// WiFi Credentials
const char* ssid = "WiFi SSID";
const char* password =  "PASSWORD";

String article;
int sentiment = 0;

void getSentiment() {

  HTTPClient http;

  http.begin("http://api.meaningcloud.com/sentiment-2.1?key=<<API-KEY>>&of=json&txt=" + article + "&lang=en");

  int httpCode = http.GET();

  if (httpCode == 200) {

    String payload = http.getString();

    const size_t capacity = 2*JSON_ARRAY_SIZE(0) + 7*JSON_ARRAY_SIZE(1) + 5*JSON_ARRAY_SIZE(2) + 2*JSON_ARRAY_SIZE(3) + JSON_ARRAY_SIZE(4) + 2*JSON_ARRAY_SIZE(5) + 2*JSON_ARRAY_SIZE(6) + JSON_ARRAY_SIZE(7) + 25*JSON_OBJECT_SIZE(4) + 4*JSON_OBJECT_SIZE(6) + 22*JSON_OBJECT_SIZE(7) + JSON_OBJECT_SIZE(8) + 2*JSON_OBJECT_SIZE(9) + 3*JSON_OBJECT_SIZE(10) + JSON_OBJECT_SIZE(11) + 3500;

    DynamicJsonDocument doc(capacity);

    DeserializationError error = deserializeJson(doc, payload, DeserializationOption::NestingLimit(11));

    if (error) {
      Serial.print(F("deserializeJson() Error: "));
      Serial.println(error.c_str());
      return;
    }

    JsonObject status = doc["status"];
    String score_tag = doc["score_tag"];

    Serial.println(score_tag);

    if (score_tag == "P+") {
      sentiment += 2;
    }
    else if (score_tag == "P") {
      sentiment += 1;
    }
    else if (score_tag == "N") {
      sentiment -= 1;
    }
    else if (score_tag == "N+") {
      sentiment -= 2;
    }
  }

  else {
    Serial.println("Bad HTTP Request");
  }
  http.end();
}

void setup() {
  pixels.begin();
  pixels.setBrightness(175);

  pinMode (14, OUTPUT); //LED Pin


  Serial.begin(115200);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }
  Serial.println("Connected!");
}

void () {

  //reset sentiment count
  sentiment = 0;

  if ((WiFi.status() == WL_CONNECTED)) {

    HTTPClient http;

    http.begin("http://newsapi.org/v2/top-headlines?country=us&apiKey=<<API-KEY>>");

    int httpCode = http.GET();

    if (httpCode == 200) {

      String payload = http.getString();

      const size_t capacity = JSON_ARRAY_SIZE(20) + 20 * JSON_OBJECT_SIZE(2) + JSON_OBJECT_SIZE(3) + 20 * JSON_OBJECT_SIZE(8) + 16600;
      DynamicJsonDocument doc(capacity);

      DeserializationError error = deserializeJson(doc, payload);

      if (error) {
        Serial.print(F("deserializeJson() Error: "));
        Serial.println(error.c_str());
        return;
      }

      //Save number of headlines
      int noHeadlines = doc["totalResults"];

      //Loop through headlines & get sentiment
      for (int i = 0; i < 15; i++) {

        //Get Headlines from Newsapi
        JsonArray articles = doc["articles"];

        JsonObject articles_number = articles[i];

        const char* articles_number_title = articles_number["title"];

        article = String(articles_number_title);
        Serial.println(article);
        
        article.replace(" ", "%20");
        Serial.println(article);

        getSentiment();
      }
      
      Serial.println("Loop done.");
      Serial.println(sentiment);

      //Show state on NeoPixel
      if (sentiment <= -5) {
        for (int i = 0; i < 12; i++) {
          pixels.setPixelColor(i, minus5[0], minus5[1], minus5[2]);
          pixels.show();
        }
      } else if (sentiment >= 5) {
        for (int i = 0; i < 12; i++) {
          pixels.setPixelColor(i, plus5[0], plus5[1], plus5[2]);
          pixels.show();
        }
      }

      switch (sentiment) {
        case -4:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, minus4[0], minus4[1], minus4[2]);
            pixels.show();
          }
          break;
        case -3:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, minus3[0], minus3[1], minus3[2]);
            pixels.show();
          }
          break;
        case -2:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, minus2[0], minus2[1], minus2[2]);
            pixels.show();
          }
          break;
        case -1:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, minus1[0], minus1[1], minus1[2]);
            pixels.show();
          }
          break;
        case 0:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, neutral[0], neutral[1], neutral[2]);
            pixels.show();
          }
          break;
        case 1:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, plus1[0], plus1[1], plus1[2]);
            pixels.show();
          }
          break;
        case 2:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, plus2[0], plus2[1], plus2[2]);
            pixels.show();
          }
          break;
        case 3:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, plus3[0], plus3[1], plus3[2]);
            pixels.show();
          }
          break;
        case 4:
          for (int i = 0; i < 12; i++) {
            pixels.setPixelColor(i, plus4[0], plus4[1], plus4[2]);
            pixels.show();
          }
          break;
      }
    }

    else {
      Serial.println("Bad HTTP Request");
    }

    http.end();
    Serial.println("Connection closed.");
  }
  //Wait for 30 minutes until next call
  delay(1800000);
}

Wie geht es weiter?

Hast du Lust auf mehr Daten und mehr Beleuchtung? In diesem Projekt baust du einen Würfel, der beginnt zu leuchten, wenn die International Space Station über ihm fliegt.

]]>
Beleuchte deine LEGO Mondlandefähre, wenn der Mond am Himmel steht https://polluxlabs.net/esp8266-projekte/beleuchte-deine-lego-mondlandefaehre-wenn-der-mond-am-himmel-steht/ Wed, 18 Nov 2020 14:13:52 +0000 https://polluxlabs.net/?p=4188 Beleuchte deine LEGO Mondlandefähre, wenn der Mond am Himmel steht Weiterlesen »

]]>

Du hast eine LEGO Mondlandefähre (Apollo 11 Lunar Lander), aber dir fehlt noch die richtige Beleuchtung? In diesem Projekt verbaust du unter der Landefähre einen LED-Ring, den du mit einem ESP8266 anschaltest, sobald der Mond aufgeht – und wieder ausschaltest, nachdem der Mond untergegangen ist.

Anfänger

1 – 2 Stunden

ca. 15 € + LEGO Mondlandefähre

Für dieses Projekt benötigst du (Mengen s. Beschreibung):

In diesem Projekt lernst du, wie du einen NeoPixel LED-Ring verwendest, die aktuelle Uhrzeit per WLAN abrufst und, am wichtigsten: herausfindest, ob der Mond bereits aufgegangen ist oder nicht.

lego lunar lander cover

Der Aufbau

Du benötigst nur wenige Bauteile, die du schnell miteinander verbunden hast. Die NeoPixel LED-Ringe werden meistens unverlötet geliefert, d.h. du musst zunächst drei Kabel an die Pins GND, VCC und DI löten.

Lege nun den Ring in die runde Aussparung (Krater?) der Bodenplatte. Diese eignet sich perfekt, um den NeoPixel unterzubringen. Wenn du vom Rand der Aussparung ein Teil entfernst, kannst du die drei Kabel hier unauffällig durchführen:

Verbinde deinen NeoPixel anschließend mit deinem ESP8266 wie folgt:

NeoPixelESP8266
GNDGND
VCC3v3
DID5

Der Sketch für die Beleuchtung der Mondlandefähre

Viele der Themen, die im folgenden Sketch wichtig sind, haben wir bereits in anderen Tutorials behandelt:

Falls du hiermit noch nicht vertraut bist, wirf dort zunächst einen Blick rein.

Steht der Mond am Himmel?

Schauen wir uns das Kernstück des Sketchs an: Um herauszufinden, ob der Mond bereits aufgegangen ist, verwendest du die Bibliothek MoonRise.h. Diese findest du wie du es von anderen Bibliotheken gewohnt bist, im Bibliotheksmanager.

Der große Vorteil dieser Bibliothek ist es, dass sie anhand deiner Koordinaten und des Zeitunterschieds zur Koordinierten Weltzeit (UTC) die Monddaten auf deinem ESP8266 berechnet. Du benötigst hier also keine API-Abfragen oder ähnliches.

Binde also zunächst die Bibliothek MoonRise.h am Anfang deines Sketchs ein und hinterlege deine Koordinaten sowie den Zeitunterschied zur UTC in Stunden. Hier das Beispiel für Karlsruhe in der Winterzeit:

#include <MoonRise.h>
const float latitude = 49.00;
const float longitude = 8.40;
const int offset = 1;

Anschließend benötigst du zwei Variablen: Eine für die aktuelle Uhrzeit und eine für den Zustand Mond sichtbar/nicht sichtbar.

long currentTime;
bool moonVisible;

Danach erstellst du das Objekt mr der Bibliothek MoonRise:

MoonRise mr;

Das war es auch schon mit den Vorbereitungen. Fehlen nur noch zwei Zeilen Code, um herauszufinden, ob der Mond am Himmel steht.

 mr.calculate(latitude, longitude, currentTime + offset);
 moonVisible = mr.isVisible;

Mit der Funktion mr.calculate berechnest du anhand deiner Koordinaten, der aktuellen Uhrzeit und des Zeitunterschieds den Stand des Monds. Ob der Mond von deinem Standort aus sichtbar ist, erfährst du mit der Funktion mr.isVisible. Das Ergebnis – entweder 1 oder 0 – speicherst du in der Variablen moonVisible.

Übrigens: Die Bibliothek hat noch weitere Funktionen. Mehr darüber erfährst du auf Github.

Schalte den NeoPixel ein

Solange in der Variablen moonVisible eine 0 gespeichert ist – der Mond also noch nicht sichtbar ist – bleibt der LED-Ring ausgeschaltet. Sobald dort jedoch eine 1 seht, beginnt er, deine LEGO Mondlandefähre zu beleuchten. Das machst du mit folgendem Code:

if (moonVisible) {
  for (int j = 0; j < 12; j++) {
    pixels.setPixelColor(j, pixels.Color(237, 235, 28));
    pixels.show();
  }
} else {
  for (int j = 0; j < 12; j++) {
    pixels.setPixelColor(j, LOW);
    pixels.show();
  }
}

Wie du siehst, schaltest du in einem For-Loop alle 12 LEDs hintereinander ein bzw. aus. In der Funktion pixels.Color() kannst du die Farbe des Lichts bestimmen – in unserem Fall ein warmes Weiß. Du kannst alle möglichen anderen Farben wählen, indem du z.B. den Color Picker von Google verwendest.

Zuletzt legst du noch einen Delay fest, der bestimmt, in welchen Abständen du berechnest, ob der Mond am Himmel sichtbar ist. Im folgendem Fall alle 100 Sekunden:

delay(100000);

Hier nun der vollständige Sketch:

Sketch als .txt anschauen

/*********
  Frederik Kumbartzki
  Complete project details at https://polluxlabs.net
*********/

//WI-FI Credentials
const char* ssid = "YOUR WI-FI NETWORK";
const char* password =  "YOUR PASSWORD";

//Coordinates
const float latitude = 00.00; //Your Latitude
const float longitude = 00.00; //Your Longitude
const int offset = 0; //Your offset to UTC in hours

#include <MoonRise.h> //MoonRise Library
#include <ESP8266WiFi.h> //Wi-Fi

//Get time
#include <NTPClient.h>
#include <WiFiUdp.h>

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "pool.ntp.org");

#include <Adafruit_NeoPixel.h> //NeoPixel

//Times and Durations
long currentTime;
bool moonVisible;

//Moonrise Library
MoonRise mr;

//Initiate NeoPixel
Adafruit_NeoPixel pixels = Adafruit_NeoPixel(12, 14, NEO_GRB + NEO_KHZ800); //14 = Pin D5 on the board

void setup() {

  pixels.begin();
  pixels.setBrightness(250); //NeoPixel Brightness: 0-255

  Serial.begin(115200); //Start Serial Monitor
  WiFi.begin(ssid, password); //Go online

  while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.println("Connecting...");
  }

  delay(1000);
  Serial.println("Hello, world!");

  timeClient.begin();
}

void loop() {

  timeClient.update();

  currentTime = timeClient.getEpochTime();

  Serial.print(currentTime);
  Serial.print(" - ");

  Serial.print("moon visible: ");
  Serial.println(moonVisible);

  mr.calculate(latitude, longitude, currentTime + offset); //Calculate Moonrise
  moonVisible = mr.isVisible; //1 if Moon is visible, 0 if not

  if (moonVisible) {
    for (int j = 0; j < 12; j++) { //Light up all 12 LEDs on NeoPixel
      pixels.setPixelColor(j, pixels.Color(237, 235, 28)); //Set NeoPixel color in RGB
      pixels.show();
    }
  } else {
    //Turn off NeoPixel if Moon isn't visible
    for (int j = 0; j < 12; j++) {
      pixels.setPixelColor(j, LOW);
      pixels.show();
    }
  }
  delay(100000); //Wait until next query
}

Wie geht es weiter?

LEGO beleuchten ist das Richtige für dich? Dann probiere etwas ähnliches mit der LEGO ISS, die anfängt zu leuchten, wenn die echte ISS über ihr fliegt.

]]>
Das Licht ein- und ausschalten mit Telegram https://polluxlabs.net/esp8266-projekte/das-licht-ein-und-ausschalten-mit-telegram/ Wed, 11 Nov 2020 07:11:02 +0000 https://polluxlabs.net/?p=4091 Das Licht ein- und ausschalten mit Telegram Weiterlesen »

]]>
In diesem Projekt lernst du, wie du von deinem Smartphone aus eine Lichtquelle ein- und ausschalten kannst. Außerdem kannst du von dort aus abfragen, ob das Licht gerade an oder aus ist.

Für einen ersten Test verwendest du eine LED, die du an deinem ESP8266 anschließt. Wenn du später möchtest – und vorausgesetzt, du fühlst dich damit sicher – kannst du dich einer “richtigen” Lampe zuwenden. Hierfür benötigst du dann ein Relais, das du per Telegram steuert und das wiederum den Stromkreis der Lampe öffnet und schließt.

Dieses Projekt ist der vierte Teil einer Serie und baut auf die Vorgängerprojekte auf. In diesem Artikel findest du alles zum Aufbau und den passenden Sketch; wir besprechen jedoch nicht alle Teile des Codes. Wenn du mehr Details erfahren möchtest, wirf bitte einen Blick in die folgenden Projekte:

  1. Ein stiller Alarm mit Telegram und einem ESP8266
  2. Überwache die Temperatur mit Telegram und einem ESP8266
  3. Die aktuelle Temperatur per Telegram abfragen

Falls du noch kein Projekt mit Telegram gebaut hast, lerne zunächst, wie du einen Telegram-Bot erstellst.

Anfänger

1 – 2 Stunden

ca. 10 €

Für dieses Projekt benötigst du (Mengen s. Beschreibung):

Der Aufbau des Projekts

Du benötigst für dieses Projekt deinen ESP8266, eine LED samt Widerstand (z.B. 220 Ohm), ein Breadboard und Kabel. Orientiere dich an folgendem Schema:

Aufbau LED steuern

Wie du oben siehst, verbindest du die Anode (langes Bein) der LED mit dem Pin D5 an deinem ESP8266. Die Kathode (kurzes Bein) verbindest du über einen Widerstand mit GND.

Der Sketch

___STEADY_PAYWALL___

Kopiere den folgenden Sketch in deine Arduino IDE, ergänze deine Daten und lade ihn auf deinen ESP8266.

Sketch als .txt anschauen

/*
   Das Licht ein- und ausschalten mit Telegram - polluxlabs.net
*/

//Bibliotheken
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <UniversalTelegramBot.h>

// Deine WLAN-Zugangsdaten
const char* ssid = "NETZWERK";
const char* password = "PASSWORT";

// Den Telegram-Bot initialisieren
#define botToken "TOKEN"  // den Bot-Token bekommst du vom Botfather)

//Deine UserID
#define userID "USERID"

WiFiClientSecure client;
UniversalTelegramBot bot(botToken, client);

//Variable für das Licht
const int lightPin = 14; //Am ESP8266 Pin D5
bool lightState = LOW;

//Variable für die Anzahl der Anfragen
int numNewRequests;

//Variable für den Text der Anfrage, die du sendest
String text = "";

//UserID des Absenders
String chat_id = "";

//Name des Absenders
String from_name = "";

//Variable für die Willkommensnachricht
String welcome = "";

//Funktion fürs Verarbeiten neuer Anfragen
void handleNewRequests(int numNewRequests) {

  for (int i = 0; i < numNewRequests; i++) { //loopt durch die neuen Anfragen

    //Checkt, ob du die Anfrage gesendet hast oder jemand anderes
    chat_id = String(bot.messages[i].chat_id);
    if (chat_id != userID) {
      bot.sendMessage(chat_id, "Du bist nicht autorisiert!", "");
      continue;
    }

    // Anfragetext speichern
    text = bot.messages[i].text;
    Serial.println(text);

    from_name = bot.messages[i].from_name;

    if (text == "/start") {
      welcome = "Willkommen, " + from_name + ".\n";
      welcome += "Folgende Befehle kannst du verwenden: \n\n";
      welcome += "/lichtEin \n";
      welcome += "/lichtAus \n";
      welcome += "/status \n";
      bot.sendMessage(chat_id, "http://gph.is/1Rc70ke", "");
      bot.sendMessage(chat_id, welcome, "");
    }

    if (text == "/lichtEin") {
      lightState = HIGH;
      digitalWrite(14, lightState);
      bot.sendMessage(chat_id, "Das Licht ist an.", "");
    }

    if (text == "/lichtAus") {
      lightState = LOW;
      digitalWrite(14, lightState);
      bot.sendMessage(chat_id, "Das Licht ist aus.", "");
    }

    if (text == "/status") {
      if (digitalRead(lightPin)) {
      bot.sendMessage(chat_id, "Das Licht ist an.", "");
      }
      else {
        bot.sendMessage(chat_id, "Das Licht ist aus.", "");
      }
    }
  }
}

void setup() {

  Serial.begin(115200);
  client.setInsecure();

  pinMode(lightPin, OUTPUT);
  digitalWrite(lightPin, lightState);

  //Verbindung zum WLAN
  Serial.print("Verbinde mich mit: ");
  Serial.println(ssid);

  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED) {
    Serial.print(".");
    delay(300);
  }
  Serial.println("");
  Serial.println("Verbunden!");
}

void loop() {

  //checkt, ob eine neue Anfrage reinkam
  int numNewRequests = bot.getUpdates(bot.last_message_received + 1);

  while (numNewRequests) { //wird ausgeführt, wenn numNewRequests == 1
    Serial.println("Anfrage erhalten");
    handleNewRequests(numNewRequests);
    numNewRequests = bot.getUpdates(bot.last_message_received + 1);
  }
  delay(1000);
}

Was ist neu in diesem Sketch?

Viel musst du in deinem Code eigentlich nicht verändern, um statt der Temperaturabfrage das Licht ein- und auszuschalten. Werfen wir einen Blick auf die Details.

Zunächst benötigst du eine Konstante für den Pin, an dem die LED angeschlossen ist und eine Variable für den Zustand der LED – also ob sie an oder aus ist.

const int lightPin = 14; //Am ESP8266 Pin D5
bool lightState = LOW;

In der Setup-Funktion legst du den pinMode für den LED-Pin fest und weist der LED den Zustand zu, der in der Variablen lightState steht – also zu Beginn LOW – aus.

pinMode(lightPin, OUTPUT);
digitalWrite(lightPin, lightState);

Die Funktion handleNewRequests()

Diese Funktion kennst du ja bereits aus dem vorangegangenen Projekt. Hier werden deine Anfragen verarbeitet, die du von deinem Smartphone aus sendest.

Licht einschalten mit Telegram
Du kannst auch GIFs nutzen, sende dazu einfach die entsprechende URL. Im Sketch oben befindet sich schon eine.

In diesem Projekt gibt es drei Anfragen (oder Befehle), die du senden kannst: /lichtEin, /lichtAus und /status. Mit der letzten Anfrage fragst du ab, ob die LED gerade ein- oder ausgeschaltet ist und erhältst die entsprechende Antwort zurück.

Wenn du also deinem ESP8266 den Text /lichtEin sendest, setzt dieser die Variable lightState auf HIGH und schaltet die LED mit digitalWrite() ein. Zuletzt sendet er dir mit der bekannten Funktion bot.sendMessage() Feedback.

if (text == "/lichtEin") {
  lightState = HIGH;
  digitalWrite(14, lightState);
  bot.sendMessage(chat_id, "Das Licht ist an.", "");
}

Der Befehl /lichtAus funktioniert so ähnlich, nur dass er die LED natürlich ausschaltet. Wenn du /status sendest, prüft dein ESP8266, ob die LED ein- oder ausgeschaltet ist:

if (text == "/status") {
  if (digitalRead(lightPin)) {
  bot.sendMessage(chat_id, "Das Licht ist an.", "");
  }
  else {
    bot.sendMessage(chat_id, "Das Licht ist aus.", "");
  }
}

Wie geht es weiter?

Wie eingangs erwähnt, kannst du statt der LED ein Relais steuern. Je nachdem, welches Signal du diesem von deinem Smartphone aus sendest, öffnet und schließt das dann den Stromkreis eines anderen Geräts – z.B. einer Lampe oder einer Kaffeemaschine.

]]>