Portal naj

Portal naj

logo

ESP8266-01 als Wetterstation Aussenposten

Der folgende Artikel beschreibt, wie die Temperatur und Luftfeuchte des DHT22 mit dem ESP8266-01 ausgelesen werden können. Der EsP8266 ist ein W-LAN Modul und wird mit dem Heimnetzwerk verbunden. So können die Daten des DHT22 anschließend an einen Raspberry übertragen werden. Zusätzlich ist an den ESP8266 eine blinkende LED angeschlossen, als opotische Anzeige für die störungsfreie Funktion. Das Programm zum Auslesen der Temperatur, der Verbindung mit dem W-LAN und der Übertragung an der Daten, sowie für die blinkende LED ist in der Scriptsprache LUA geschrieben.

Auf dem Raspberry PI läfut ein Ampache Web-Server und MariaDB mit PHP-Myadmin. Die vom ESP8266 übermittelten Daten werden per PHP in eine Datenbank geschrieben und mittels php auf einer Website zur Verfügung gestellt.

Top

Technik

Die Installation eines Ampache Web-Servers und MariaDB ist nicht bestandteil diese Artikels. Hier sei auf najs weitere Projektseiten verwiesen.

Materialliste:

Top

Den ESP8266-01 über USB mit dem Rechner verbinden

ESP to USB Adapter
ESP-01 Programmer
Bevor mit dem ESP8266-01 gearbeitet werden kann muss dieser "programmiert", gelfasht werden. Hierzu muss dieser mit dem ESP-01 USB to serial Programmer verbunden werden. Diese besitzt einen USB-Port zum Anschluss an den PC. ESP-01 USB to serial Progrmmer

Der Adapter hat einen Schalter zum Wechsel zwischen Programmiermodus und Ausführen bereits fest installiert.

Pin-Belegung beim ESP8266-01

Achte darauf, dass die GPIO Nummerierung, wie auch beim Raspberry Pi, nicht mit der Pinbelegung übereinstimmt. So gilt bspw. beim ESP-01 GPIO0 = Pin3 und GPIO2 = Pin2. Im LUA-Script wird mit der GPIO Nummer gearbeitet. Die Belegung kann hier Pin-Belegung nachgelesen werden.

Abbildung des ESP8622-01 Chips
Pinbelegung des ESP8266-01
Um Code hochzuladen muss mann den ESP im Programmiermodus (Flash) starten. Hierzu muss beim Start (USB Kabel mit PC verbinden) GND mit GPIO0 verbunden werden, (Schalter auf Programmieren stellen). Für einen Neustart (reboot) muss man die Pins RST und GND verbinden, oder einfach das USB-Kabel ziehen.

Top

Update für den ESP8266-01

ESP-Prgrammer mit ESP8266-01
Der Schalter muss zum Flashen auf Prog stehen (zum gelben Sockel zeigend)

Um den ESP zu flashen muss GND mit GPIO 0 verbunden werden oder beim ESP-Programmer der Schalter auf Prog. gestellt werden. Aus dem Internet muss dass Programm “ESP8266Flasher” heruntergeladen werden. Download von GitHub: ESP8266Flasher

Auch auf Samba unter /EDV/Projekte/ESP8266 zu finden.

ESP-Flasher
Register Advanced des EPS-Flashers

Starte den ESP8266Flasher und wähle den entsprechenden Port aus, an dem der ESP8266 angeschlossen ist. Normalerweise wird dieser automatisch erkannt (solange nicht mehr als ein Modul angeschlossen ist). Nach Prüfung drücke auf Flash(F) und warte, bis der Vorgang vollendet ist. Die Mac-Adresse sollte direkt angezeigt werden. Achtung: Falls es Probleme mit der Ausgabe auf dem seriellen Monitor gibt, beim Flashen den FlashMode auf QIO stellen um eine Ausgabe auf den Seriellen Monitor zu bekommen. Sobald die Firmware erfolgreich übertragen wurde, kannst du GPIO0 von GND trennen (=Den Schalte Umstellen; weg vom Sockel) und das Flashing Tool schließen. Den ESP neu booten. Am einfachsten in dem man kurz den USB-Stecker zieht.

