Quantcast
Channel: Arduino – Fluuux – TechBlog
Viewing all articles
Browse latest Browse all 40

Arduino, MySQL – Temperatur-Sensoren über Webserver auslesen

$
0
0

In diesem Beitrag zeige ich wie man mit wenigen Mitteln einen Temperaturlogger mit Arduino basteln kann, der die ermittelten Temperaturwerte zweier ds18s20-Temperatursensoren über ein Ethernet-Shield in einer MySQL-Datenbank speichert. Außerdem zeige ich, wie man diese Werte anschließend über eine Website auslesen kann. Wie das Ganze in Aktion aussieht könnt ihr hier sehen. Ich habe für das Diagram die Charting Library von highcharts.com verwendet. Außerdem habe ich die Website über stylesheets  so angepasst dass die Ausgabe auf den verschiedenen Geräten wie PC, Tablet und iPhone angepasst dargestellt wird. Wie man Daten aus einer MySQL-Datenbank mit der HighChart Library als Chart ausgeben kann erfahrt ihr in diesem Beitrag.

12-Stunden-Ansicht als AreaSpline 12-Stunden-Ansicht als Column 12-Stunden-Ansicht als Spline 7-Tage-Ansicht als Spline Aktuelle Temperatur-Ansicht Pin-Belegung des DS1820 Temperatur-Sensors Temperaturlogger-Preview

Ich werde das ganze hier in mehrere Teile gliedern. Im ersten Teil zeige ich wie man die zwei Temperatursensoren mit dem Arduino verbindet und wie man den Arduino so programmiert, dass dieser die ermittelten Temperaturwerte in einem bestimmten Interval an ein php-Script übergibt. Im zweiten Teil erstellen wir die benötigte MySQL-Datenbank in der die Temperaturwerte gespeichert werden und das php-Script das durch den Arduino aufgerufen wird und das dafür zuständig ist, die vom Arduino übergebenen Temperaturwerte in der zuvor erstellten MySQL-Datenbank abgelegt  werden. Teil 3 enthält zwei kleine php-Scripts mit denen man die zuletzt gespeicherten Temperaturwerte und die Werte der letzten 12 Stunden gezielt wieder auslesen kann.

benötigte Hardware

  • 1 x Arduino
  • 1 x Ethernet-Shield
  • 2 x ds1820 Temperatursensoren
  • 1 x 4,7 kOhm Vorwiderstand für den ds18s20
  • 1 x Breadboard

Teil 1

Grundaufbau

Ich denke, hier kann ich mich kurz fassen, da dieses Thema in diesem Blog bereits behandelt wurde. (Arduino – Temperatur auslesen und auf Display ausgeben)
Wenn wir den ds18s20 Temperatursensor so halten, dass wir direkt auf die flache Seite schauen, dann wird das linke Bein mit GND und das rechte Bein mit +5V verbunden. Das rechte Bein, also +5V und das mittlere Bein, das zum digitalen Pin am Arduino geht, verbinden wir über den Vorwiderstand. Das mittlere Bein des ds18s20 wird mit Pin7 am Arduino verbunden. Der zweite Temperatursensor wird einfach dahinter angeschlossen ohne dass ein weiterer Vorwiderstand zum Einsatz kommt.

Pin-Belegung des DS1820 Temperatur-Sensors

Arduino-Sketch

/***************************************************************************************************************************            
  PROJEKT: Temperaturlogger                                                                                                 *
  Beschreibung:  Temperaturwerte von 2 ds1820 Temperatursensoren werden an ein php-Script gesendet,                         *
  dass diese Daten in eine MySQL-Datenbank schreibt,                                                                        *
                                                                                                                            *
                                                                                                                            *
  Folgende Werte müssen angepasst werden                                                                                    *
  --------------------------------------------------------------------------------------------------------------------------*
  Intervall = Zeitraum in welchen Abständen die Temperaturdaten vom Arduino zur Datenbank übertragen werden sollen,         *
  mac[] = MAC-Adresse des Ethernet Shields                                                                                  *
  ip[] = IP-Adresse über die der Arduino erreichbar sein soll.                                                              *
  server[] = IP-Adresse des Servers auf den die Daten übertragen werden sollen. herauszufinden mit ping www.domain.de       *
  host[] = Name der Domain zu der die Verbindung aufgebaut werden soll                                                      *
  url[] = Pfad und Name der Datei die für den Upload der übergebenen Daten zur Datenbank zuständig ist.                     *
  key[] = Kennwort dass mit dem Kennwort in der php-Datei übereinstimmen muss (Sicherheitsaspekt)                           *
*****************************************************************************************************************************/

