Arduinoskript
#include <ESP8266WiFi.h> #include <ESP8266HTTPClient.h> #include <Arduino.h> HTTPClient sender; WiFiClientSecure wifiClient; // WLAN-Daten const char* ssid = "wlan_ssid"; const char* password = "passwort"; // uint8_t newMACAddress[] = {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xf2}; // CO2 - Sensor #include <Mhz19.h> #include <SoftwareSerial.h> SoftwareSerial softwareSerial(D7, D8); Mhz19 sensor; int carbonDioxide; // Display #include <Wire.h> #include "SSD1306Ascii.h" #include "SSD1306AsciiWire.h" SSD1306AsciiWire oled; // Luftfeuchtigkeitssensor #include "DHT.h" #define DHTPIN 12 //Der Sensor wird an PIN 12 angeschlossen #define DHTTYPE DHT22 // Es handelt sich um den DHT22 Sensor DHT dht(DHTPIN, DHTTYPE); //Der Sensor wird ab jetzt mit „dht“ angesprochen float temperatur; float luftfeuchtigkeit; void setup() { Serial.begin(9600); // Display Wire.begin(); Wire.setClock(400000L); oled.begin(&Adafruit128x32, 0x3C); oled.setFont(System5x7); oled.clear(); // Beginn Netzwerk und WLAN - Konfiguration // auskommentieren, falls notwendig //WiFi.mode(WIFI_STA); //wifi_set_macaddr(STATION_IF, &newMACAddress[0]); //IPAddress ip(10, 144, 5, 2); //IPAddress dns(10, 144, 1, 1); //IPAddress gateway(10, 144, 1, 2); //IPAddress subnet(255, 255, 0, 0); //WiFi.config(ip, dns, gateway, subnet); // ende der Netzwerkkonfiguration WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(200); Serial.print("."); } Serial.println("Mit dem WLAN verbunden!"); Serial.println(); wifiClient.setInsecure(); // sichere Verbindung wird nicht überprüft oled.print("Netzwerk hergestellt"); delay(100); // Luftfeuchtigkeits-Sensor dht.begin(); //DHT22 Sensor starten // CO2-Sensor softwareSerial.begin(9600); sensor.begin(&softwareSerial); sensor.setMeasuringRange(Mhz19MeasuringRange::Ppm_5000); sensor.enableAutoBaseCalibration(); Serial.println("Preheating..."); // Preheating, 3 minutes oled.println("Vorheizen..."); while (!sensor.isReady()) { delay(100); Serial.print("."); oled.print("."); } oled.clear(); delay(50); } void loop() { luftfeuchtigkeit = dht.readHumidity(); temperatur = dht.readTemperature(); carbonDioxide = sensor.getCarbonDioxide(); oled.clear(); oled.print("CO2: "); oled.println(carbonDioxide); oled.print("Feuchte: "); oled.println(luftfeuchtigkeit); oled.print("Temperatur: "); oled.println(temperatur); // für das Internet String Str_luftfeuchtigkeit =String(luftfeuchtigkeit); String Str_temperatur =String(temperatur); String Str_carbonDioxide =String(carbonDioxide); //GET Data + Link String getData = "?wert1=" + Str_carbonDioxide +"&wert2="+Str_luftfeuchtigkeit+"&wert3="+ Str_temperatur + "&beschreibung=2022_10_05"; String Link = "https://www.info-checker.de/raumklima/einlesen.php"; Link = Link + getData; // Serial.println(Link); if (sender.begin(wifiClient, Link)) { int httpCode = sender.GET(); if (httpCode > 0) { if (httpCode == 200) { String antwort = sender.getString(); Serial.println(antwort); }else{ Serial.print("HTTP-Error: " + String(httpCode)); } } sender.end(); }else { Serial.printf("HTTP-Verbindung konnte nicht hergestellt werden!"); } delay(5*60*1000); // alle 5 Minuten }
PHP - einlesen
<?php // Datenbankkonfiguration: Anpassen $servername = "localhost"; $dbname ="datenbankname"; $username = "username"; $password="passwort"; $pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // GET Werte einlesen und auf Gültigkeit überprüfen if(isset($_GET['wert1'])&& is_numeric($_GET['wert1'])){ $wert1 = $_GET['wert1'];} else { $wert1 ="-------"; } if(isset($_GET['wert2'])&& is_numeric($_GET['wert2'])){ $wert2 = $_GET['wert2'];} else { $wert2 ="-------"; } if(isset($_GET['wert3'])&& is_numeric($_GET['wert3'])){ $wert3 = $_GET['wert3'];} else { $wert3 ="-------"; } if(isset($_GET['beschreibung'])&& strlen($_GET['beschreibung'])<20){ $beschreibung = preg_replace('/\s+/', '', $_GET['beschreibung']);} else { $beschreibung ="-------"; } // Eintrag in die Datenbank // $sql ="INSERT INTO `messwerte` (`id`, `wert1`, `wert2`, `wert3`, `beschreibung`, `zeit`) VALUES (NULL, '".$wert1."', '".$wert2."', '".$wert3."', '".$beschreibung."', CURRENT_TIMESTAMP);"; $pdo->query($sql); ?> <!DOCTYPE html> <html lang="de"> <head> </head> <body> <h1>Werte in Datenbank eingetragen.</h1> <ul> <li> Wert1: <?php echo $wert1; ?></li> <li> Wert2: <?php echo $wert2; ?></li> <li> Wert3: <?php echo $wert3; ?></li> <li> Beschreibung: <?php echo $beschreibung; ?></li> <li> info: <?php echo $info; ?></li> <li> zeit: <?php echo $zeit; ?></li> </ul> </body> </html>
PHP auslesen und darstellen
<?php // Datenbankkonfiguration: Anpassen $servername = "localhost"; $dbname ="datenbankname"; $username = "username"; $password="passwort"; $pdo = new PDO("mysql:host=$servername;dbname=$dbname", $username, $password); // es wird eine Liste der Messreihen erzeugt, die angezeigt werden sollen $sql ="SELECT DISTINCT `beschreibung` FROM `messwerte` "; $auswahl=""; foreach ($pdo->query($sql) as $row) { // defaultwert der Messreihen $auswahl = $auswahl."'".$row['beschreibung']."',"; } $auswahl = substr($auswahl, 0, -1); // Liste aller möglichen Messreihen // GET einlesen // werden welche über GET angefordert, so werden nur diese aus der Liste ausgewählt $alle_messreihen = $auswahl; if(isset($_GET['beschreibung']) && $_GET['beschreibung'] !="") { $beschreibung = $_GET['beschreibung']; $auswahl=""; foreach ($beschreibung as $value) { $pos = strpos($alle_messreihen, $value); if ($pos >0){ $auswahl = $auswahl."'".$value."',"; } } $auswahl = substr($auswahl, 0, -1); // Liste der angeforderten Messenreihen } else { $beschreibung =""; } // Für welchen Zeitraum sollen die Messwerte angezeigt werden? // default: die letzten 5 Tage if(isset($_GET['stopzeit'])&& $_GET['stopzeit'] !="") {$stopzeit= $_GET['stopzeit'];} else { $stopzeit = date('Y-m-d H:i'); // aktuelle Uhrzeit } if(isset($_GET['startzeit']) && $_GET['startzeit'] !="") {$startzeit= $_GET['startzeit'];} else { $startzeit = date("Y-m-d H:i", mktime(date("H"), date("m"), 0, date("m") , date("d")-5,date("Y"))); } ?> <!doctype html> <html lang="de"> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1"> <meta name="description" content=""> <title>Messwerte</title> <link href="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-EVSTQN3/azprG1Anm3QDgpJLIm9Nao0Yz1ztcQTwFspd3yD65VohhpuuCOmLASjC" crossorigin="anonymous"> <script src="https://cdn.jsdelivr.net/npm/bootstrap@5.0.2/dist/js/bootstrap.bundle.min.js" integrity="sha384-MrcW6ZMFYlzcLA8Nl+NtUVF0sA7MsXsP1UyJoMp4YLEuNSfAP+JcXn/tWtIaxVXM" crossorigin="anonymous"></script> <script type="text/javascript" src="https://www.gstatic.com/charts/loader.js"></script> <style><!-- eigene Styles --> #suchformular, #kontakt{ min-height: 100vh; } #schaubild_wert1, #schaubild_wert2, #schaubild_wert3, #tabelle, #suchformular, #kontakt { padding-top:55px; } .formular { width: 600px; background-color: #ddd; padding: 20px; } </style> </head> <body> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <div class="container-fluid"> <a class="navbar-brand" href="https://www.info-checker.de/raumklima2/index.php#top">Messwerterfassung</a> <button class="navbar-toggler" type="button" data-bs-toggle="collapse" data-bs-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation"> <span class="navbar-toggler-icon"></span> </button> <div class="collapse navbar-collapse" id="navbarCollapse"> <ul class="navbar-nav me-auto mb-2 mb-md-0"> <li class="nav-item"><a class="nav-link zumachen" href="#schaubild_wert1">CO2</a></li> <li class="nav-item"><a class="nav-link zumachen" href="#schaubild_wert2">Luftfeuchtigkeit</a></li> <li class="nav-item"><a class="nav-link zumachen" href="#schaubild_wert3">Temperatur</a></li> <li class="nav-item"><a class="nav-link zumachen" href="#tabelle">Tabelle</a></li> <li class="nav-item"><a class="nav-link zumachen" href="#suchformular">Auswählen</a></li> </ul> <ul class="nav navbar-nav navbar-right"> <li class="nav-item"><a class="nav-link zumachen" href="#kontakt"><span class="glyphicon glyphicon-user"></span> Kontakt</a></li> </ul> </div> </div> </nav> <main class="container" id="top" style=" padding-top: 55px;"> <!-- die folgenden (inneren) 3 div-Container (schaubild_wert#) werden (von Javascript) mit den Schaubilder gefüllt --> <h2>Schaubilder:</h2> <div class="row"> <div class="col"> <div id="schaubild_wert1"></div> </div> </div> <div class="row"> <div class="col"> <div id="schaubild_wert2"></div> </div> </div> <div class="row"> <div class="col"> <div id="schaubild_wert3"></div> </div> </div> <?php // `wert1` NOT LIKE '-1' zeigt eine fehlerhafte Messung der CO2- Konzentration an // Auswahl nach der auswahl Liste und Zeitraum mit maximal 1000 Werten $sql ="SELECT * FROM `messwerte` WHERE (`wert1` NOT LIKE '-1' and `beschreibung` IN (".$auswahl.")) and (`zeit` BETWEEN '".$startzeit."' AND '$stopzeit') ORDER BY `id` DESC LIMIT 1000"; $google_chart_string_wert1 = ""; $google_chart_string_wert2 = ""; $google_chart_string_wert3 = ""; foreach ($pdo->query($sql) as $row) { $jahr = substr($row['zeit'],0,4); $monat =substr($row['zeit'],5,2)-1; $tag = substr($row['zeit'],8,2); $stunde = substr($row['zeit'],11,2); $minute = substr($row['zeit'],14,2); $sekunde = substr($row['zeit'],17,2); $google_chart_string_wert1= $google_chart_string_wert1."[new Date('".$jahr."','".$monat."','".$tag."','".$stunde."','".$minute."','".$sekunde."'),".$row['wert1']."],\n"; $google_chart_string_wert2= $google_chart_string_wert2."[new Date('".$jahr."','".$monat."','".$tag."','".$stunde."','".$minute."','".$sekunde."'),".$row['wert2']."],\n"; $google_chart_string_wert3= $google_chart_string_wert3."[new Date('".$jahr."','".$monat."','".$tag."','".$stunde."','".$minute."','".$sekunde."'),".$row['wert3']."],\n"; } $google_chart_string_wert1 = substr($google_chart_string_wert1,0,-2); $google_chart_string_wert2 = substr($google_chart_string_wert2,0,-2); $google_chart_string_wert3 = substr($google_chart_string_wert3,0,-2); ?> <!-- GOOGLE CHART--> <script type="text/javascript"> google.charts.load('current', {'packages':['corechart']}); google.charts.setOnLoadCallback(drawChart_wert1); google.charts.setOnLoadCallback(drawChart_wert2); google.charts.setOnLoadCallback(drawChart_wert3); function drawChart_wert1() { var data = new google.visualization.DataTable(); data.addColumn('datetime', 'Time of Day'); data.addColumn('number', 'CO2 in ppm'); data.addRows([ <?php echo $google_chart_string_wert1;?> ]); var options = { title: 'Luftqualität: CO2 - Gehalt', height: 500, hAxis: { gridlines: { count: -1, units: { days: {format: ['dd.MMM']}, hours: {format: ['HH:mm']}, } }, minorGridlines: { units: { hours: {format: ['HH:mm']}, minutes: {format: ['HH:mm']} } } } , vAxis: { gridlines: {color: 'none', count: 5}, minValue: 0 } }; var chart = new google.visualization.LineChart(document.getElementById('schaubild_wert1')); chart.draw(data, options); } function drawChart_wert2() { var data = new google.visualization.DataTable(); data.addColumn('datetime', 'Time of Day'); data.addColumn('number', 'Feuchtigkeit in %'); data.addRows([ <?php echo $google_chart_string_wert2;?> ]); var options = { title: 'Luftqualität: Luftfeuchtigkeit', height: 500, hAxis: { gridlines: { count: -1, units: { days: {format: ['dd.MMM']}, hours: {format: ['HH:mm']}, } }, minorGridlines: { units: { hours: {format: ['HH:mm']}, minutes: {format: ['HH:mm']} } } } , vAxis: { gridlines: {color: 'none', count: 5}, minValue: 0 }}; var chart = new google.visualization.LineChart(document.getElementById('schaubild_wert2')); chart.draw(data, options); } function drawChart_wert3() { var data = new google.visualization.DataTable(); data.addColumn('datetime', 'Time of Day'); data.addColumn('number', 'Temperatur'); data.addRows([ <?php echo $google_chart_string_wert3;?> ]); var options = { title: 'Luftqualität: Temperatur', height: 500, hAxis: { gridlines: { count: -1, units: { days: {format: ['dd.MMM']}, hours: {format: ['HH:mm']}, } }, minorGridlines: { units: { hours: {format: ['HH:mm']}, minutes: {format: ['HH:mm']} } } } , vAxis: { gridlines: {color: 'none', count: 5}, minValue: 0 } }; var chart = new google.visualization.LineChart(document.getElementById('schaubild_wert3')); chart.draw(data, options); } </script> <!--ende google chart --> <h2 id="tabelle">Messwerte:</h2> <?php // im folgenden wird eine Tabelle aller angeforderten Messwerte erzeugt echo "<table class=\"table table-striped table-bordered\">"; echo "<tr><th>id</th><th>Wert 1 </th><th> Wert 2 </th><th> Wert 3 </th><th> Beschreibung </th><th> Zeit</th></tr>\n"; foreach ($pdo->query($sql) as $row) { echo "<tr>"; echo "<td> ".$row['id']."</td>"; echo "<td>".$row['wert1']."</td>"; echo "<td>".$row['wert2']."</td>"; echo "<td>".$row['wert3']."</td>"; echo "<td>".$row['beschreibung']."</td>"; echo "<td>".$row['zeit']."</td>"; echo "</tr>\n"; } echo "</table>"; ?> <div id="suchformular"> <div class="formular"> <form name="Messung" method="GET" action=""> <h3>Messdatenabfrage:</h3> <div class="row p-1"> <div class="col"> <label for="startzeit" class="form-label">Start:</label> <input type="datetime-local" id="startzeit" name="startzeit" value="<?php echo $startzeit;?>"> </div> <div class="col"> <label for="stopzeit" class="form-label">Stop:</label> <input type="datetime-local" id="stopzeit" name="stopzeit" value="<?php echo $stopzeit;?>"> </div> </div> <div class="row p-1"> <div class="col"> <label for="beschreibung">Messdatenreihe: (Mehrauswahl möglich)</label> <select name="beschreibung[]" id="beschreibung" class="form-control" multiple> <?php $sql ="SELECT DISTINCT `beschreibung` FROM `messwerte` "; foreach ($pdo->query($sql) as $row) { echo"<option value=\"".$row['beschreibung']."\">".$row['beschreibung']."</option>"; } ?> </select> </div> </div> <div class="row p-3"> <div class="col"> <button type="reset" class="btn btn-primary">Zurücksetzen</button> </div> <div class="col"> <button type="submit" class="btn btn-primary">Absenden</button> </div> </div> </form> </div> <!-- ende div formular--> </div> <!-- ende id suchformular --> <div style="min-height:100vh;" id="kontakt"> <div class="jumbotron"> <h1>Klaus Hirling</h1> </div> </div> </main> <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.6.1/jquery.min.js" integrity="sha512-aVKKRRi/Q/YV+4mjoKBsE4x3H+BkegoM/em46NNlCqNTmUYADjBbeNefNxYV7giUp0VxICtqdrbqU7iVaeZNXA==" crossorigin="anonymous" referrerpolicy="no-referrer"></script> <script> $('.zumachen' ).click(function() { $('#navbarCollapse').collapse('hide'); }); </script> </body> </html>