Top

ESP8266 mit dem WLAN verbinden

ESP-Flasher
Die Arduino IDE aufbau eines sketch

Um ein Programm auf dem ESP8266-01 zu istallieren nimmt man am Besten die Arduino IDE (Windows). Arduino IDE Damit mit dem ESP8266-01 gearbeitet werden kann muss die Arduino-Boardverwaltung um weitere Pakete erweitert werden. Im Menü Datei den Menüpunkt Voreinstellungen aufrufen. Dort gibt es das Eingabefeld Zusätzliche Boardverwalter URL´s*. Hier die unten aufgeführte Url eingeben und den Dialog mit OK schließen.

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

Aufruf der Boardverwaltung
Auswahl des passenden Boards über Boardverwalter → Board "Generick ESP8266 Module"

Nachdem Ihr die Voreinstellungen wieder mit OK verlassen habt, könnt Ihr im Menü Werkzeuge den Menüpunkt Board... und danach Boardverwalter auswählen. In der Boardverwaltung sucht Ihr jetzt nach ESP8266, in der Regel solltet Ihr es auch finden wenn ihr dort ganz nach unten scrollt. Wenn Ihr darauf klickt, dann erscheint ein Auswahlfeld für die Version und ein Installieren-Button.
Nachdem wir den Dialog mit Schließen geschlossen haben, können wir über das Menü den Eintrag NodeMCU 1.0 (ESP-12E Module) auswählen.

Im Menü → Werkzeuge → Board → ESP8266 Boards (2.74) den Eintrag NodeMCU 1.0 (ESP-12E Module)

Um eine WLAN-Verbindung herstellen zu können, müssen wir zunächst die notwendige WiFi-Bibliothek installieren. Dazu wählen wir im Menü Werkzeuge den Eintrag Bibliotheksverwalter. Dort geben wir im Suchfeld den Begriff wifi ein und installieren die WiFi-Bibliothek WIFI Built-In by Arduino.
Das folgende Script Stellt eine W-Lan-Verbindung her und lässt eine LED die an GPIO 2 angeschlossen ist blinken. Achtung die LED benötigt einen Vorwiederstand von 330 Ohm.
Die Meldungen zum W-Lan sollen am Seriellen Port ausgegeben werden, aber das klappt nur wenn:

Sonst zeigt der Monitor erst nach einem Wechsel der Baud-Rate etwas an.

Code für die W-Lan Verbindung am ESP-01 mit LUA-Script. Auch als Downlaod.

#include <ESP8266WiFi.h>

#ifndef STASSID

#define STASSID "Haging_13"
#define STAPSK "bauernhof13!"
#define LED 2

#endif

const char* ssid = STASSID;
const char* password = STAPSK;

void setup() {

Serial.begin(9600);
pinMode(LED, OUTPUT); // Port als Ausgang schalten
delay(100);

Serial.print("Connect to Wifi ");

WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) {

delay(1000);
Serial.print(".");

}

Serial.println("");
Serial.println("WiFi connected");
Serial.println("IP address: ");
Serial.println(WiFi.localIP());
pinMode(LED, OUTPUT); // Port als Ausgang schalten

}

void loop() {

digitalWrite(LED, LOW); //Led port ausschalten
delay(1000); //1 Sek Pause
digitalWrite(LED, HIGH); //Led port einschlaten
delay(1000);
if (WiFi.status() == WL_CONNECTED) {

// Your WiFi-Stuff here :-)

}

}

Top

DHT22 Temperatursensor am ESP8266-01 anschließen

Im Arduino Menü Über Sketzch → Bibliothek einbinden → Bibliothek verwalten nach "Adafruit Unified Sensor" suchen und installieren. Ebenso die DHT sensor library. Anschließend muss die Schaltung aufgebaut werden. Auf folgenden Bildern wird der Anschluss des DHT22 am ESP gezeigt. Anschließend wird die Schaltung um eine LED ergänzt. Die LED soll später durch Blinken den fehlerfreien Betrieb der Schaltung signalisieren. Als drittes noch der zugehörige Schaltplan.

