Mrz 162011
 

Überwachung der Wassertemperatur eines Aquariums mit ARDUINO und LM 35 Temperatur-Sensor. Datenspeicherung in einer MySQL-Datenbank unter Zuhilfenahme von PHP,  sowie Visualisierung der Daten im Webbrowser mit JpGraph.

 

Verwendete Hardware:

  • Arduino
  • Ethernet Shield
  • LM35 Temperatur-Sensor

Benötigte Software:

  • Web-Server mit PHP und MySQL
  • JPGRAPH

 

MySQL

Zum Anlegen der Datenbank braucht man natürlich seine Daten zum Webspace. Wer (so wie ich) noch nie eine solche Datenbank selber „von Hand“ (mit phpMyAdmin) angelegt hat, sollte einen Blick auf die Links unten werfen. Nach dem verlinkten Tutorial habe ich folgende Datenbank mit entsprechenden Feldern erzeugt:

 

Arduino

Für das Arduino-Board habe ich ein Beispiel-Code aus dem Internet verwendet und diesen modifiziert (siehe Links). Der Wert des Temperatur-Sensors wird alle 15 Minuten ausgelesen und übertragen. Hierzu wird per Ethernet-Shield ein auf dem Webspace gespeichertes PHP-Skript aufgerufen. Der Wert wird einfach in der „Adresszeile“ mit übergeben. Arduino macht also das gleiche, was man im Browser durch Aufruf der URL

www.EigenerServer.de/Arduino_push_data.php?TEMP=20&KEY=XXXXX

bewirkt. Das ist hier auch schon alles. Alles Weitere übernimmt PHP.

 

PHP