#include <SPI.h>
#include <Ethernet.h>             // library for ethernet functions
#include <DallasTemperature.h>    // library for temperature sensors
#include <OneWire.h>              // library for the onewire bus

OneWire  ds(7);                         // pin für Temperatursensoren

//DeviceAdressen der einzelnen ds1820 Temperatursensoren.
DeviceAddress sensor1 = { 0x10, 0x98, 0x46, 0x57, 0x2, 0x8, 0x0, 0xF9 };
DeviceAddress sensor2 = { 0x10, 0x59, 0x4B, 0xC0, 0x1, 0x8, 0x0, 0x3E }; 

//ETHERNET-SETTINGS
byte mac[]     = { 0x5D, 0xA2, 0xFA, 0x2D, 0x76, 0x7C };    // MAC-Adresse des Arduino
//byte ip[]      = { 192, 168, 0, 99 };                     // IP-Adresse des Arduino
//byte gateway[] = { 192, 168, 178, 1 };                    // Gateway
//byte subnet[]  = { 255, 255, 255, 0 };                    // SubNet
byte server[]  = { 95, 143, 172, 134 };                     // IP-Adresse des Servers

EthernetClient client;
char host[]    = "ihrewaesche.de";	                    // Domain
char url[]     = "/ARDUINO/Temperatur/SaveTempToMySQL.php"; // Pfad zur PHP-Datei
char key[]     = "MEINPASSWORT123";	                    // Kennwort aus PHP-Datei
char c;                                                     // Variable für Rückgabe des Servers

long Interval  = 60;                                        // Upload-Interval in Minuten
DallasTemperature sensors(&ds);                                
int numSensors;                                             // Variable zum speichern der Anzahl der Temperatur-Sensoren

void setup()
{
  delay(1000);

  Serial.begin(9600); 
  Serial.flush();
  delay(200);

  Serial.println("Arduino TemperaturLogger");
  Serial.println("Ethernet initialisieren...");  

  Ethernet.begin(mac, ip);
  Interval = Interval * 1000 * 60;                            // Das in Minuten angegebene Interval in Millisekunden umrechnen
  delay(1000);	                                              // warten, bis Ethernet gestartet

  //Sensoren abfragen
  sensors.begin();
  Serial.println("Temperatur-Sensoren ermitteln...");

  numSensors = sensors.getDeviceCount();                      // Anzahl der angeschlossenen Sensoren in numSensors speichern

  if(numSensors > 0)                                          // Es wurde mindestens 1 Sensor gefunden                                        
  {
    Serial.print(numSensors);
    Serial.println( " Temperatur-Sensoren gefunden.");
  }          
  else                                                        // Es wurde kein Sensor gefunden
  {
    Serial.println("Keine Temperatur-Sensoren gefunden.");
  }
}

void loop()
{
  float temp1 = getTemperature(sensor1);                      // Temperatur von Sensor 1 ermitteln
  float temp2 = getTemperature(sensor2);                      // Temperatur von Sensor 2 ermitteln

  Serial.print("Temp1: ");
  Serial.println(temp1);
  Serial.print("Temp2: ");
  Serial.println(temp2);

  Daten_senden(temp1, temp2);                                 // Temperaturdaten an Server übertragen

  delay(700);

  byte maxReads = 10;	//Seconds
  while ((maxReads-- > 0) && client.connected())              // Antwort des Servers lesen
  {
    delay(1000);
    while (client.available())
    {
      char response = client.read();
      Serial.print(response);
    }
  }
  client.stop();
  Serial.println("Done.");
  client.flush();

  delay(Interval);
}