DHT22-Sensor am ESP8266-01
Anschluss vom DHT22 am ESP8266-01

Code zum Auslesen der Temperatur und Luftfeuchte des DHT22-Sensor am ESP-01 mit LUA-Script auf dem seriellen Monitor. Auch als Downlaod.

#include "DHT.h"

#define DHT_Type DHT22
uint8_t DHTPIN = 2; //GPIO 02
DHT dht(DHTPIN, DHT_Type);

float t;
float h;

void setup() {

Serial.begin(9600);
pinMode(DHTPIN, INPUT);
dht.begin();

}

void loop() {

h = dht.readHumidity();
t = dht.readTemperature();

Serial.print("Temperatur: ");
Serial.print(t);
Serial.print("C, Luftfeuchtigkeit: ");
Serial.print(h);
Serial.print("%");

delay(3000);

}

Top

Daten auslesen und übertragen

Nun werdne beide Sketche zusammengeführt und zusätzlich mit einer blinkenden LED versehen. Die LED blinkt über eine While-Schleife. Dabei wird ein Timer hochgezählt. Ein Blinkzyklus dauert 2 Sekunden. Also ist ist eine Stunde vergangen, wenn der timer bei 1800 angekommen ist, erst dann kommt es zur Abfrage der Temperatur und Luftfeuchte.
Sketch mit blinkender LED an GPIO 0, W-LAN Verbindung und DHT22-Temperatursensor an GPIO 2 Das Beispiel hier ist für den Außenposten der Wetterstation am Samba. Auch als Downlaod

DHT-Sensor und LED am ESP8266-01
Anschluss vom DHT22 und einer LED am ESP8266-01
Schaltplan vom DHT22 und einer LED am ESP8266-01
Anschluss vom DHT22 und einer LED am ESP8266-01 - Schaltplan

//DHT22 Außenposten, inkl. W-Lan und blinkender LED

#define LED 0 //GPIO00 über 330 Ohm an Masse.

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <WiFiClient.h> //kann evtl. raus?
#include <Wire.h> // kann evtl. raus?
#include <Adafruit_Sensor.h> // kann evtl. raus?
#ifndef STASSID
#define STASSID "Haging_13"
#define STAPSK "bauernhof13!"
#endif

const char* ssid = STASSID;
const char* password = STAPSK;
const char* serverName = "http://192.168.178.27/post-outside.php"; //Adresse des Servers mit der SQL-Datenbank und Apache
String apiKeyValue = "tPmAT5Ab3j7F9"; //Sicherheitsspaß, dass nur dieser ESP Daten schicken darf.

#include "DHT.h"
#define DHT_Type DHT22
uint8_t DHTPIN = 2; // Der DHT22 hängt an GPIO 02
DHT dht(DHTPIN, DHT_Type);
float t;
float h;
int timer = 900;


void setup() {

pinMode(LED, OUTPUT); // Port als Ausgang schalten
Serial.begin(9600);
delay(2000);
Serial.print("Connect to Wifi ");
WiFi.begin(ssid, password);

while (WiFi.status() != WL_CONNECTED) { //solange die W-Lan verbindung aufgebaut wird, werden punkte geschrieben

delay(1000);
Serial.print(".");

}

Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());

pinMode(DHTPIN, INPUT);
dht.begin();
delay(5000);

}

