Archiv der Kategorie: MySQL
Addendum2 zum Tutorial – Speicherung von MySQL DB Werten mit ESP8266
Nachdem ich mich in meinen letzten Blogs intensiv mit dem ESP8266 auseinandergesetzt habe, steht logischerweise eine Erweiterung meines Tutorials zur Speicherung von Messwerten in eine MySQL DB unter Verwendung des ESP8266 an. Das Programm wurde weitestgehend analog dem bisherigen Programm aufgebaut, so dass es relativ einfach zu verstehen sein sollte. Im Programm müssen noch die persönlichen Daten für das WLAN und den Host eingetragen werden.
/* Programm zur Speicherung von Messwerten in einer webbasierten MySQL DB based on standard programs of the ESP8266Wifi library and examples on sparkfun.com */ #include <ESP8266WiFi.h> #define CYCLE 60000 const char* ssid = "hier deine SSID"; const char* password = "und das Passwort des WLANs"; const char* host = "hier deinen Host eintragen"; unsigned long value = 0; unsigned int lastcall = CYCLE; int conn_time; void setup() { Serial.begin(115200); delay(10); // We start by connecting to a WiFi network Serial.println(); Serial.println(); Serial.print("Connecting to "); Serial.println(ssid); WiFi.begin(ssid, password); while (WiFi.status() != WL_CONNECTED) { delay(500); Serial.print("."); conn_time++; if (conn_time > 20) { break; } } if (WiFi.status() == WL_CONNECTED) { Serial.println(""); Serial.println("WiFi connected"); Serial.println("IP address: "); Serial.println(WiFi.localIP()); } else { Serial.println(""); Serial.println("no WiFi connection"); ESP.deepSleep(100000); Serial.println("gone to sleep"); } } void loop() { while (millis() - lastcall < CYCLE) { delay(1); } lastcall = millis(); ++value; Serial.print("connecting to "); Serial.println(host); // Use WiFiClient class to create TCP connections WiFiClient client; const int httpPort = 80; if (!client.connect(host, httpPort)) { Serial.println("connection failed"); return; } // We now create a URI for the request String url = "/w2mysql.php"; url += "?A0="; url += millis(); url += "&A1="; url += value; Serial.print("Requesting URL: "); Serial.println(url); // This will send the request to the server client.print(String("GET ") + url + " HTTP/1.1\r\n" + "Host: " + host + "\r\n" + "Connection: close\r\n\r\n"); delay(1000); // Read all the lines of the reply from server and print them to Serial while (client.available()) { String line = client.readStringUntil('\r'); Serial.print(line); } Serial.println(); Serial.println("closing connection"); }
Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Addendum
In diesem Post fasse ich einige Informationen zusammen, die ich noch loswerden wollte
Addendum1 – Config-file für MySQL Datenbank
Wenn man mit verschiedenen Abfragen einer Datenbank arbeitet und immer wieder die Zugangsdaten eingeben muss, ist das auf Dauer ziemlich nervig. Übersichtlicher ist es dann auch die Zugangsdaten separat in einen File, hier mit dem Namen config.php zuschreiben, der dann in die eigentliche Abfrage included wird.
<?php $mysql_host = "hier Name des Server/Host eintragen"; $mysql_db = "hier Datenbanknamen eintragen"; $mysql_user = "hier MySQL User eintragen"; $mysql_pw = "hier MySQL Passwort eintragen"; ?>
Die Abfrage sieht dann so aus, hier das Beipiel aus Teil 4 zur Abfrage der letzten 20 Datensätze, Zusätzlich habe ich hier die Tabelle in eine Stringvariable gesetzt. Damit wird der File leichter anpassbar für andere Tabellen.
<?php require ($_SERVER['DOCUMENT_ROOT']."/config.php"); $connection = mysqli_connect($mysql_host, $mysql_user, $mysql_pw, $mysql_db); $mysql_table = "analog_data"; if (!$connection) { echo "Fehler: konnte nicht mit MySQL verbinden." . PHP_EOL; echo "Debug-Fehlernummer: " . mysqli_connect_errno() . PHP_EOL; echo "Debug-Fehlermeldung: " . mysqli_connect_error() . PHP_EOL; exit; } /* Select queries return a resultset */ $abfrage = "SELECT datum, analog0, analog1 FROM analog_data ORDER BY datum DESC LIMIT 20"; $result = $connection->query($abfrage); if (!$result) { echo "Verbindung zur Datenbank fehlgeschlagen"; exit; } while ($row = mysqli_fetch_array($result)) { echo $row['datum'].",".$row['analog0'].",".$row['analog1']."<br>"; } ?>
Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Teil 5
Teil 5 – CSV und MySQL Daten grafisch präsentieren
Bei der Recherche, wie MySQL Daten einfach und dennoch wirkungsvoll grafisch zu präsentieren sind, habe ich mir viele Möglichkeiten angesehen. Letztendlich habe ich mich dann für dygraphs entschieden, weil diese JavaScript Library viele Möglichkeiten bietet und die Dokumentation und das Tutorial gut verständlich sind.
Um die Library einzusetzen muss zunächst der File dygraph-combined.js von der dygraphs Download-Seite geladen werden und im Basisverzeichnis des Webspaces abgelegt werden. Um die Funktionsweise der Library kennenzulernen, möchte ich zunächst zeigen, wie die Daten aus dem csv-File aus dem 3. Teil des Tutorials dargestellt werden können. Dazu erstellen wir auf dem Webspace eine html-Seite, die im Wesentlichen dem Beispiel auf den Dygraphs Seite für csv-Dateien entspricht. Der Name dieser Datei könnte z.B. graphcsv.html sein.
<html> <head> <script type="text/javascript" src="dygraph-combined.js"></script> </head> <body> <div id="graphdiv2" style="width:500px; height:300px;"></div> <script type="text/javascript"> g2 = new Dygraph( document.getElementById("graphdiv2"), "test.csv", // path to CSV file {} // Options ); </script> </body> </html>
Wer jetzt schon einige Daten in seiner csv-Datei hat, sollte nach Aufruf dieser html-Seite jetzt die typische Dygraphs Grafik sehen. Dabei fällt allerdings auf, dass Dygraphs den Unix Timestamp nicht als Datum und Zeit interpretiert. Um das zu ändern, muss entweder die Speicherung der Daten geändert werden oder dem dygraphs-Aufruf eine optionale Funktion mitgegeben werden. Die Option wird in den geschweiften Klammern übergeben, hier der gesamte Funktionsaufruf. Zusätzlich habe ich noch Labels ergänzt.
g2 = new Dygraph( document.getElementById("graphdiv2"), "test.csv", // path to CSV file { xValueFormatter: Dygraph.dateString_, xValueParser: function(x) { return 1000*parseInt(x);}, xTicker: Dygraph.dateTicker, labels: [ "Datum", "A0", "A1" ] } // Options );
Die Darstellung des Datums in der Grafik finde ich aber sehr ungünstig, habe mich aber nicht weiter damit beschäftigt, das zu verändern. Sinnvoller finde ich, die csv-Daten direkt mit einem interpretierbaren Datumsformat zu erzeugen. (Sorry, dass das nicht schon in Teil 3 berücksichtigt wurde). Hier die Änderung der php-Seite zur Ablage der Daten als csv-Datei, im Aufruf der Dygraph Funktion müssen jetzt natürlich die Optionen wieder entfernt werden.
<?php isset($_GET['A0']) ? $a0=$_GET['A0'] : $a0=''; isset($_GET['A1']) ? $a1=$_GET['A1'] : $a1=''; $jetzt = time(); $delimiter = ","; $enclosure = " "; $handle = fopen("./test.csv", 'a'); fputcsv($handle, array(date("Y/m/d H:i:s",$jetzt),$a0,$a1),$delimiter,$enclosure); fclose($handle); ?>
Doch nun zur Darstellung der Daten aus der MySQL Datenbank. Ich habe lange rumprobiert, wie man die Daten aus MySQL in den JavaScript Aufruf einbauen kann. Als Lösung habe ich die Daten innerhalb des JavaScript Aufrufs per php aus der Datenbank gelesen und als Array an die dygraphs Funktion übergeben. Die Daten müssen in genau dieser Form
[ [ new Date("2009/07/12"),100, 200 ], [ new Date("2009/07/19"), 150, 220 ] ]
an dygraphs übergeben werden, deshalb sieht die Formatierung der Daten innerhalb der php-Funktion etwas chaotisch aus (siehe hier).
Folgende php-Seite sollte unter dem Namen graph.php auf dem Webspace erzeugt werden. Natürlich müssen wieder die Zugangsdaten der Datenbank eingetragen werden:
(Update 04/2020 – Umbau auf mysqli)
<html> <head> <body style="color: rgb(0, 0, 0); background-color: rgb(77, 77, 77)" alink="#ee0000" link="#0000ee" vlink="#551a8b"> <div style="text-align: center;"><span style="color: rgb(255, 255, 255);">Daten aus MySQL<br></span> <br> <script type="text/javascript" src="dygraph-combined.js"></script> </head> <body> <table style="margin:0px auto" border="0" width="500" align="center"> <tr> <td style="background-color: #FFFFFF"> <div id="graphdiv2" style="width:500px; height:300px;"></div> <script type="text/javascript"> g2 = new Dygraph(document.getElementById("graphdiv2"), <?php $mysql_host = "hier Name des Server/Host eintragen"; $mysql_db = "hier Datenbanknamen eintragen"; $mysql_user = "hier MySQL User eintragen"; $mysql_pw = "hier MySQL Passwort eintragen"; $connection = mysqli_connect($mysql_host, $mysql_user, $mysql_pw, $mysql_db); $mysql_table = "analog_data"; if (!$connection) { echo "Fehler: konnte nicht mit MySQL verbinden." . PHP_EOL; echo "Debug-Fehlernummer: " . mysqli_connect_errno() . PHP_EOL; echo "Debug-Fehlermeldung: " . mysqli_connect_error() . PHP_EOL; exit; } /* Select queries return a resultset */ $result = $connection->query("SELECT DATE_FORMAT(datum, '%Y/%m/%d %H:%i:%s') AS date, datum, analog0, analog1 FROM ".$mysql_table); echo "["; while($row = mysqli_fetch_array($result)) { //$dcount = $dcount+1; // prepare Dygraph data, each row like this: [new Date("2016/03/31 20:01:57"),37,34], //echo "["."new Date(\"".$row['date']."\")".",".$row['analog0'].",".$row['analog1']."],"; $utime = strtotime($row[datum]); $diffutime = $utime - $lastutime; if ($diffutime > 600) { echo "["."new Date(\"".$row['date']."\")".",NaN,NaN],"; } else { echo "["."new Date(\"".$row['date']."\")".",".$row['analog0'].",".$row['analog1']."],"; } $lastutime = strtotime($row['datum']); } echo "]"; $_SESSION["dcount"] = $dcount; mysqli_close($connection); ?>, {rightGap: 20, connectSeparatedPoints: true, labels: [ "Datum", "A0", "A1" ] } // options ); </script> </div> </td> </tr> </table> <div style="text-align: center;"><span style="color: rgb(255, 255, 255);"> <?php echo "<br>".$_SESSION["dcount"]." Datensätze "; ?> </span> </body> </html>
In der Übergabe des Arrays an die dygraph-Funktion habe ich eine Abfrage eingebaut, die dafür sorgt, dass (zeitliche) Lücken in der Datenreihe nicht als verbundene Punkte dargestellt werden.
Ich hoffe, diese Tutorial hat euch geholfen eure Daten zu speichern und grafisch zu präsentieren. Ich bin gespannt auf euer Feedback und eure Ergebnisse.
Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Teil 4
Teil 4 – Einrichten der MySQL Datenbank und speichern der Daten
In diesem Teil des Tutorials werde ich euch zeigen, wie man vom Arduino erzeugte Daten über Ethernet in einer MySQL Datenbank abspeichert. Eine Datenbank hat gegenüber der im vorherigen Beitrag angelegten csv-Datei viele Vorteile, z.B. dass die Daten bei der Abfrage bereits selektiert werden können (z.B. ein bestimmter Zeitraum) oder sortiert werden können. Ein Abfragebeispiel dazu werde ich in diesem Teil des Tutorials später vorstellen.
Die MySQL Datenbank und die Datentabelle muss zunächst auf dem Webspace angelegt werden, am einfachsten ist das über das Programm phpMyAdmin, dass auf den meisten Webspaces bereits installiert ist. Auf dem Webspace aus dem Teil 2 des Tutorials greift man darauf über die Administration des eigenen Webspaces zu. Dazu loggt man sich ein und wählt im linken Menue meine Projekte und dann das bereits angelegte Projekt. Auf dieser Seite scrollt man ganz nach unten und wählt dann unter Webspace MySQL. Die Zugangsdaten für MySQL werden später im Programm noch verwendet. Wenn noch keine Datenbank angelegt ist, muss man jetzt zunächst eine Datenbank anlegen.
Über den Link zu phpMyAdmin erreichen wir die Administration der Datenbank. Als nächstes legen wir eine Tabelle zur Speicherung der Daten an, Das geht am schnellsten mit einem SQL Statement. Zunächst wählt man links die Datenbank, dann den Reiter SQL und geben folgendes Statement ein
CREATE TABLE IF NOT EXISTS `analog_data` ( `id` int(11) NOT NULL AUTO_INCREMENT, `datum` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, `analog0` int(11) NOT NULL COMMENT 'Analog0', `analog1` int(11) NOT NULL COMMENT 'Analog1', PRIMARY KEY (`id`) )
das wir mit OK bestätigen. Mit diesem Statement wird eine Tabelle mitr dem Namen analog_data mit 4 Feldern (Spalten) angelegt, einer ID, die mit jedem Datensatz automatisch hochzählt, einem Zeitstempel, der bei Erzeugung eines neuen Datensatzes automatisch erzeugt wird und die beiden Messwerte analog0 und analog1.
Wenn keine Fehlermeldung kommt, ist die Tabelle, zunächst leer, jetzt angelegt.
Wie in Teil 3 benötigen wir jetzt zunächst eine php-Webseite die die Daten des Arduino annimmt und dann in der MySQL Tabelle abspeichert. Diese Seite legen wir unter dem Namen data2mysql.php an. Die Zugangsdaten (siehe Webspace Administrationsseite) müssen innerhalb der Anführungsstriche eingetragen werden. Der Name des Servers ($mysql_host) ist im Falle von kilu.de „localhost“.
(Update wegen mysqli 04/2020)
<?php $mysql_host = "hier Name des Server/Host eintragen"; $mysql_db = "hier Datenbanknamen eintragen"; $mysql_user = "hier MySQL User eintragen"; $mysql_pw = "hier MySQL Passwort eintragen"; isset($_GET['A0']) ? $a0=$_GET['A0'] : $a0=''; isset($_GET['A1']) ? $a1=$_GET['A1'] : $a1=''; $connection = mysqli_connect($mysql_host, $mysql_user, $mysql_pw, $mysql_db); $mysql_table = "analog_data"; if (!$connection) { echo "Fehler: konnte nicht mit MySQL verbinden." . PHP_EOL; echo "Debug-Fehlernummer: " . mysqli_connect_errno() . PHP_EOL; echo "Debug-Fehlermeldung: " . mysqli_connect_error() . PHP_EOL; exit; } /* Select queries return a resultset */ $insert_data = "INSERT INTO analog_data (analog0, analog1) VALUES ($a0, $a1)"; if (!$connection->query($insert_data)) { echo "Verbindung zur Datenbank fehlgeschlagen"; exit; ?>
Einen ersten Test können wir wie im 3. Teil auch mit dem direkten Aufruf der Webseite machen, also z.B.: <webspace>/data2mysql.php?A0=123&A1=345
Mit phpMyAdmin kann man jetzt kontrollieren, ob die Werte korrekt übernommen wurden. Nun muss nur noch das Arduino Programm aus Teil 3 auf die neue php-Webseite umgestellt werden, also statt der Zeile
client.print("GET /data2csv.php?A0=");
wird jetzt
client.print("GET /data2mysql.php?A0=");
eingetragen.
Um sich die letzten Daten anzusehen reicht diese einfache php-Webseite, wobei wieder die Zugangsdaten der Datenbank eingetragen werden müssen.
<?php $mysql_host = "hier Name des Server/Host eintragen"; $mysql_db = "hier Datenbanknamen eintragen"; $mysql_user = "hier MySQL User eintragen"; mysql_pw = "hier MySQL Passwort eintragen"; $connection = mysqli_connect($mysql_host, $mysql_user, $mysql_pw, $mysql_db); $mysql_table = "analog_data"; if (!$connection) { echo "Fehler: konnte nicht mit MySQL verbinden." . PHP_EOL; echo "Debug-Fehlernummer: " . mysqli_connect_errno() . PHP_EOL; echo "Debug-Fehlermeldung: " . mysqli_connect_error() . PHP_EOL; exit; } /* Select queries return a resultset */ $abfrage = "SELECT datum, analog0, analog1 FROM analog_data ORDER BY datum DESC LIMIT 20"; $result = $connection->query($abfrage); if (!$result) { echo "Verbindung zur Datenbank fehlgeschlagen"; exit; } while ($row = mysqli_fetch_array($result)) { echo $row['datum'].",".$row['analog0'].",".$row['analog1']."<br>"; } ?>
In dieser Abfrage wird die oben erwähnte Selektion, hier der letzten 20 Datensätze und eine Sortierung angewendet. Im nächsten und letzten Teil des Tutorial beschäftigen wir uns dann mit der grafischen Präsentation der Daten.
Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Teil 3
Teil 3 – Speichern von Daten auf dem Webspace
In diesem Teil des Tutorials werden wir Daten, die der Arduino misst, auf einem Webserver als CSV-Datei ablegen. Wichtig ist dabei zu verstehen, wie Daten an einen Webserver übergeben werden können. In diesem Beispiel nutze ich das HTTP GET Protokoll. Im HTTP GET Protokoll werden die Daten in der Adresszeile des Browsers übergeben. Hier einmal ein einfaches Beispiel: http://erniberni.kilu.de/name.php?Name=Reinhard Der Aufruf übergibt den Parameter Name mit Inhalt Reinhard. Kopier den Link und gibt etwas anderes ein.
Die Datei name.php auf dem Webspace sieht so aus:
<?php isset($_GET['Name']) ? $name=$_GET['Name'] : $name=''; echo "Hallo, guten Tag ".$name; ?>
Das Programm dahinter ist sehr einfach. Wenn der Parameter Name gesetzt ist (isset), dann lade den Parameter in die Variable $name, falls er nicht gesetzt ist, lade die Variable mit einem leeren String.
Ich hoffe damit ist das Prinzip der Datenübergabe klar geworden. Als nächstes wollen wir mit dem Arduino Daten an den Webspace übertragen. Dazu nutzen wir ein Programm, dass ganz ähnlich ist zum WebClock Programm aus dem ersten Teil. Doch zunächst legen wir die php Seite an, die die Daten empfängt. Auf dem Webspace legen wir eine Datei mit dem Namen data2csv.php mit folgendem Inhalt an.
<?php isset($_GET['A0']) ? $a0=$_GET['A0'] : $a0=''; isset($_GET['A1']) ? $a1=$_GET['A1'] : $a1=''; // echo "eingegeben wurde: ".$a0." und ".$a1; //your php code here $jetzt = time(); $handle = fopen("./test.csv", 'a'); fputcsv($handle, array($jetzt,$a0,$a1)); fclose($handle); ?>
Wenn diese Seite mit Parametern für A0 und A1 aufgerufen wird, werden diese Werte mit einem Zeitstempel in eine Datei test.csv auf dem Webspace abgelegt. Über die Browserzeile kann das jetzt schon mal getestet werden. Der Aufruf lautet z.B. <webspace>/data2csv.php?A0=123&A1=345 . Den gespeicherten Inhalt kann man sich ansehen durch Aufruf der Datei auf dem Webspace, also <webspace>/test.csv . Das das keine darstelbare Webseite ist, fragt der Browser, ob die Datei gespeichert oder geöffnet werden soll. Der Inhalt der Datei sollte jetzt z.B. so aussehen:
1399410041,124,345
Der erste Wert ist ein Unix Timecode und steht für die Anzahl der Sekunden seit 1.1.1970 0:00. Weiter geht es jetzt mit dem Arduino Code zur Speicherung der Werte. Im Code muss dann noch die eigene IP-Adresse des Ethernetshield und der Name des Webspaces eingetragen werden.
/* This sketch is based on: Repeating Web client This sketch connects to a web server and makes a request using a Wiznet Ethernet shield. You can use the Arduino Ethernet shield, or the Adafruit Ethernet shield, either one will work, as long as it's got a Wiznet Ethernet module on board. Circuit: * Ethernet shield attached to pins 10, 11, 12, 13 created 19 Apr 2012 by Tom Igoe, modified by Reinhard Nickels 15.02.2014 http://arduino.cc/en/Tutorial/WebClientRepeating This code is in the public domain. */ #include <SPI.h> #include <Ethernet.h> // assign a MAC address for the ethernet controller. // fill in your address here: byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED}; // fill in an available IP address on your network here, // for manual configuration: IPAddress ip(192,168,2,99); // <- hier die IP des Ethernet Shield eintragen // initialize the library instance: EthernetClient client; char server[] = "<name webspace>"; // <- hier Name des Webspaces eintragen unsigned long lastConnectionTime = 0; // last time you connected to the server, in milliseconds boolean lastConnected = false; // state of the connection last time through the main loop const unsigned long postingInterval = 60000; // das ist ein Bug im Beispiel -> http://forum.arduino.cc/index.php/topic,125510.0.html void setup() { // start serial port: Serial.begin(115200); // give the ethernet module time to boot up: delay(1000); // start the Ethernet connection using a fixed IP address and DNS server: Ethernet.begin(mac, ip); // print the Ethernet board/shield's IP address: Serial.print("My IP address: "); Serial.println(Ethernet.localIP()); } void loop() { // if there's incoming data from the net connection. // send it out the serial port. This is for debugging // purposes only: if (client.available()) { char c = client.read(); Serial.print(c); } // if there's no net connection, but there was one last time // through the loop, then stop the client: if (!client.connected() && lastConnected) { Serial.println(); Serial.println("disconnecting."); client.stop(); } // if you're not connected, and ten seconds have passed since // your last connection, then connect again and send data: if(!client.connected() && (millis() > lastConnectionTime + postingInterval)) { httpRequest(); } // store the state of the connection for next time through // the loop: lastConnected = client.connected(); } // this method makes a HTTP connection to the server: void httpRequest() { // if there's a successful connection: Serial.println("try connecting..."); if (client.connect(server, 80)) { Serial.println("connecting..."); // send the HTTP PUT request: client.print("GET /data2csv.php?A0="); client.print(analogRead(A0)); client.print("&A1="); client.print(analogRead(A1)); client.println(" HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Connection: close"); client.println(); // note the time that the connection was made: lastConnectionTime = millis(); } else { // if you couldn't make a connection: Serial.println("connection failed"); Serial.println("disconnecting."); client.stop(); } }
Die Kontrolle der abgelegten csv Datei kann dann wie oben erfolgen. Sehr viel eleganter ist das allerdings, wenn die csv Datei durch den Aufruf einer Webseite angezeigt wird. Dafür legen wir uns eine php Seite, die z.B. unter dem Namen showdata.php an.
<?php // $row = 1; // optional kann durch weglassen der Auskommentierung eine Zeilennummer angezeigt werden. if (($handle = fopen("test.csv", "r")) !== FALSE) { while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) { $num = count($data); // echo "<p> $num Felder in Zeile $row: <br /></p>\n"; // $row++; for ($c=0; $c < $num; $c++) { if ($c < 1) { $datum = date("m.d.y H:i:s", $data[$c]); echo $datum." "; } else { echo $data[$c]." "; } } echo "<br>"; } fclose($handle); } ?>
Diese Seite liest die Datei Zeile für Zeile ein und gibt den Inhalt als Text aus, Das Datum wird dabei in eine lesbare Form umgewandelt. Der Aufruf erfolgt über <webspapce>/showdata.php .
In der nächsten Folge dieses Tutorial geht es dann weiter mit Anlage einer MySQL Datenbank und die Speicherung der Daten darin.
Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Teil 2
Tutorial Teil 2 – Anlegen eines kostenlosen Webspace
Für die Speicherung der Logging Daten benötigen wir einen Server mit Webserver inklusive PHP und MySQL Datenbank. Natürlich kann man sich einen Webserver sehr einfach z.B. auf einem Linux Rechner oder einem RaspberryPi installieren, aber diese Server müssen immer eingeschaltet sein. Als eine reizvolle Alternative gibt es verschiedene Anbieter im Markt, die Webserver mit MySQL kostenlos anbieten. Unter chip.de findet man eine Liste der Anbieter.
Ich habe mir hier den Anbieter kilu.de ausgesucht, weil angeblich werbefrei 10GB Speicherplatz und unlimitierter Traffic versprochen wird. Die Anmeldung verläuft problemlos.
Aktualisierung 17.07.2015 Leider ist kilu.de ab dem 01.08.2015 kostenpflichtig. Die Anleitung gilt sinngemäß natürlich auch für andere Webspaces. Die angegebenen Links auf meinen Webspace bei kilu.de werden deshalb nicht mehr funktionieren.
Die Anmeldung erfordert die Angabe der persönlichen Daten, die sicherlich zu Werbezwecken weiterverwendet werden. Nach Angabe der Daten erhgält man eine Bestätigungmail mit den Zugangsdaten. Bein ersten Login sollte man das Passwort ändern. Man wir zur Eingabe einer Mobilnummer aufgefordert, über die dann ein Bestätigungcode gesendet wird, der eingegeben werden muss.
Als erstes richten wir den Webspace ein, das geht über „neues Projekt“ und „Webspace erstellen“. Nach Angabe von Titel und Beschreibung kann man den Webspace einer Kategorie zuordnen.
Die zuvor gewählte Subdomain wird übernommen. Die Einrichtung des Webspaces dauert bis zu 15 min. Nach kurzer Zeit ist der neue Webspace unter „meine Projekte“ sichtbar. Zur Konfiguration muss man dann ganz nach unten auf die Seite scrollen. Ganz unten findet man dann die Zugangsdaten für FTP und MySQL. Leider ist die Seite doch nicht werbefrei, wie sich jetzt zeigt. Nachdem auch MySQL aktiviert ist, können die Zugangsdaten der Dienste notiert werden. Wir benötigen für FTP: Server, Benutzer, Passwort und für MySQL: Server/Host, Benutzer, Passwort. Insgesamt sind 3 Datenbanken möglich.
Über phpMyAdmin können die Datenbanken und Tabellen sehr einfach gepflegt werden. In einem späteren Tutorial werde ic die Anlage von Tabellen zeigen. Mit einem FTP-Client seiner Wahl kann man sich dann mal ansehen, was schon auf dem Webspace liegt. Man kann natürlich auch seinen Webspace schon mal aufrufen.
Als erstes sollte man sich mal per FTP in das Verzeichnis www eine Datei mit dem Namen phpinfo.php und folgendem Inhalt kopieren
<?php phpinfo(); ?>
Über den Aufruf <webspacename>/phpinfo.php kann man sich dann ansehen, was der Webserver so leistet.
Wer das Beispiel aus Teil 1 des Tutorials zur Ausgabe der Uhrzeit jetzt auf seinem eigenen Webspace anlegen möchte, muss nur eine Datei unter dem Namen clock.php mit folgendem Inhalt in das www Verzeichnis seines Webspaces legen und im Arduino Programm bei char server[]= den Servernamen eintragen.
<?php echo "Es ist ".date('H:i:s'); ?>
Im nächsten Teil dieser Tutorial Reihe (coming soon) geht’s dann weiter mit der Anlage einer Webseite über die ich Daten per Arduino als WebClient ablegen kann.
Tutorial: Speicherung von Arduino Messdaten auf Webserver und deren Darstellung – Teil 1
Einführung
Es ist immer wieder das selbe Problem:
Da entwickelt man ein Program für den Arduino zur Messung von irgendwelchen Daten. Solange der Computer angeschlossen ist, kann man die Daten über die serielle Schnittstelle als Text darstellen. Um diese Daten dann grafisch darzustellen, kann man die Daten z.B. nach Excel kopieren. Das ist aber umständlich und letzendlich nur eine Momentaufnahme der Messung.
Doch was, wenn der Arduino ohne Computer weiter messen soll?
Eine mögliche Lösung wäre die Speicherung der Daten auf einer SD-Karte. Es gibt günstige Shields mit SD Kartenslot und auch das Ethernet Shield hat einen SD Slot. Aber auch hier muss man die Messung unterbrechen und die Daten der SD Karte im Computer weiterverarbeiten.
Das alles ist umständlich und außerdem will ich an meine Daten ohne in der Nähe meines Arduinos zu sein. Die Lösung ist die Speicherung der Daten auf einem Webserver und der Abruf der Daten von irgendeinem Rechner oder Tablett über das Internet.
In diesem Tutorial werde ich in mehreren Schritten zeigen, wie Daten nur von einem Arduino mit Ethernetshield auf einen Webserver abgelegt werden und sich von dort grafisch aufarbeiten lassen. Hier ein kleiner Vorgeschmack was euch in diesem Tutorial erwartet. (edit: leider hat sich der Betreiber funpic.de aufgelöst, der Link funktioniert deshalb nicht mehr. Ich werde das Beispiel in Kürze auf eine andere Webseite nehmen).
Diese Daten liegen auf einem kostenlosen Webspace von Funpic.de . Der Anbieter finanziert sich mit Werbung, die aufpoppenden Fenster muss man leider dafür billigend in Kauf nehmen. In die Messwerte kann man durch Markieren eines Bereiches mit der Maus reinzoomen. Nach dem Durcharbeiten dieses Tutorial bist du in der Lage, deine Daten ebenso darzustellen.
Im ersten Teil dieses Tutorial gehe ich darauf ein, wie Daten vom Arduino mit Ethernetshield an einen Webspace gesendet werden. Im zweiten Teil werden wir dann einen freien Webspace einrichten und eine einfache Webseite anlegen. Im dritten Teil geht es dann um das Ablegen der Messdaten in einer CSV Datei. Der vierte Teil beschreibt die Konfiguration einer MySQL Datei und das Speichern der Daten darin. Im letzten Teil werden wir uns dann mit der grafischen Darstellung der Daten beschäftigen.
Teil 1 – Verbindung mit Webspace
Ich benutze für meine Experimente ein Ethernetshield mit Wiznet Chipsatz, die man inzwischen sehr günstig bekommen kann. Eine genaue Beschreibung findet man hier. Mit diesem Shield kann man die Beispiele aus der Arduino IDE verwenden, z.B. in der Arduino IDE über das Menü. Datei->Beispiele->Ethernet->WebClient. Ich habe dieses Beispiel geringfügig verändert und lade damit die aktuelle Zeit von einer von mir entsprechend vorbereiteten Webseite. Das Beispiel kann so übernommen werden, lediglich die IP des Ethernet Shield muss angepasst werden. Der Arduino verbindet sich mit der Webseite und liest deren Inhalt (in diesem Fall die aktuelle Zeit) und gibt ihn seriell aus. Sicher nichts spektakuläres, aber man könnte damit unter Verwendung des Time Libraries die Uhrzeit stellen und Gangungenauigkeiten ausgleichen. Natürlich geht das auch über NTP, soll aber hier als Beispiel für den Aufruf einer Webseite dienen.
/* WebClock by Reinhard Nickels This sketch connects to a website using an Arduino Wiznet Ethernet shield. Circuit: * Ethernet shield attached to pins 10, 11, 12, 13 based on WebClient (arduino Examples) by David A. Mellis, by Tom Igoe, based on work by Adrian McEwen */ #include <SPI.h> #include <Ethernet.h> // Enter a MAC address for your controller below. // Newer Ethernet shields have a MAC address printed on a sticker on the shield byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED }; char server[] = "rncologne.rn.funpic.de"; // <- wenn du das auf deinem eigenen Server machen willst, muss das hier geändert werden // Set the static IP address to use if the DHCP fails to assign IPAddress ip(192,168,2,99); // <- an dieser Stelle die IP des Ethernet Shield eintragen, ich habe eine feste Adresse vergeben. // Initialize the Ethernet client library // with the IP address and port of the server // that you want to connect to (port 80 is default for HTTP): EthernetClient client; void setup() { // Open serial communications and wait for port to open: Serial.begin(115200); while (!Serial) { ; // wait for serial port to connect. Needed for Leonardo only } // start the Ethernet connection: Ethernet.begin(mac, ip); // give the Ethernet shield a second to initialize: delay(1000); // print the Ethernet board/shield's IP address: Serial.print("My IP address: "); Serial.println(Ethernet.localIP()); Serial.println("connecting..."); // if you get a connection, report back via serial: if (client.connect(server, 80)) { Serial.println("connected"); // Make a HTTP request: client.println("GET /clock.php HTTP/1.1"); client.print("Host: "); client.println(server); client.println("Connection: close"); client.println(); } else { // kf you didn't get a connection to the server: Serial.println("connection failed"); } } void loop() { // if there are incoming bytes available // from the server, read them and print them: if (client.available()) { char c = client.read(); Serial.print(c); } // if the server's disconnected, stop the client: if (!client.connected()) { Serial.println(); Serial.println("disconnecting."); client.stop(); // do nothing forevermore: while(true); } }
Die Ausgabe seriell sieht dann z.B. so aus:
My IP address: 192.168.2.99 connecting... connected HTTP/1.1 200 OK Server: Apache Set-Cookie: notabotxxx=775e1282fb3146e7de81e2f8f769d433; expires=Sun, 11-May-2014 18:31:16 GMT; path=/; domain=.. Vary: Accept-Encoding Content-Type: text/html X-Funpic-Backend-ID: webfree_071 Content-Length: 15 Accept-Ranges: bytes Date: Sun, 11 May 2014 17:31:19 GMT Via: 1.1 varnish Connection: close X-Funpic-ID: 1392478474 X-Funpic-Age: 0 X-Funpic-Host: rncologne.rn.funpic.de X-Funpic-Backend: fp_storage_07 X-Funpic-Cache: MISS Es ist 19:31:16 disconnecting.
Im zweiten Teil dieses Tutorials geht es dann um die Konfiguration eines kostenlosen Webspaces.