/******************************
                              *
  Daten an Server schickenn   *
                              *
*******************************/
void Daten_senden(float T1, float T2)
{
  if (client.connect(server, 80)) // Verbindung zum Server aufbauen
  {
    Serial.println("Verbunden, Sende Daten...");
    client.print("GET " + String(url));
    Serial.println("GET " + String(url));
    client.print("?T1=");
    Serial.print("?T1=");
    client.print(T1);
    Serial.println(T1);
    client.print("&T2=");
    Serial.print("&T2=");
    client.print(T2);
    Serial.println(T2);
    client.print("&key=" + String(key));
    Serial.print("&key=" + String(key));
    client.println(" HTTP/1.1");
    Serial.println(" HTTP/1.1");
    client.print("Host: " + String(host));
    Serial.print("Host: " + String(host));
    client.println();
    Serial.println();
    client.println("User-Agent: Arduino");
    Serial.println("User-Agent: Arduino");
    client.println("Connection: close");
    Serial.println("Connection: close");
    client.println();
    Serial.println();
  }
  else
  {
    Serial.println(" ***** VERBINDUNG KANN NICHT HERGESTELLT WERDEN *****");
  }
}

/*************************************
                                     *
  Temperatur der Sensoren auslesen   *
                                     *
*************************************/
void writeTimeToScratchpad(byte* address)
{
  ds.reset();
  ds.select(address);
  ds.write(0x44,1);
  delay(1000);
}

void readTimeFromScratchpad(byte* address, byte* data)
{
  ds.reset();
  ds.select(address);
  ds.write(0xBE);
  for (byte i=0;i<9;i++)
  {
    data[i] = ds.read();
  }
}

float getTemperature(byte* address)
{
  int tr;
  byte data[12];

  writeTimeToScratchpad(address);

  readTimeFromScratchpad(address,data);

  tr = data[0];

  if (data[1] > 0x80)
  {
    tr = !tr + 1; //two's complement adjustment
    tr = tr * -1; //flip value negative.
  }

   int cpc = data[7];
   int cr = data[6];

   tr = tr >> 1;

   return tr - (float)0.25 + (cpc - cr)/(float)cpc;
}

Bevor Sie dieses Sketch auf Ihren Arduino übertragen, denken Sie bitte daran, folgende Werte anzupassen.

  • Device-Adressen Ihrer ds18s20 Temperatursensoren. (DeviceAdressen ermitteln)
  • MAC-Adresse Ihres Ethernet-Shields.
  • IP des Webservers auf dem die MySQL-Datenbank läuft (kann mit ping www.adresse.de ermittelt werden)
  • host (Name der Domain auf der die MySQL-Datenbank installiert ist)
  • url (Pfad zur Datei SaveTempToMySQL.php)
  • key (Passwort das in der Datei SaveTempToMySQL.php als KEY angegeben wurde)

Die Werte für ip, gateway und subnet habe ich auskommentiert da diese in diesem Beispiel nicht benötigt werden. Wenn wir später einmal über die Website auf den Arduino zugreifen wollen um z.B. gezielt die aktuelle Temperatur anzufordern, brauchen wir die ip des Arduinos die man unter ip definieren kann.

Wenn Sie also alles angepasst und das Sketch zum Arduino übertragen haben, können wir uns an die Programmierung der php-Seite machen, die für das Speichern der Temperaturwerte in der MySQL-Datenbank vorgesehen ist. Am besten erstellen Sie einen neuen Ordner in dem Sie alle Daten die wir für dieses Projekt benötigen ablegen. In meinem Fall heißt der Ordner ARDUINO.

Teil 2

Anlegen der MySQL-Datenbanktabelle

Es gibt verschiedene Wege eine MySql-Datenbanktabelle anzulegen. Hier werde ich den Weg über phpmyadmin gehen da nicht jeder mit dem Terminal vertraut ist.

Öffnen Sie also phpmyadmin auf dem Server und vergewissern Sie sich dass Sie in der richtigen Datenbank sind, falls Sie mehr als eine Datenbank zur Verfügung haben. Sie können nun von Hand eine neue Datenbanktabelle anlegen, indem Sie, je nach phpmyadmin-Version, auf den entsprechenden Link oder Button klicken und anschließend den Namen der neuen Datenbanktabelle eingeben. Alternativ können Sie auch oben auf SQL klicken und  folgendes Script verwenden. Dazu einfach das Script in das Code-Fenster eingeben und auf OK klicken.