void loop() {

while (timer < 900) {

digitalWrite(LED, LOW); //Led port ausschalten
delay(1000); //warte 1 sec.
digitalWrite(LED, HIGH); //Led port einschlaten
delay(1000);//warte 1 sec.
timer = timer + 1;

}

Serial.println(timer);
timer = 0;
Serial.println(timer);
if (WiFi.status() == WL_CONNECTED) {

Serial.println("Your WiFi-Stuff here :-)");
WiFiClient client;
HTTPClient http;
http.begin(client, serverName);
Serial.println(serverName);

// Specify content-type header
http.addHeader("Content-Type", "application/x-www-form-urlencoded");

h = dht.readHumidity();
t = dht.readTemperature();
Serial.print("Temperatur: ");
Serial.print(t);
Serial.println(" C");
Serial.print("Luftfeuchtigkeit: ");
Serial.print(h);
Serial.println(" %");

String httpRequestData = "api_key=" + apiKeyValue + "&Luftfeuchtigkeit=" + h + "&Temperatur=" + t;
Serial.print("httpRequestData: ");
Serial.println(httpRequestData);

// Send HTTP POST request
int httpResponseCode = http.POST(httpRequestData);
if (httpResponseCode>0) {

Serial.print("HTTP Response code: ");
Serial.println(httpResponseCode);

}
else {

Serial.print("Error code: ");
Serial.println(httpResponseCode);

}
// Free resources
http.end();

}

}

Top

Die Datenbank erstellen

Als Datenbannk läuft auf dem Raspberry PI MariaDB. Die Installation von MariaDB sowie des Apache Webservers werden in einem eigenen Artikel beschrieben.

Die Datenbank auf dem Raspberry Pi vorbereiten

Über die Secure Shell mit dem Raspberry Pi verbinden. Alternativ kann auch über das Webinterface phpmyadmin eine weitere Tabelle in der Datenbank Wetter anlegen.

http://192.168.178.27/phpmyadmin

In der Shell MariaDB aufrufen. Die Passwörter sind im Keepass hinterlegt.

mysql -u [username] -p

Auf dem Samba gibt es bereits die Datenbank “wetter” mit der Tabelle “tkschrank”. Diese muss aufgerufen werden:

use wetter;

Nun muss eine neue Tabelle in der Datenbank wetter (Maria DB) angelegt werden:

CREATE TABLE outside (

id INT(6) UNSIGNED AUTO_INCREMENT PRIMARY KEY,
Luftfeuchtigkeit VARCHAR(25) NOT NULL,
Temperatur VARCHAR(25) NOT NULL,
Timestamp VARCHAR(50) NOT NULL

);

Top

Die Daten in die Datenbank einlesen per PHP-Script

Auf dem Raspberry Pi einen Editor öffnen z.B. nano und eine Datei mit dem Namen "post-outside.php" erstellen.

pi@raspberrypi:~ $ nano /var/www/html/post-outside.php

Auf dem Samba muss die Datei unter /media/daten/web/naj abgespeichert werden. Dies ist der Ort an dem die Daten für die Website naj liegen. Das Verzeichnis web ist auch als Freigabe auf dem Samba zu erreichen. Hier das Script, wie immer auch als Download.

<?php

$servername = "localhost";

// REPLACE with your Database name
$dbname = "wetter";
// REPLACE with Database user
$username = "naj";
// REPLACE with Database user password
$password = "Chilli07";

// Keep this API Key value to be compatible with the ESP32 code provided in the
// project page. If you change this value, the ESP32 sketch needs to match
$api_key_value = "tPmAT5Ab3j7F9";
$Timestamp = date('d.m.Y H:i', time());

$api_key= $Luftfeuchtigkeit = $Temperatur = "";

if ($_SERVER["REQUEST_METHOD"] == "POST") {

$api_key = test_input($_POST["api_key"]);
if($api_key == $api_key_value) {

$Luftfeuchtigkeit = test_input($_POST["Luftfeuchtigkeit"]);
$Temperatur = test_input($_POST["Temperatur"]);
//$Timestamp = test_input($_POST["Timestamp"]);
$Timestamp = $Timestamp;
// Create connection
$conn = new mysqli($servername, $username, $password, $dbname);
// Check connection
if ($conn->connect_error) {

die("Connection failed: " . $conn->connect_error);
}

$sql = "INSERT INTO outside (Luftfeuchtigkeit, Temperatur, Timestamp)
VALUES ('" . $Luftfeuchtigkeit . "', '" . $Temperatur . "', '" . $Timestamp . "')";
if ($conn->query($sql) === TRUE) {

echo "New record created successfully";

}
else {

echo "Error: " . $sql . "
" . $conn->error;

}
$conn->close();

}
else {

echo "Wrong API Key provided.";

}

}
else {

echo "No data posted with HTTP POST.";

}
function test_input($data) {

$data = trim($data);
$data = stripslashes($data);
$data = htmlspecialchars($data);
return $data;

}
?>

