Skip to content

Technik Blog

Programmieren | Arduino | ESP32 | MicroPython | Python | Raspberry Pi | Raspberry Pi Pico

Menu
  • Smarthome
  • Arduino
  • ESP32 & Co.
  • Raspberry Pi & Pico
  • Solo Mining
  • Über mich
  • Deutsch
  • English
Menu

WEMOS D1 – WLAN Thermometer – Teil2 Upload der Daten in eine Datenbank

Posted on 4. Oktober 201713. Dezember 2023 by Stefan Draeger

Basierend auf das Tutorial WEMOS D1 – WLAN Thermometer mit DHT11 Sensor möchte ich nun die Daten in eine Datenbank speichern.

Dazu nutze ich eine MySQL Datenbank von „meinem“ Server.

  • Ziel
  • Schritt 1 – Erstellen der Datenbank
  • Schritt 2 – PHP Schnittstelle zum Schreiben in die Datenbank
  • Schritt 3 – Erweitern des Arduino Sketches
  • Download

Ziel

Ziel soll es nun sein den vorhandenen Sketch so umzuschreiben das die Webseite immer noch angezeigt wird, jedoch sollen die Daten in eine Datenbank geschrieben werden.

Schritt 1 – Erstellen der Datenbank

Als Erstes wird die Datenbank erzeugt. Da ich einen Webserver gemietet habe und auf diesem noch einige Datenbanken frei sind, kann ich mit folgendem Script eine Tabelle in einem aktuellen Schemata anlegen.