CREATE TABLE IF NOT EXISTS `arduino_temperaturen` (
  `id` bigint(11) NOT NULL AUTO_INCREMENT,
  `datumzeit` datetime NOT NULL,
  `temp1` float(10,2) NOT NULL,
  `temp2` float(10,2) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM  DEFAULT CHARSET=latin1 COLLATE=latin1_german2_ci;

SaveTempToMySQL.php

<?php
/***********************************************************************************
  Autor:   Enrico Sadlowski                                                        *
  Kontakt: profwebapps@gmail.com                                                   *
                                                                                   *
  PROJEKT: Arduino-MultiSensor-Temperatur-Ueberwachung                             *
  -------------------------------------------------------------------------------  *
                                                                                   *
  Arduino ruft dieses Script auf, uebergibt Innen- und Aussentemperatur            *
  (TI und TA) sowie einen Key (key), der mit dem hier angegebenen Key              *
  identisch sein muss.                                                             *
  Wenn der Key identisch ist und beide Temperaturwerte uebergeben wurden,          *
  werden die Temperaturwerte und das aktuelle Datum in der Datenbank gespeichert.  *
                                                                                   *
***********************************************************************************/

define("KEY","MEINPASSWORT123");

include("../inc/db.inc.php");

if(isset($_GET['key']))
{
  if($_GET['key'] == KEY)
  {
    if(isset($_GET['T1']) && isset($_GET['T2']))
    {
      $TEMP1 = mysql_real_escape_string($_GET['T1']);
      $TEMP2 = mysql_real_escape_string($_GET['T2']);
      $DATUM = date("Y-m-d H:i:s");

      $result = mysql_query("INSERT INTO arduino_temperaturen (datumzeit, temp1, temp2) 
              VALUES('".$DATUM."', '".$TEMP1."', '".$TEMP2."') ") or die(mysql_error());

      if(mysql_affected_rows() == 1)
      {
        $result = "Temperaturwerte gespeichert";
      } else $result = "Fehler beim speichern der Daten in der MySQL-Datenbank";
    } else $result = "Keine Temperaturwerte übergeben";
  } else $result = "Falscher Key";
} else $result = "Kein Key übergeben";

print_r($result);
?>

Damit die Datei SaveTempToMySQL.php eine Verbindung zur MySQL-Datenbank aufbauen kann, benötigen wir die Datei db.inc.php die wir im Unterverzeichnis inc abspeichern.

inc/db.inc.php

<?php
define('DB_SERVER',"localhost");
define('DB_NAME',"DATENBANKNAME");
define('DB_USER',"DATENBANKUSER");
define('DB_PASSWORD',"DATENBANKPASSWORT");

$conn = mysql_connect(DB_SERVER, DB_USER, DB_PASSWORD);
if(is_resource($conn))
{
  mysql_select_db(DB_NAME, $conn);
  mysql_query("SET NAMES 'utf8'", $conn);
  mysql_query("SET CHARACTER SET 'utf8'", $conn);
}
?>

Die durch den Arduino in der MySQL-Datenbank gespeicherten Werte kann man nun nach Belieben auslesen. Ich möchte jetzt nicht ins Detail gehen wie man mit StyleSheets die Ausgaben schön formatiert oder wie man die Daten in einem animierten Diagram ausgeben kann, denn das würde den Rahmen hier sprengen. Ich werde zwei Beispiele aufzeigen wie man die Daten auslesen kann. Im ersten Beispiel zeige ich, wie man die zuletzt gespeicherten Werte ganz normal als Text ausgibt. Im zweiten Beispiel werde ich die Werte der letzten 12 Stunden ausgeben. Beide Beispiele, wie gesagt, ohne irgendwelche besonderen Formatierungen.

Teil 3

Auslesen der zuletzt gespeicherten Werte

<?php
/***********************************************************************************
  Autor:   Enrico Sadlowski                                                        *
  Kontakt: profwebapps@gmail.com                                                   *
                                                                                   *
  PROJEKT: Ausgabe des durch den ARDUINO zuletzt generierten Temperaturwertes      *
                                                                                   *
***********************************************************************************/

include("../inc/db.inc.php"); 

$q_data  = mysql_query("SELECT DATE_FORMAT(datumzeit,'%d.%m.%Y') AS DATUM, DATE_FORMAT(datumzeit,'%H:%i') AS ZEIT, temp1, temp2 
                        FROM arduino_temperaturen ORDER BY datumzeit DESC LIMIT 1") or die(mysql_error());
if(mysql_num_rows($q_data) > 0)
{
  $r_data = mysql_fetch_array($q_data);
  $DATUM  = $r_data['DATUM'];
  $temp1  = number_format($r_data['temp1'], 2, '.', '');
  $temp2  = number_format($r_data['temp2'], 2, '.', '');
  $ZEIT   = $r_data['ZEIT']; 
}
else
{
  $E = 1;
  $M = "Es wurden keine Temperaturwerte in der Datenbank gefunden!";
}
?>

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="user-scalable=yes, width=device-width"> 
  <title>ARDUINO - Aktuelle Temperatur</title>
</head>
<body>

<?php 
//Wenn Daten in der Datenbank gefunden wurden, diese ausgeben
if(!isset($E)) 
{
?>
  <h2>Letzter gespeicherter Temperatur-Messwert</h2>
  <h3><?php echo $DATUM.", ".$ZEIT." Uhr";?></h3>
  Innen: <?php echo $temp1;?>°C<br />
  Außen:<?php echo $temp2;?>°C
<?php            
} 
else 
{
// Meldung ausgeben wenn noch keine Daten in der Datenbank stehen 
  echo $M;
}
?>   

  </body>
</html>

 

Auslesen der Daten der letzten 12 Stunden

<?php
/********************************************************************************************
  Autor:   Enrico Sadlowski                                                                 *
  Kontakt: profwebapps@gmail.com                                                            *
                                                                                            *
  PROJEKT: Ausgabe der durch den Arduino generierten Temperaturwerte der letzten 12 Stunden *
                                                                                            *
********************************************************************************************/
?>

<!DOCTYPE HTML>
<html>
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
  <meta name="viewport" content="user-scalable=yes, width=device-width"> 
  <title>ARDUINO - Aktuelle Temperatur</title>
</head>
<body>

<table>
  <tr>
    <td width="120">Datum</td>
    <td width="120">Zeit</td>
    <td width="120">Innen</td>
    <td width="120">Außen</td>
  </tr>

<?php
include("../inc/db.inc.php"); 

$q_data  = mysql_query("SELECT DATE_FORMAT(datumzeit,'%d.%m.%Y') AS DATUM, DATE_FORMAT(datumzeit,'%H:%i') AS ZEIT, temp1, temp2 FROM arduino_temperaturen WHERE `datumzeit` >= date_sub(now(), interval 12 hour) AND `datumzeit` <= now()  GROUP BY DATE_FORMAT(datumzeit, '%Y-%m-%d %H') ORDER BY datumzeit DESC") or die(mysql_error());
if(mysql_num_rows($q_data) > 0)
{
  while($r_data = mysql_fetch_array($q_data))
  {
    echo "<tr>\n";
    echo "  <td>".$r_data['DATUM']."</td>\n";
    echo "  <td>".$r_data['ZEIT']."</td>\n";
    echo "  <td>".number_format($r_data['temp1'], 2, '.', '')."°C</td>\n";
    echo "  <td>".number_format($r_data['temp2'], 2, '.', '')."°C</td>\n";
    echo "</tr>\n";
  }
}
else
{
  $E = 1;
  $M = "Es wurden keine Temperaturwerte in der Datenbank gefunden!";
}
?>

    </table>
  </body>
</html>

 

Die Arduino-Plattform bietet nicht nur eine sofort und sehr universell einsetzbare, komplette Mikrocontroller-Konfiguration, sondern auch eine besonders einfach erlernbare Programmierung auf einer eigenen, kostenlos via Internet verfügbaren Entwicklungsplattform.

Bei elv finden Sie immer wieder aktuelle Angebote und Schnäppchen wenn Sie einen Arduino und Arduino Zubehör suchen.
FRANZIS Arduino Uno-Platine R3

The post Arduino, MySQL – Temperatur-Sensoren über Webserver auslesen appeared first on Fluuux - TechBlog.


Viewing all articles
Browse latest Browse all 40

Trending Articles