Testen ob das Script aufrufbar ist:

http://192.168.178.27/post-esp-data.php (http://192.168.178.47/post-esp-data.php)
Test des Uploadscripts
Erscheint diese Info, funktioniert das Script einwandfrei
Top

Daten per PHP auf Website anzeigen

Um die Daten auf einer Website anzuzeigen müssen diese wieder aus der Datenbank ausgelesen werden über eine Web-Site mit PHP-Script. Die Seite kann die Endung phtml haben. Hier der Auszug um die Daten anzuzeigen. Im verwendeten Tutorial wurde ein anderes Script verwendet als das hier aufgeführte. Natürlich aus diese auch wieder zum Download.

<div align="center">

<?php

$con = mysqli_connect("localhost","naj","Chilli07","wetter");
if (mysqli_connect_errno())
{

echo "Failed" . mysqli_connect_error();

}
$result = mysqli_query($con,"SELECT Datum, Uhrzeit, Wochentag, luftfeuchtigkeit, temperatur FROM tkschrank ORDER BY id DESC LIMIT 25");
echo "<table>";

echo "<caption>Wetterdaten TK-Schrank</caption>";
echo "<thead>";

echo "<tr>";
echo "<th scope='coll'>Datum</th>";
echo "<th scope='coll'>Uhrzeit</th>";
echo "<th scope='coll'>Tag</th>";
echo "<th scope='coll'>rF (%)</th>";
echo "<th scope='coll'>Temp.(°C)</th>";
echo "</tr>";

echo "</thead>";
while( $row = mysqli_fetch_array($result))
{

echo "<tbody>";

echo "<tr>";
echo "<td><div align=center>". $row['Datum']. "</div></td>";
echo "<td><div align=center>". $row['Uhrzeit']. "</div></td>";
echo "<td><div align=center>". $row['Wochentag']. "</div></td>";
echo "<td><div align=center>". $row['luftfeuchtigkeit']. "</div></td>";
echo "<td><div align=center>". $row['temperatur']. "</div></td>";
echo "</tr>";

echo "</tbody>";

}
echo "<tfoot>";

echo "<tr>";
echo "<td class='fuss' colspan='5'>Wetterdaten des DHT22 - Temperatur und Luftfeuchte</td>";
echo "</tr>";

echo "</tfoot>";

echo "</table>";

mysqli_close($con);
?>

</div>

Top

Update Oktober 22 das Script mit einigen Anpassungen

Nach ein paar Tagen hat sich der ESP8622-01 leider immer wieder aufgehangen, zudem Übertrug der ESP die Daten zwar alle 30 Minuten, aber immer abhängig von der Zeit, zu der man den ESP8622-01 eingeschaltet hatte. Deshalb wurde das Script erweitert um die Funktionen TIME und die Temperatur wird nun in abhängigkeit der Uhrzeit gemessen. Die Idee den ESP8622-01 regelmäßig neu starten zu lassen führte leider dazu, dass der DHT22 nicht mehr richtig initialisiert wurde und keine Werte mehr lieferte. Statt dessen wurde nun eine Prüffunktion eingebaut, ob noch eine Verbindung zum WLAN besteht und wenn nicht wird ein Neuaufbau der Verbinung veranlasst.

//DHT22 Außenposten, inkl. W-Lan und blinkender LED und Zeit und Restart

#include <ESP8266WiFi.h>
#include <ESP8266HTTPClient.h>
#include <time.h> //time() ctime()
#ifndef STASSID
#define STASSID "Haging_13"
#define STAPSK  "bauernhof13!"
#endif

/*W-LAN und Datenübertragung an Server*/
const char* ssid     = STASSID;
const char* password = STAPSK;
const char* serverName = "http://192.168.178.27/post-outside.php"; //Adresse des Servers mit der SQL-Datenbank und Apache
String apiKeyValue = "tPmAT5Ab3j7F9"; //Sicherheitsspaß, dass nur dieser ESP Daten schicken darf.