CREATE TABLE `data` (
  `id` int(11) NOT NULL,
  `temp` double NOT NULL,
  `press` double NOT NULL,
  `timestamp` bigint(20) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Schritt 2 – PHP Schnittstelle zum Schreiben in die Datenbank

Wenn die Datenbank erzeugt wurde, muss eine Schnittstelle zur Datenbank geschaffen werden. Dazu benutze ich nun eine einfache PHP Datei welche über die URL als Parameter die Werte der Temperatur und den Luftdruck erhält.
Der Zeitstempel wird vom Server zusätzlich an den Datensatz gehängt.

<?php

error_reporting(E_ALL);
ini_set('display_errors', 1);
 
  if (empty($_GET) || (!isset($_GET['temp']) || !isset($_GET['press']))) {
    echo "<h1>Es wurden keine oder nicht alle Parameter übergeben!</h1><br/>";  
    echo "Mögliche Parameter sind:<br/>";
    echo "<ul>";
    echo "<li>temp - Temperatur</li>";    
    echo "<li>press - Luftdruck</li>";
    echo "</ul><br/><br/>";
    $sampleLink = "http://progs.draeger-it.blog/wemosd1/dht11db/upload.php?temp=12.4&press=54.5";
    echo "zbsp.: <a href='$sampleLink'>$sampleLink</a>";
  } else {
    echo "<h2>Folgende Parameter wurden empfangen:</h2>";
    $tempValue = 0;
    $pressValue = 0;
    date_default_timezone_set('Europe/Berlin');
    $milliseconds = round(microtime(true));
    foreach ($_GET as $key => $value) { 
      echo "Parameter: ";
      echo $key;
      echo "<br/>Wert:";
      echo $value;
      echo "<br/><br/>";
      
      if($key === 'temp'){
        $tempValue = $value;
      } else if($key === 'press'){
        $pressValue = $value;
      }
    }
        
    echo "Zeitstempel: ";
    echo date('d.m.Y H:i:s',$milliseconds);
    echo " (<i>automatisch</i>)";

    echo "<br/>";    
    storeData($tempValue, $pressValue, $milliseconds);
  }
  
function storeData($tempValue, $pressValue, $milliseconds){
 $stmt = "INSERT INTO `data` ";
 $stmt .= "(`id`, `temp`, `press`, `timestamp`)";
 $stmt .= " VALUES (";
 $stmt .= "NULL";
 $stmt .= ",'";
 $stmt .= $tempValue;
 $stmt .= "',";
 $stmt .= "'";
 $stmt .= $pressValue;
 $stmt .= "',";
 $stmt .= "'";
 $stmt .= $milliseconds;
 $stmt .= "'";
 $stmt .= ");";
 
 fireSQLStmt($stmt);

}

function fireSQLStmt($sqlStmt){
  $connection = getDBConnection();
  $result = mysqli_query($connection,$sqlStmt);  
  return $connection->error;
}
  
function getDBConnection(){
  //Das bleibt Geheim!
  $dbname = ""; 
  $dbusername = "";
  $dbpassword = "";
  $dburl='';

  //Erzeugt einen Datenbanklink aus den Parametern (die Verbindungsdaten stehen in der Datei dbconfig.php)
	$link = mysqli_connect($dburl, $dbusername, $dbpassword,$dbname);
	if (!$link) {
		die('Verbindung schlug fehl: ' . mysqli_error());
	}
  
  /* check connection */
  if (mysqli_connect_errno()) {
       die($fehler1);
  }
  return $link;
}
?>

Schritt 3 – Erweitern des Arduino Sketches

Der Arduino Sketch muss nun so erweitert werden das der Wemos D1 eine HTTP Verbindung zu einem Server aufnimmt.
In diesem Fall soll der Wemos D1 eine Anfrage (Request) an die Adresse
http://progs.draeger-it.blog/wemosd1/dht11db/upload.php?temp=22.00&press=44.00
aufnehmen.

#include <ESP8266WiFi.h>
#include "DHT.h"
 
const char* ssid = ""; //SSID aus dem Router
const char* password = ""; //Passwort für den Zugang zum WLAN
 
int ledPin = D5; //digitaler PIN 5 des Wemos D1 an welchem die LED angeschlossen ist.
int ledStatus = LOW; //aktueller Status der LED (default / start  -> AUS)
WiFiServer server(80); //Port auf welchem der Server laufen soll.

 #define DHT11PIN 2 
 #define DHT11TYPE DHT11
 DHT dht11(DHT11PIN, DHT11TYPE);
 
void setup() {
  Serial.begin(115200); //Baudrate für die Serielle Geschwindigkeit.
  delay(10); //10ms. Warten damit die Seriele Kommunikation aufgebaut wurde.
  
  pinMode(ledPin, OUTPUT); //Den LEDPin als ausgang setzen.
  digitalWrite(ledPin, ledStatus); //Die LED initial auf den Status "AUS" setzen.
   
  Serial.print("Aufbau der Verbindung zu: "); //Ausgabe der SSID auf der Seriellen Schnittstelle.
  Serial.println(ssid);
  
  WiFi.begin(ssid, password); //Initialisieren der Wifi Verbindung.
 
  while (WiFi.status() != WL_CONNECTED) { //Warten bis die Verbindung aufgebaut wurde.
    delay(500);
    //Einen Punkt auf der Seriellen Schnittstelle ausgeben so das der Benutzer erkennt dass, das Sketch noch läuft.
    Serial.print("."); 
  }
  //Bei erfolgreicher Verbindung wird der folgende Text ausgeben.
  Serial.print("Mit ");
  Serial.print(ssid);
  Serial.print("erfolgreich verbunden!");

  dht11.begin();
  
  server.begin(); // Starten des Servers.
  Serial.println("Server gestartet"); //Ausgabe auf der Seriellen Schnittstelle das der Server gestartet wurde.
 
  // Ausgabe der IP Adresse 
  Serial.print("Adresse : http://");
  Serial.print(WiFi.localIP());
  Serial.println("/");
}

/**
 * Die Funktion gibt den HTML Kopf auf dem Client aus.
 * Dieses wird für jeden Respond verwendet.
 **/
void writeResponse(WiFiClient client, float tempValue, float pressValue){  
  client.println("HTTP/1.1 200 OK");
  client.println("Content-Type: text/html");
  client.println("");
  client.println("<!DOCTYPE HTML>");
  client.println("<html>"); 
  client.println("<head>"); 
  client.println("<script type='text/javascript' src='https://www.gstatic.com/charts/loader.js'></script>"); 
  client.println("<script type='text/javascript' src='http://progs.draeger-it.blog/wemosd1/dht11/gauges.js'></script>"); 
  client.println("<link rel='stylesheet' href='http://progs.draeger-it.blog/wemosd1/dht11/styles.css'/>");   
  client.println("</head>"); 
  client.println("<body>"); 
  client.println("<div id='tempChart' class='chartContainer'></div>"); 
  client.println("<div id='pressChart' class='chartContainer'></div>"); 
  client.println("<script>"); 
  client.println("google.charts.load('current', {'packages':['gauge']});"); 
  client.println("google.charts.setOnLoadCallback(drawCharts);"); 
  client.println("function drawCharts() {"); 
  client.print("drawTempChart(");
  client.print(tempValue); 
  client.print(");");
  client.print("drawPressChart(");
  client.print(pressValue); 
  client.print(");");
  client.println("}"); 
  client.println("</script>"); 
  client.println("</body>"); 
  client.println("</html>"); 
}

void loop() {
  //Prüfen ob sich ein Client verbunden hat, wenn nicht die Loop "verlassen"
  WiFiClient client = server.available();
  if (!client) {
    return;
  }
 
  // Wenn sich ein Client verbunden hat solange warten bis Daten gesendet werden.
  Serial.println("Neuer Client verbunden.");
  while(!client.available()){
    delay(1);
  }
 
  String request = client.readStringUntil('\r');
  Serial.println(request);
  client.flush(); 

  float tempValue = dht11.readTemperature(); //Temperatur vom Sensor DHT22 lesen
  float pressValue = dht11.readHumidity(); //relative Luftfeuchtigkeit vom Sensor DHT22 lesen

 if (isnan(tempValue) || isnan(pressValue)) {
     Serial.println("DHT11 konnte nicht ausgelesen werden");
 }
 
 writeResponse(client, tempValue, pressValue);
 delay(1500); 
 storeData(tempValue, pressValue); 
 delay(1); //1ms. Pause
}

void storeData(float tempValue,float pressValue){
    WiFiClient client;
    const char* host = "progs.draeger-it.blog";
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
      Serial.println("connection failed");
      return;
    }
   
    String url = "/wemosd1/dht11db/upload.php?";
    url = url + "temp="+tempValue;
    url = url + "&press="+pressValue;

    client.print(String("GET ") + url + " HTTP/1.1\r\n" +
                 "Host: " + host + "\r\n" + 
                 "Connection: close\r\n\r\n");
    delay(10);
}

