Go Down

Topic: [gelöst] Temperatur Logger, mit DS18B20 (Read 7874 times) previous topic - next topic

Cetax

Hallo,
ich habe da nochmal eine Verständnis Frage, folgendes Szenario:
Der Arduino misst die Temperatur und schreibt sie eine Logdatei,
ohne sie auf einer Webseite wieder zugeben.
Kann ich dann ohne Problem die Daten per FTP oder telnet abrufen ?

Arduino -->Logfile -->Ethernet

Dann dürfte sich doch nichts beissen, oder nicht ?

Danke für Eure Hilfe und Geduld  :smiley-red:
*greatz*

 CeTax

www dot blinkmann dot de

mkl0815


Hallo,
ich habe da nochmal eine Verständnis Frage, folgendes Szenario:
Der Arduino misst die Temperatur und schreibt sie eine Logdatei,
ohne sie auf einer Webseite wieder zugeben.
Kann ich dann ohne Problem die Daten per FTP oder telnet abrufen ?
Arduino -->Logfile -->Ethernet

Dann musst Du Deinem Arduino aber auch FTP oder telnet beibringen. Denn so wie Du es beschreibst, ist der Arduino der Server, denn der loggt ja die Daten.
Das Problem bleibt aber das Gleiche, Dein Arduino hat die Daten und Du musst sie per Ethernet abholen. Dabei ist dann HTTP immer noch viel einfacher als telnet oder ftp.
Wo ist denn Dein Problem, wenn Du den Webserver schon hast. Du musst lediglich noch die Datei auf der SD-Karte öffnen und dann die Daten in einen Puffer lesen und den dann an den verbundenen Webclient (Browser, wget etc.) ausgeben.

Cetax

#17
Apr 18, 2012, 10:09 pm Last Edit: Apr 19, 2012, 07:40 pm by Cetax Reason: 1
Hi,
ok danke für die erläuterung, ich glaube ich verstehe.
Vielleicht denke ich auch zu kompliziert oder zu einfach... :~

Quote
Wo ist denn Dein Problem, wenn Du den Webserver schon hast. Du musst lediglich noch die Datei auf der SD-Karte öffnen und dann die Daten in einen Puffer lesen und den dann an den verbundenen Webclient (Browser, wget etc.) ausgeben.

Das ich nicht verstehe wie ich das umsetzten soll.  :smiley-red:
Was du geschrieben hast, verstehe ich (glaub ich..).
- DATALOG.txt öffnen -->Inhalt in den Puffer schieben -->Webclient ruft den Puffeinhalt ab (z.b. wget)

Und da verließen sie mich.. Sorry...
Und ich glaube, das der Sketch zu groß wird, er hat jetzt schon 29660bytes

Ist es Hilfreich, den Sketch zu Posten?
Danke !
*greatz*

 CeTax

www dot blinkmann dot de

mkl0815

Ja, der Code wäre sicher hilfreich. Aber bitte in "#" Tags. Evtl. auch als Anhang, denn ich vermute mal das ist nicht wenig :-)
Evtl. kann man ja das eine oder andere optimieren, damit der Webservice auch noch mit dazu passt.

Cetax

Hallo,
erstmal ein großes Danke für deine Hilfe und Mühe !!
Ich habe aber noch eine Fage.
Wäre es einfacher, ich würde alles wegwerfen und neu anfangen (Theoretisch :smiley-mr-green:)
Folgende Vorstellung:

DS18B20 --> Arduino Ethernet -->LAN-Kabel --> WebServer (Synology DS111)

Soll heißen, der Arduino misst die Temperatur und mein Webserver ruft die Temperatur ab und speichert sie in einer Text-Datei (z.b. Log.txt)
Dann hätte ich doch nicht das Problem mit der SD-Karte und dem Ethernet Pin, oder ?
Und der Code wäre kleiner und der Arduino vielleicht nicht überlastet.

Oder geht das so nicht ? (Is ja nur so´ne Idee  :smiley-roll:)

Ich pack den Sketch mal als Anhang...
*greatz*

 CeTax

www dot blinkmann dot de

mkl0815