Das angesprochene PHP-Skript „Arduino_push_data.php“ steckt die zusätzlich erhaltenen Daten in zwei Variablen („TEMP“ & „KEY“). Der Inhalt in „KEY“ wird mit einem im Quellcode enthaltenen Wert verglichen. Sind die Kennwörter identisch wird eine Verbindung zur Datenbank geöffnet und der Wert aus „TEMP“ ins gleichnamige Feld eingetragen. Die Felder „ID“ und „DATE“ werden automatisch gefüllt. ID zählt um Eins hoch (durch die Option „auto_increment“ in MySQL; bei „DATE“ wird der Befehl „now();“ zur Hilfe genommen. Dieser übernimmt die Zeit des Servers für den Datenbankeintrag.

Außerdem ist im Skript eine kleine Datenausgabe des aktuellsten Wertes integriert. Ruft man das PHP-Skript ohne den Zusatz „?TEMP=20……“ auf, erhält man diese Ausgabe.

Die Zugangsdaten für die MySQL-Datenbank sind zudem noch ausgelagert. Durch „include(„db.php“);“ wird eine weitere, kleine PHP-Datei integriert.

An dieser Stelle ist alles getan, um Werte zu erfassen. Diese können wie beschrieben (aktueller Wert), oder durch das phpMyAdmin-Interface (alle Werte) jederzeit kontrolliert werden.

Kleiner Hinweis noch, welcher mir beim Löschen von Werten in der Datenbank aufgefallen ist:

Löscht man einzelne, mehrere oder alle Datensätze von Hand, muss der Wert für „auto_increment“ ebenfalls zurück gesetzt werden. Andernfalls wird einfach weitergezählt. Ändern kann man diesen unter „Operationen“ -> „Tabellenoptionen“.

 

VISUALISIERUNG

Um die Werte nun ohne eine nötige Anmeldung an phpMyAdmin und vor allem übersichtlicher darzustellen habe ich ein wenig recherchiert und mich dann am Ende für JPGRAPH entschieden. Die Möglichkeiten sind vielfältig, das Handling recht einfach. Bis mein Diagramm dann aber so war, wie ich es gerne haben wollte, vergingen aber auch ein paar Stunden.

Um JPGRAPH nutzen zu können wird das heruntergeladene Verzeichnis einfach in einen Unterordner auf den Server entpackt. Der gewählte Pfad wird dann einfach in der PHP-Datei verlinkt. Apropos PHP-Datei. Diese wird ebenfalls auf dem Server gespeichert. Meine habe ich „show_data.php“ genannt. Sie kann dann einfach in eine vorhandene Webseite eingebunden werden:

<img src="show_data.php" alt="Diagramm wird geladen..." align="middle" width="800" height="500">

 

ERGEBNIS

Weiter möchte ich an dieser Stelle nicht auf die einzelnen Dateien eingehen. Mit ein wenig Fleiß kommt man schnell zu diesem Ergebnis. Schließlich habe ich es ja auch hinbekommen 😉 Kleiner Tipp: Ich habe meine Dateien unten angehängt.

LINKS zum Projekt:

gute MySQL und PHP – Seite

Arduino Code LM35 (aus dem Netz)

PHP Tutorial

JPGRAPH – Most powerful PHP-driven Charts – Herstellerseite

JPGRAPH – Einführung – in Deutsch

Arduino-Datei:

Arduino-Code

PHP-Dateien auf dem Webspace:

arduino_push_data.php

db.php

show_data.php

  16 Responses to “Arduino Daten-Logger (MySQL/PHP)”

  1. Super Darstellung des gesamten Projektes.
    Vielen Dank für Deine Arbeit.

  2. Hi,

    wenn ich die PHP Skripte ausführe bekomme ich fast überall folgend oder ähnliche Meldungen.

    Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in C:\wamp\www\temperatur\db.php on line 2

    gibt es schon angepasste skripte? liegt wohl an der PHP 5 Version

    Gruß
    Martin

  3. Moin. Danke für dieses gute Tutorial. Mit Hilfe dessen kann ich endlich sehen wann der Winter da ist 😉

    http://erstkun.de/298368712579/wxindex.php

  4. Hallo Poldi,

    hab’s gerade mal nachgebaut und muss sage, tolle Vorlage die Du uns hier zur Verfuegung gestellt hast. Und vielen Dank auch an Eike fuer den korrigierten Source.

    Wer den von Eike korrigierten Source per copy&paste verwenden will, dort werden – zumindest war das bei mir so – nach dem paste die sogenannten Anfuehrungszeichen falsch dargestellt, was aber kaum auffaellt. Ich habe diese dann manuell kurz neu gesetzt und das war’s auch schon …

    Bei mir steuert die Schaltung eine Klimaanlage, wurde also noch um zwei Relais erweitert.

    Gruss

    Guenther,
    Davao City, Philippines, Planet Earth, 25.0 °C

    PS: Mit 25.0 °C ist das heute ’saukalt‘ hier …

  5. Hallöchen,
    habe da doch nochmal eine Frage bezüglich jpgraph.
    Ist es möglich auch eine Zeitspanne in der X-Achse anzuzeigen?
    Ich speichere alle 5min die Temperatur, das möchte ich Anzeigen, aber nur von 7:00 bis 20:00 Uhr.
    Was muss ich wo eintragen, ich möchte nicht die Temperatur jede Stunde anzeigen, wie jetzt ist.
    Sondern alle 5min in der Zeit von 7:00Uhr bis 20:00Uhr.

    Ich hoffe Ihr versteht was ich meine.

    Gruß
    Stefan

  6. Hiho, erst mal geil das du das alles online stellst..
    ich habe folgendes problem, die db.php und die arduino_push_date.php geben beide keine fehler aus. aber ich bekomme keine daten in die mysql Datenbank, habe den benutzer arduino genannt, passwort gesetzt aber es geht nichts ;(

    hast du ne ahnung woran das liegen kann?
    lg Andi

  7. Ich verstehe das mit der Server IP nicht ganz.
    Wie komme ich an diese? Ich habe eine eigene Website online und wollte dort meine Daten speichern.
    Wenn ich nun mit nslookup die IP der Website ermittle und diese in den Browser eingebe, erscheint aber nicht meine Website sondern der Server bei dem meine Website neben vielen anderen gehostet ist.

    Kannst Du mir also bitte erklären welche IP ich da genau angeben muss?

  8. Ein kurzer Hinweis an alle, die Probleme beim Kompilieren haben. Dies kann daran liegen, dass die Client Klasse in EthernetClient umbenannt wurde. Demnach sieht der Quellcode für den Arduino (getestet am Arduino Ethernet, openSuse 12.1 mit Arduino 1.0) folgendermaßen aus:

    /*

    #####################################
    # Poldis Aquarium-Temperatur-Logger #
    #####################################

    Hardware:
    ———
    – Arduino Diecimila mit ATMEGA168
    – LM35 Temperatur-Sensor (an Analog 0)
    – Taster an Digital 2

    Funktionen:
    ———–
    Wird der Taster gedrückt, liest Arduino die Temperatur des Sensors und überträgt den
    Wert per Ethernet-Shield in eine mySQL-Datenbank.
    Hierzu enthält die angegebenen URL ein PHP Skript, welches die Daten per GET-Befehl
    übernimmt und in die Datenbank einträgt.

    Versionsinfo:
    ————-
    AutoSend = Keine Abfrage des Tasters
    sendet alle 15 Minuten einen Wert in die Datenbank

    Bitte unbedingt IP Adressen anpassen!

    */

    #include
    #include

    byte mac[] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 }; // MAC-ADRESSE eingeben!
    byte ip[] = { 192, 168, 178, 2 }; // IP-Adresse eingeben!
    byte gateway[] = { 192, 168, 178, 1 }; // Gateway eingeben!
    byte subnet[] = { 255, 255, 255, 0 };
    byte server[] = {192, 168, 1, 39}; // IP des Servers eingeben
    EthernetClient client;
    char host[] = „domain_eingeben.de“; // DOMAIN eingeben!
    char url[] = „/DeineDatei.php“; // Pfad zur PHP-Datei eingeben
    char key[] = „Kennwort_eingeben“; // Kennwort aus PHP-Datei eingeben
    char c;

    int Sensor = 0; // LM35
    int PowerLED = 3; // Power LED
    float Temperatur = 0; // Variable für Temperatur 😉
    int temp = 0; // Analog-Wert

    void setup()
    {
    pinMode(PowerLED, OUTPUT);
    Serial.begin(9600); // für Debug-Ausgaben
    Serial.println(„Programm gestartet…“);
    digitalWrite(PowerLED, HIGH);
    Ethernet.begin(mac, ip, gateway, subnet);
    delay(5000); // warten, bis LAN gestartet
    }

    void loop()
    {
    digitalWrite(PowerLED, LOW);
    Sensor_lesen();
    Daten_senden();
    delay(900);
    digitalWrite(PowerLED, HIGH);

    if (client.available())
    {
    char c = client.read();
    Serial.print(c);
    }
    delay(899000);
    client.stop();
    client.flush();
    }

    void Sensor_lesen()
    {
    temp = analogRead(Sensor); // Analog-Wert auslesen
    Temperatur = (5.0 * temp * 100.0)/1024.0; // Berechnung der Temperatur in °C
    Serial.print(„Temperatur: „);
    Serial.println(Temperatur);
    }

    void Daten_senden()
    {
    if (client.connect(server, 80)) // Verbindung zum Server aufbauen
    {
    Serial.print(„Verbunden…sende Daten…“);
    client.print(„GET „);
    client.print(url);
    client.print(„?TEMP=“);
    client.print(Temperatur);
    client.print(„&key=“);
    client.print(key);
    client.println(“ HTTP/1.1″);
    client.print(„Host: „);
    client.println(host);
    client.println();
    Serial.println(„fertig!“);
    }
    else
    {
    Serial.println(“ ***** VERBINDUNGSAUFBAU NICHT MÖGLICH *****“);
    }
    }

  9. hmmmm der arduino code klappt nicht (mehr?)

    es kommt folgende fehlermeldung


    BarometricPressureWebServer:38: error: no matching function for call to 'Client::Client(IPAddress [4], int)'
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:7: note: candidates are: Client::Client()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:7: note: Client::Client(const Client&)
    BarometricPressureWebServer:38: error: cannot declare variable 'client' to be of abstract type 'Client'
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:7: note: because the following virtual functions are pure within 'Client':
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:12: note: virtual size_t Client::write(uint8_t)
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:13: note: virtual size_t Client::write(const uint8_t*, size_t)
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:14: note: virtual int Client::available()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:15: note: virtual int Client::read()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:17: note: virtual int Client::peek()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:18: note: virtual void Client::flush()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:10: note: virtual int Client::connect(IPAddress, uint16_t)
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:11: note: virtual int Client::connect(const char*, uint16_t)
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:16: note: virtual int Client::read(uint8_t*, size_t)
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:19: note: virtual void Client::stop()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:20: note: virtual uint8_t Client::connected()
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:21: note: virtual Client::operator bool()
    BarometricPressureWebServer.cpp: In function 'void Daten_senden()':
    BarometricPressureWebServer:87: error: no matching function for call to 'Client::connect()'
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:10: note: candidates are: virtual int Client::connect(IPAddress, uint16_t)
    C:\Users\sm\Desktop\arduino-1.0\hardware\arduino\cores\arduino/Client.h:11: note: virtual int Client::connect(const char*, uint16_t)

  10. Hallo… erst mal vielen Dank für die super Beschreibung.
    Ich hätte noch ne frage. Ich hab einen Webspace mit Mysql, php etc.
    Wie kann ich mich mit dem Arduino mit diesem Server verbinden? Bekomme immer keine Verbindung möglich. Und auch wenn ich im Browser: http://www.EigenerServer.de/Arduino_push_data.php?TEMP=20&KEY=XXXXX … mit meinen Daten eingebe wird nichts in die Datenbank geschrieben. Bekomme es einfach nicht auf die Reihe und habe keinen Ansatz.

    Vielen Dank u mfG,
    Lorenz

  11. @Poldi: wie wäre es mit einem arduino mit GPRS und GPS Shield (z.B. im Auto) welches per GPRS die aktuellen Standortdaten schickt an eine db schickt. wäre ja eine nette idee, oder?

  12. Vorbildlich dokumentiert und dargestellt! Danke, H.

  13. Hallo,

    es natürlich immer schwer per Ferndiagnose zu sagen woran es liegt. Wenn das Board aber nicht via ping erreichbar ist, würde ich da ansetzen. Immer Stück für Stück probieren. Klappen denn die Ethernet-Beispiele, die in der Arduino IDE dabei sind? Ideal für dieses Vorhaben ist das Beispiel, in dem Arduino auf Google zugreift. Wenn das klappt, ist man doch schon ganz weit (LAN und Internetzugriff getestet).
    Dann empfehle ich noch, das PHP-Skript von Hand (per Browseraufruf) zu testen. Wenn das geht, muss es auch mit Arduino funktionieren.

    Viel Glück!

  14. Hi,

    ich versuche etwas ähnliche zuhause nach zustellen ich habe meinen Code mit deinem vergliche und die Ethernet Sachen sind fast gleich. Ich kann das arduino aber nicht an-pingen wenn ich die MAC benutze die auf dem Shild steht. Nutze ich irgend eine die ich im netz gefunden habe geht es. Aber die Daten werden dann auch nicht in die DB geschrieben.
    Ich lasse mir die ganzen Sache auch per serial Print ausgeben und er geht alles durch aber der PHP Code geht nicht raus 🙁
    Muss ich bei der MAC Adresse was besonderes beachten?

    Ich hoffe du kannst mir vielleicht einen kleinen Tipp geben.

    Danke schon mal im Voraus

    Dirk

  15. Es ist der Name der angelegten Tabelle. Vielleicht hilft Ihnen ein MySQL Tutorial (http://de.wikipedia.org/wiki/MySQL)

  16. Ich habe das Setup versucht, aber nicht ganz, dass es funktioniert!

    Was nennen Sie Ihren Tisch in der SQL-Datenbank

Sorry, the comment form is closed at this time.