Wenn nun im Browser die Adresse des Wemos D1 eingegeben wird, wird die bekannte Seite aus dem Tutorial WEMOS D1 – WLAN Thermometer mit DHT11 Sensor angezeigt.
Und 1500ms später wird der Request an die Adresse mit den Sensordaten gestellt.

Download

WEMOS D1 – WLAN Thermometer – Teil2 DatenbankHerunterladen

13 thoughts on “WEMOS D1 – WLAN Thermometer – Teil2 Upload der Daten in eine Datenbank”

  1. Svenja sagt:
    23. Oktober 2017 um 19:45 Uhr

    Das WLAN Thermometer (also mit der WebGUI) und dem Volkszähler Projekt wäre meiner Meinung nach sehr interessant.

    Antworten
    1. Stefan Draeger sagt:
      24. Oktober 2017 um 17:20 Uhr

      Hallo Svenja,
      soweit ich das überblicken kann ist das Volkszähler Projekt ja eher für den Bereich Photovoltaik ausgelegt.
      Aber sicherlich kann man generell jeden Sensor auslesen und die Daten an eine geeignete Schnittstelle senden.

      Gruß,

      Stefan

      Antworten
  2. Joachim sagt:
    3. Januar 2021 um 19:27 Uhr

    Hallo habe folgendes Problem,

    es funktioniert soweit alles, bis auf die Speicherung in der Datenbank.
    Keine Fehlermeldung aber es kommt nichts an.

    Bin mit meinem Latein am Ende.

    Antworten
    1. Stefan Draeger sagt:
      7. Januar 2021 um 14:42 Uhr

      Hallo,

      schauen Sie doch mal in das Access Log vom Webserver ob man zumindest einen Zugriff sieht. Ansonsten einmal die URL nachbauen und manuell über den Browser absenden.
      Ggf. sind Sonderzeichen enthalten welche durch Urlencoding Escaped werden müssen.

      Gruß,
      Stefan Draeger

      Antworten
  3. Bernd sagt:
    14. August 2021 um 10:05 Uhr

    Hallo,
    was ist falsch? Wenn ich „https://localhost/dht/public/upload.php?temp=12.4&press=54.5“ mit Browser abschicke, kommt es in der Datenbank an.
    Versuche ich es über die IP, erscheint im seriellen Monitor:
    „Adresse : http://192.168.178.48/
    Neuer Client verbunden.
    GET / HTTP/1.1
    connection failed
    Neuer Client verbunden.
    GET /favicon.ico HTTP/1.1
    connection failed“
    Die „ino“ sieht so aus(Auszug):
    const char* host = „localhost“;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
    Serial.println(„connection failed“);
    return;
    }
    String url = „/dht/public/upload.php?“;
    url = url + „temp=“+tempValue;
    url = url + „&press=“+pressValue;
    und die upload.php(Auszug) :
    function getDBConnection(){
    //Das bleibt Geheim!
    $dbname = „dht“;
    $dbusername = „root“;
    $dbpassword = „“;
    $dburl=’localhost‘;
    Komme nicht weiter.
    Gruß Bernd

    Antworten
    1. Stefan Draeger sagt:
      14. August 2021 um 12:27 Uhr

      Hi Bernd,

      der „Fehler“ liegt daran das bei der connection mit localhost geprüft wird. Gleich am Anfang des Codes. Das klappt mit localhost im eigenen, lokalen Netzwerk ohne Probleme. Wenn du aber über das Internet mit einer entsprechenden Freigabe arbeiten möchtest dann musst du hier die IP Adresse eintragen.

      Gruß,

      Stefan Draeger

      Antworten
  4. Bernd sagt:
    14. August 2021 um 14:02 Uhr

    Danke für schnelle Antwort.
    Ich arbeite nicht übers internet, sondern mit „xammp“. Deshalb habe ich in der „Upload.php“ und in der „ino“ „localhost“ eingetragen.
    function getDBConnection(){
    //Das bleibt Geheim!
    $dbname = „dht“;
    $dbusername = „root“;
    $dbpassword = „“;
    $dburl=’localhost‘;

    void storeData(float tempValue,float pressValue){
    WiFiClient client;
    const char* host = „localhost“;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
    Serial.println(„connection failed“);
    return;

    Antworten
    1. Stefan Draeger sagt:
      15. August 2021 um 08:28 Uhr

      Hi,

      okay aber du musst trotzdem die Zeile „const char* host = “localhost”;“ auf deine genannte IP-Adresse anpassen, dann sollte es passen.
      Die DB Konfiguration ist so i.O.

      Gruß,

      Stefan Draeger

      Antworten
      1. Bernd sagt:
        17. August 2021 um 14:49 Uhr

        Hallo nochmal,
        letzte Frage. Die Verbindung mit der Datenbank scheint jetzt klappen. Es werden aber keine Werte eingetragen. Wenn ich
        client.print(String(„GET“) + url + “ HTTP/1.1\r\n“ +
        „Host: “ + host + „\r\n“ +
        „Connection: close\r\n\r\n“);
        auch auf dem Monitor ausgeben lasse, erscheint
        Neuer Client verbunden.
        GET /favicon.ico HTTP/1.1
        GET/localhost/uploadlocal.php?temp=32.30&press=1.00 HTTP/1.1
        Host: 192.168.178.43
        Connection: close
        Sollte doch so stimmen, oder?
        Gruß Bernd

        Antworten
  5. Stefan Draeger sagt:
    19. August 2021 um 08:25 Uhr

    Hi,

    wenn ich richtig sehe fehlt da ein Leerzeichen „GET/localhost/u….“ -> „GET /localhost/u…“.

    Gruß,

    Stefan

    Antworten
  6. Thomas sagt:
    13. Dezember 2021 um 12:23 Uhr

    Hallo Stefan
    find das Projekt echt spannend
    komm leider nicht mehr weiter
    hab auf einem anderen PC Apache laufen
    hatte auch die Datenbank eingerichtet
    laut Access Log von Apache wird das Übergeben
    192.168.0.14 – – [13/Dec/2021:12:16:28 +0100] „GET 192.168.0.15/tank/upload.php?temp=22.80&press=34.00 HTTP/1.1“ 400 328 „-“ „-“
    hoffe das das so passt
    bin kein Programmierer Sorry !
    leider werden keine Daten in die Datenbank eingetragen
    hier mal die Datenbankverbindung aus dem PHP
    function getDBConnection(){
    //Das bleibt Geheim!
    $dbname = „data“;
    $dbusername = „tank“;
    $dbpassword = „tank12“;
    $dburl=’192.168.0.15′;
    und hier die der vom Arduino IDE
    void storeData(float tempValue,float pressValue){
    WiFiClient client;
    const char* host = „192.168.0.15“;
    const int httpPort = 80;
    if (!client.connect(host, httpPort)) {
    Serial.println(„connection failed“);
    return;
    }

    String url = „192.168.0.15/tank/upload.php?“;
    url = url + „temp=“+tempValue;
    url = url + „&press=“+pressValue;

    client.print(String(„GET „) + url + “ HTTP/1.1\r\n“ +
    „Host: “ + host + „\r\n“ +
    „Connection: close\r\n\r\n“);
    weis mittlerweile nicht mehr weiter
    können Sie mir weiterhelfen? das ganze soll dann später so geändert werden dass ich die Menge meiner Öltanks anzeigen kann und speichern ohne dass ich immer in die Garage muss 🙂

    schonmal vielen dank !!!

    Antworten
    1. Stefan Draeger sagt:
      15. Dezember 2021 um 07:07 Uhr

      Hallo Thomas,

      das & in der URL ist nicht korrekt. Ersetze dieses escapte Zeichen gegen ein einfaches UND Symbol „&“.

      Gruß,

      Stefan

      Antworten
  7. Pingback: ESP8266 DIY IoT Wetterstation, Webseite mit Sensordaten - Teil 2 - Technik Blog

Schreibe einen Kommentar Antworten abbrechen

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

Fragen oder Feedback?

Du hast eine Idee, brauchst Hilfe oder möchtest Feedback loswerden?
Support-Ticket erstellen

Newsletter abonnieren

Bleib auf dem Laufenden: Erhalte regelmäßig Updates zu neuen Projekten, Tutorials und Tipps rund um Arduino, ESP32 und mehr – direkt in dein Postfach.

Jetzt Newsletter abonnieren

Unterstütze meinen Blog

Wenn dir meine Inhalte gefallen, freue ich mich über deine Unterstützung auf Tipeee.
So hilfst du mit, den Blog am Leben zu halten und neue Beiträge zu ermöglichen.

draeger-it.blog auf Tipeee unterstützen

Vielen Dank für deinen Support!
– Stefan Draeger

Kategorien

Tools

  • Unix-Zeitstempel-Rechner
  • ASCII Tabelle
  • Spannung, Strom, Widerstand und Leistung berechnen
  • Widerstandsrechner
  • 8×8 LED Matrix Tool
  • 8×16 LED Matrix Modul von Keyestudio
  • 16×16 LED Matrix – Generator

Links

Blogverzeichnis Bloggerei.de TopBlogs.de das Original - Blogverzeichnis | Blog Top Liste Blogverzeichnis trusted-blogs.com

Stefan Draeger
Königsberger Str. 13
38364 Schöningen

Tel.: 01778501273
E-Mail: info@draeger-it.blog

Folge mir auf

  • Impressum
  • Datenschutzerklärung
  • Disclaimer
  • Cookie-Richtlinie (EU)
©2025 Technik Blog | Built using WordPress and Responsive Blogily theme by Superb
Cookie-Zustimmung verwalten
Wir verwenden Technologien wie Cookies, um Geräteinformationen zu speichern und/oder darauf zuzugreifen. Wir tun dies, um das Surferlebnis zu verbessern und um personalisierte Werbung anzuzeigen. Wenn Sie diesen Technologien zustimmen, können wir Daten wie das Surfverhalten oder eindeutige IDs auf dieser Website verarbeiten. Wenn Sie Ihre Zustimmung nicht erteilen oder zurückziehen, können bestimmte Funktionen beeinträchtigt werden.
Funktional Immer aktiv
Die technische Speicherung oder der Zugang ist unbedingt erforderlich für den rechtmäßigen Zweck, die Nutzung eines bestimmten Dienstes zu ermöglichen, der vom Teilnehmer oder Nutzer ausdrücklich gewünscht wird, oder für den alleinigen Zweck, die Übertragung einer Nachricht über ein elektronisches Kommunikationsnetz durchzuführen.
Vorlieben
Die technische Speicherung oder der Zugriff ist für den rechtmäßigen Zweck der Speicherung von Präferenzen erforderlich, die nicht vom Abonnenten oder Benutzer angefordert wurden.
Statistiken
Die technische Speicherung oder der Zugriff, der ausschließlich zu statistischen Zwecken erfolgt. Die technische Speicherung oder der Zugriff, der ausschließlich zu anonymen statistischen Zwecken verwendet wird. Ohne eine Vorladung, die freiwillige Zustimmung deines Internetdienstanbieters oder zusätzliche Aufzeichnungen von Dritten können die zu diesem Zweck gespeicherten oder abgerufenen Informationen allein in der Regel nicht dazu verwendet werden, dich zu identifizieren.
Marketing
Die technische Speicherung oder der Zugriff ist erforderlich, um Nutzerprofile zu erstellen, um Werbung zu versenden oder um den Nutzer auf einer Website oder über mehrere Websites hinweg zu ähnlichen Marketingzwecken zu verfolgen.
Optionen verwalten Dienste verwalten Verwalten von {vendor_count}-Lieferanten Lese mehr über diese Zwecke
Einstellungen anzeigen
{title} {title} {title}