Dann mach doch aus dem Arduino einen Webclient, keinen Webserver.
Der Arduino misst die Temperatur und ruft auf Deinem Webserver eine URL (z.B. http://<synology-IP>/senddata.php?temp1=10.3&temp2=23) auf. Der Synology-Webserver kann auch PHP, Du kannst dort also ohne Probleme die Daten verarbeiten und in eine Datei schreiben. Außerdem sparst Du Dir so den Cronjob auf dem NAS das alle X Minuten den Arduino abfragt. Meine Arduino-Wetterstation funktioniert auf diese Weise sehr stabil seit einem halben Jahr. Ich habe mir sogar die RTC gespart und frage einmal täglich über eine spezielle URL von Webserver die Zeit ab. Das spart den Code für eine NTP-Funktion, denn ein HTTP-Get musste ich ja eh bauen.
Ein weiterer Vorteil ist, das der Arduino den Zeitpunkt zum Senden der Daten bestimmen kann und nicht immer auf ankommende Requests warten muss.

thewknd

dafür hast du den grossen Nachteil, dass
- wenn das NAS nicht läuft
- wenn das Netzwerkkabel nicht eingesteckt ist
du keine Messwerte hast.
duemilanove / OSX & WIN
Arduino & Teensy: http://bit.ly/13rbdtQ

mkl0815

Dafür ist ja die SD-Karte da, dort werden die Daten lokal gespeichert. Der Zugriff selbst kann auch wieder indirekt erfolgen. z.B. durch aufrufen eine URL http://<synologyIP>/service.php
Das kann der Arduino regelmäßig pollen und dort stehen z.B. Befehle wie
"send 2012-04-19.csv" drin. Damit kann der Arduino in einer "Messpause" die Datei von der SD-Karte per HTTP-Post an den Webserver hochladen.
Das kann man sicher auch alles anders lösen. Es gibt immer verschiedene Wege zum Ziel. Bei meiner Lösung war mir wichtig, das der Arduino Wetterdaten sammelt und nicht die meiste Zeit damit verbringt auf einen HTTP-Request zu warten, oder von einem Request im ungünsitgen Zeitraum erwischt wird.

Cetax

Hallo mkl0815,
Das hört sich super an.
Nur wie das funktionieren soll mit dem übergeben der gemessenen Temperatur, versteh ich nicht.
Bin jetzt auf die Arbeit,werde mich heute Abend mal dran setzen.
Aber erstmal vielen Dank den Lösungsvorschlag.
Ich werde aber bestimmt für die Umsetzung deine Hilfe brauchen. 

PS: Eine Wetterstation habe ich auch, WS2300.
*greatz*

 CeTax

www dot blinkmann dot de

Cetax

#24
Apr 20, 2012, 01:38 pm Last Edit: Apr 20, 2012, 01:43 pm by Cetax Reason: 1
Moin,
so habe mich mal an einen Anfang gewagt:
Code: [Select]
/*
 Web client
 This sketch connects to my Diskstation 192.168.178.111
 and send the Themperature from DS18B20 at DigiPin 6 to it

 created 20 April 2012
*/

#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[] = {  0x90, 0xA2, 0xDA, 0x00, 0xEE, 0xF3 }; // Mac-Adresse Arduino Ethernet
byte ip[] = {192,168,178,230}; // IP-Adresse Arduino Ethernet
byte gateway[] = {192,168,178,1}; // Gateway (Fritzbox)
byte subnet[] = {255,255,255,0};
IPAddress server(192,168,178,111); // Diskstation DS111

// 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()
{
 Serial.begin(9600);                             // initialisiere serielle Verbindung mit 9600
 Ethernet.begin(mac, ip, gateway, subnet);       // starte Ethernet
 delay(1000);                                    // warten auf Ethernet
 Serial.println("verbinde...");                  // Ausgabe(n) auf serieller Konsole
if (client.connect(server, 80))                  // wenn Verbindungsversuch erfolgreich ...
 {
   Serial.println("verbunden");                  // Ausgabe(n) auf serieller Konsole
                                                 // schicke Temperatur zum Server
   client.println("GET http://192.168.178.111/senddata.php?temp1=10.3&temp2=23) HTTP/1.0"); // <-- Wie setzt sich die Adresse zusammen??
   client.println();                             // schicke Leerzeile (beende Anfrage)
 }
else                                             // sonst, wenn Verbindung fehlgeschlagen, ...
 {
    Serial.println("Verbindung fehlgeschlagen"); // Fehlermeldung auf Konsole
 }
}

void loop()
{
 //Keine Ahnung was hier rein soll... :-(
}


Jetzt bräuchte ich HIlfe, wwie setzt sich das zusammen:
Code: [Select]
client.println("GET http://192.168.178.111/senddata.php?temp1=10.3&temp2=23) HTTP/1.0");
senddata.php?  <-- Was muss darein und muss die auf den Arduino? Auf die SD-Karte?
temp1=10.3  <-- Ok, temp1 soll wohl der erste DS18B20 sein, aber was ist die 10.3?
temp2=23  <-- Hier auch, was ist die 23 ?

Und was kommt in den Loop-Bereich, sowie was muss auf der Diskstation sein (PHP-File?)

Fragen über Fragen...  :smiley-red:
Ach ja, der DS18B20 muss ja auch noch rein... ups..
*greatz*

 CeTax

www dot blinkmann dot de

thewknd

Quote
http://192.168.178.111/senddata.php?temp1=10.3&temp2=23


192.168.178.111
die ip deines NAS

senddata.php
das PHP Script auf dem NAS

temp1=10.3
der erste DS18B20, 10.3 ist der aktuelle Messwert (Temperatur)
10.3 ist nur ein Beispielwert, bei dir muss da der aktuelle Messwert von dem DS18B20 stehen

temp2=23
der zweite DS18B20
duemilanove / OSX & WIN
Arduino & Teensy: http://bit.ly/13rbdtQ

Cetax

#26
Apr 20, 2012, 01:56 pm Last Edit: Apr 20, 2012, 02:02 pm by Cetax Reason: 1
hi,
ok, ich habe was im Netz gefunden und versucht auf meine Bedürfnisse anzupassen,
aber es kommt beim Compilieren eine Fehlermeldung :
Code: [Select]
Temperatur_WebClient.cpp: In function 'void loop()':
Temperatur_WebClient:83: error: a function-definition is not allowed here before '{' token
Temperatur_WebClient:91: error: a function-definition is not allowed here before '{' token
Temperatur_WebClient:109: error: expected `}' at end of input


Hier mein Sketch:
Code: [Select]
/*
/*
 Web client
 This sketch connects to my Diskstation 192.168.178.111
 and send the Themperature from DS18B20 at DigiPin 6 to it

 created 20 April 2012
*/

#include <SPI.h>
#include <Ethernet.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#define ONE_WIRE_BUS 6          // DS18B20 an Pin 6 angeschlossen

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature sensors(&oneWire);

DeviceAddress kessel_Thermometer =         { 0x28, 0x03, 0xF6, 0xC2, 0x03, 0x00, 0x00, 0xA7 };  //Adressen der Sensoren manuell eingeben


// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = {  0x90, 0xA2, 0xDA, 0x00, 0xEE, 0xF3 }; // Mac-Adresse Arduino Ethernet
byte ip[] = {192,168,178,230}; // IP-Adresse Arduino Ethernet
byte gateway[] = {192,168,178,1}; // Gateway (Fritzbox)
byte subnet[] = {255,255,255,0};
IPAddress server(192,168,178,111); // Diskstation DS111

// 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;

char url[]  = "/senddata.php"; // Pfad zur PHP-Datei eingeben
char key[] = "Kennwort_eingeben"; // Kennwort aus PHP-Datei eingeben
char c;

int Sensor = 5;            // DS18B20 an DigitalPin 5
int PowerLED = 3;           // Power LED DigitalPin3
float Temperatur = 0;       // Variable für Temperatur ;-)
int temp = 0;            

void setup()
{
 Serial.begin(9600);  
 sensors.begin();
 sensors.setResolution(kessel_Thermometer, 9);  // initialisiere serielle Verbindung mit 9600
 
 digitalWrite(PowerLED, HIGH);
 Ethernet.begin(mac, ip, gateway, subnet);       // starte Ethernet
 delay(1000);                                    // warten auf Ethernet
 Serial.println("verbinde...");                  // Ausgabe(n) auf serieller Konsole
if (client.connect(server, 80))                  // wenn Verbindungsversuch erfolgreich ...
 {
   Serial.println("verbunden");                  // Ausgabe(n) auf serieller Konsole
                                                 // schicke Temperatur zum Server
   client.println("GET http://192.168.178.111/senddata.php?temp1=10.3&temp2=23) HTTP/1.0"); // <-- Wie setzt sich die Adresse zusammen??
   client.println();                             // schicke Leerzeile (beende Anfrage)
 }
else                                             // sonst, wenn Verbindung fehlgeschlagen, ...
 {
    Serial.println("Verbindung fehlgeschlagen"); // Fehlermeldung auf Konsole
 }
}

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 (EthernetClient.connect())  // 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.println();
   Serial.println("fertig!");
 }
 else
 {
   Serial.println(" ***** VERBINDUNGSAUFBAU NICHT MÖGLICH *****");
 }    
}


Was noch fehlt :
Code: [Select]

sensors.requestTemperatures();
float tempKessel = sensors.getTempC(kessel_Thermometer);

Wo wird das rein geschrieben ? In welchen void ?

Ich hoffe das das so die Richtung ist, oder ist das total falsch?
*greatz*

 CeTax

www dot blinkmann dot de

mkl0815

#27
Apr 20, 2012, 02:20 pm Last Edit: Apr 20, 2012, 02:25 pm by mkl0815 Reason: 1
Code: [Select]
client.println("GET http://192.168.178.111/senddata.php?temp1=10.3&temp2=23) HTTP/1.0");
stimmt schon fast.

Code: [Select]

client.print("GET /senddata.php?temp1=");
client.print(temp1);
client.print("&temp2=");
client.print(temp2);
client.print(" HTTP/1.0\n");
client.println("Host: 192.168.178.111\n");

Ist richtig. Du gibts hinter dem GET nur den relativen Pfad an. Solltest Du für den Webservice einen Domainnamen verwenden und nicht nur die IP, dann musst Du den Parameter "Host:" anpassen. Akutell sollte es aber erstmal so gehen.
Das obige Beispiel geht davon aus, das Du zwei Variablen temp1 und temp2 hast, welche die gemessene Temperatur as float enthalten.
Du brauchst dann auf dem NAS ein PHP-Script das unter http://192.168.178.111/senddata.php aufrufbar ist. In diesem Script hast Du dann zwei Werte im globalen Array $_GET[] für temp1 und temp2, die Du dann z.B. in eine Datei schreiben kannst. Idealerweise ergänzt um den aktuellen Timestamp.

Allerdings ist Dei Code noch durcheinander. Das Senden an den Server soll ja regelmäßig passieren, also muss das in die loop(). Dafür muss der Server-Kram aus der loop() raus, da Du den nicht mehr brauchst. Am einfachsten definierst Du Dir eine Funktion sendHTTP(float temp1, float temp2) die den HTTP-Request kapselt, dann wird Dein Programm übersichtlicher.

mkl0815

Ok, ich hab mir den Code gerade nochmal angesehen. Welcher Teil ist von Dir und was ist von dem Beispiel das Du gefunden hast? Denn es gibt bereits zwei Funktionen zum Sensor-Lesen und Daten-Senden. Allerdings verwenden die noch einen analogen Sensor und schicken einen Key mit im Request, vermutlich zur Authentifizierung beim PHP-Script.
Wie in einem anderen Thread schon geschrieben, finde ich es ungünstig, fremden Code 1:1 zu übernehmen und auf die eigenen Bedürfnisse anzupassen. Lieber eigenen Code schreiben und einzelne Teile oder Funktionen aus anderem Code übernehmen. Das ist strukturierter und übersichtlicher.
Wenn es nicht auf Anhieb klappt, dann zerlege die Aufgabe in einzelne Teilaufgaben, die Du unabhängig voneinander löst.

z.B.
1) HTTP-Request an ein PHP-Script auf dem NAS schicken. Dazu einfach zwei fixe Werte in loop() einmal pro Minute an das Script schicken und dort auswerten.
2) Wenn 1 funktioniert, dann Deinen Code zum Auslesen der Temperaturen (am besten als eigene Funktion) in den Code mit einbauen. Dann die bisher fixen Werte durch die gemessene Temperatur ersetzen und wieder mit dem PHP-Script verarbeiten
3) Ergänzen weiterer Funktionen die Du noch haben willst.

Btw. ich habe keine zusätzliche Wetterstation, der Arduino IST die Wetterstation :-)
Mario.

Cetax

Hallo,
ok ich bin dabei den Code zu zerpflücken und ihn für mich neu zusammen zu setzten...
Aber hier mal der Link zum Orginal, von dem ich das kopiert habe:
http://jleopold.de/wp-content/uploads/2011/03/ArduinoDatenLogger.txt

Ich versuche es mal so wie du gesagt hast... Gar nicht so einfach...
ich geh den mal wieder ins Kämmerlein.....

Danke dir !!
*greatz*

 CeTax

www dot blinkmann dot de

Go Up