/*Globale Variablen Time*/
time_t now;   //this is the epoch (Zeitraum)
tm tm;        // the structure tm holds time information in a more convenient (geeignet, praktisch) way
int sekunden;
int minuten;
int stunden;

/*Configuration LED*/
#define LED 0 //GPIO00 über 330 Ohm an Masse.

/*Configuration for NTP Timeserver*/
#define MY_NTP_SERVER "de.pool.ntp.org"           
#define MY_TZ "CET-1CEST,M3.5.0/02,M10.5.0/03"

#include "DHT.h"
#define DHT_Type DHT22
uint8_t DHTPIN = 2; // Der DHT22 hängt an GPIO 02
DHT dht(DHTPIN, DHT_Type);
float t;
float h;
int timer = 15;// contDown wann Daten übertragen werden sollen


void setup() {
 //Definiert die Zeitzone und den NTP-Server
 configTime(MY_TZ, MY_NTP_SERVER);
  
 pinMode(LED, OUTPUT); // Port als Ausgang schalten
 Serial.begin(9600);
 delay(2000);  
 Serial.print("Connect to Wifi "); 
 WiFi.begin(ssid, password); 
 
 while (WiFi.status() != WL_CONNECTED) {
    delay(1000);
    Serial.print("."); 
 }
   
 Serial.println("");
 Serial.println("WiFi connected");
 Serial.print("IP address: ");
 Serial.println(WiFi.localIP());

 //The ESP8266 tries to reconnect automatically when the connection is lost
  WiFi.setAutoReconnect(true);
  WiFi.persistent(true);

 pinMode(DHTPIN, INPUT);
 dht.begin();
 delay(5000);
}

void Zeit() {
  time(&now);                       // read the current time
  localtime_r(&now, &tm);           // update the structure tm with the current time
}
void loop() {
  Zeit();
  sekunden = tm.tm_sec;
  minuten = tm.tm_min;
  stunden = tm.tm_hour;
  
  if (sekunden % 2 == 0){
  digitalWrite(LED, LOW); //Led port ausschalten
  }
  else
  {
  digitalWrite(LED, HIGH); //Led port einschlaten
    Serial.print(stunden);
    Serial.print(":");
    Serial.print(minuten);
    Serial.print(":");
    Serial.print(sekunden);
    Serial.println(" - Stunden:Minuten:Sekunden");
  } 
  delay(1000); //warte 1 sec

  if (sekunden == 1){
    if (minuten == 0 or minuten == 15 or minuten == 30 or minuten == 45){
      if (WiFi.status() == WL_CONNECTED) {
       Serial.println("Your WiFi-Stuff here :-)");
       WiFiClient client;
       HTTPClient http;
       http.begin(client, serverName);
       Serial.println(serverName);
    
       // Specify content-type header - ohne keine Datenübertragung möglich!
        http.addHeader("Content-Type", "application/x-www-form-urlencoded");
    
        h = dht.readHumidity();
        t = dht.readTemperature();
        Serial.print("Temperatur: ");
        Serial.print(t);
        Serial.println(" C");
        Serial.print("Luftfeuchtigkeit: ");
        Serial.print(h);
        Serial.println(" %");
    
        String httpRequestData = "api_key=" + apiKeyValue + "&Luftfeuchtigkeit=" + h + "&Temperatur=" + t;
        Serial.print("httpRequestData: ");
        Serial.println(httpRequestData);
        
        // Send HTTP POST request
        int httpResponseCode = http.POST(httpRequestData);
        if (httpResponseCode>0) {
          Serial.print("HTTP Response code: ");
          Serial.println(httpResponseCode);
        }
        else {
          Serial.print("Error code: ");
          Serial.println(httpResponseCode);
        }
    // Free resources
    http.end();
    }
  }
  }
  /*Neustart:
  if (minuten  == 5 and sekunden == 5){ 
      Serial.println("Starte neu");
      //ESP.restart();
      ESP.reset();
    }*/
}

Top

Literatur- und Quellenverzeichnis