Temperatur Webserver

Zum meinem Geburtstag habe ich das neuer Ethernetshield bekommen und direkt auch mal ein bisschen gespielt
So und das ist dabei rausgekommen:
http://dhmaster.no-ip.biz/
Hier habe ich eine Seeeduino Mega als Hauptplatine darauf das Ethernetshield.
Die Temperatur wird von einem LM35CZ erfasst der über einem MAX127 von Maxim (12Bit-I2C-8Ch-Analogeingang).
Da der LM35 für negative Temperaturen eine negative Spannung braucht habe ich mich für einen Zeitsparenden Trick entschieden
Ich habe die Masse des LM35 einfach mit einer Diode 1N4148 um ca 0,5V angehoben und dadruch eine Virtuelle Masse die dann höher liegt als meine Bezugmasse. Der LM35 ist mit einer minimalen Betriebsspannung von 4V angegeben was hier dann noch im Normalbereich liegt (5V-0,5V=4,5V).
Dann mit einem Widerstand 10K den Ausgang auf Masse gelegt. So hatt der LM35 0,5V unterhalb seiner Versorgung zur Verfügung was für ca -50°C ausreicht.
Um einen Temperaturdrift der Offset Spannung zu kompensieren habe ich eine weiteren Kanal des MAX127 auf die "vituelle" Masse gelegt und dann damit alle 60s die Diodenspannung zu messen und die dann mit in die Berechnung der aktuellen Temperatur zu haben.

Nicht schön aber selten :wink:
Projektdauer ca 1,5 std :wink:

Hier noch der Code:
01.01.11. (Überarbeitet Rechenfehler beim Offset)

#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>

/* 
 Lizenz (Deutsch): creative commons Namensnennung - Keine kommerzielle Nutzung - Weitergabe unter gleichen Bedingungen 3.0 Unported - http://creativecommons.org/licenses/by-nc-sa/3.0/deed.de
 Bei Verwendung und Weitergabe des Quellcodes muss ein Verweis auf den Autor und die Webseite erfolgen. In Begleitdokumentationen ist ebenfalls in angemessener Weise dieser Verweis anzubringen.
 
 License (English): creative commons Attribution-Noncommercial-Share Alike 3.0 Unported - http://creativecommons.org/licenses/by-nc-sa/3.0/
 When using and distributing this source code a reference to the author and the web page must take place. In accompanying documents this reference must also be attached.
 
 Code by Mats Vanselow - http://www.mats-vanselow.de
 enhanced by Daniel Herr
 Erweiterung des Servers mit einem MAX127(Analogeingang 12Bit) von Maxim per Ansteuerung über I2C in einer eigenen Funktion, zur bessern Auflösung der Temeperatur 10mV=1°
 Die Temperatur wird über einen LM35 gemacht dem mithilfe einer Diode die neagtive Temperaturbereich beigebracht wird. Um Temperaturdrift der Diode zu kompensieren wird automatisch
 der Offset alle 60 sekunden  korrigiert
 */

int tempc = 0;
int tempbefore=0;
int tempafter=0;
int tempafter1=0;
int tempafter2=0;
int rund=0;
int runh=0;
int runm=0;
int runs=0;
int ticks=0;
int offset=370;      // erster Startwert des Offset mit einem mal gemessenen Wert von 480mV Dioden spannung
unsigned long last_millis1=0;
unsigned long last_millis2=0;

byte mac[] = {
  0x90, 0xA2, 0xDA, 0x00, 0x2B, 0xEA };           // MAC Adresse des Arduino Boards
byte ip[] = {
  192, 168, 178, 5 };                              // IP Adresse des Arduino Boards
byte gateway[] = {
  192, 168,178, 1 };                               // Gateway Fritzbox
byte subnet[] = { 
  255, 255, 255, 0 };                             // Subnet Maske (optional)
Server server = Server(80);                       // Port Einstellung (Standard 80)

void setup() {
  Wire.begin();                                    // I2C als Master
  Ethernet.begin(mac, ip);//, gateway, subnet);   // Ethernet initialisieren
  server.begin();                                 // Auf Clients warten
  pinMode(4,OUTPUT);                              // zum Abwählen der SD karte  auf dem Shield
  digitalWrite(4,HIGH);                           // zum Abwählen der SD karte  auf dem Shield
}

void loop() {
  long cur_millis;
  cur_millis= millis();                            

  if (cur_millis-last_millis1 >=1000) {          // Für den Laufzeit zähler
    runs=runs+1;
    last_millis1=cur_millis;
  } 
  if (cur_millis-last_millis2 >60000){             // Für den Offset 
    offset=readMAX127(1);
    last_millis2=cur_millis;
  }

  if (runs >= 60){
    runm=runm+1;
    runs=0;
  }
  if (runm >= 60){
    runh=runh+1;
    runm=0;
  }
  if (runh >= 24){
    rund=rund+1;
    runh=0;
  }
  tempc = ( (50000-offset*12.2) * (readMAX127(0)-offset))/4096;    // Umwandeln der 12Bit Wertes in einen Temperaturwert/100 zum besseren auflösen der Nachkommastellen
  tempbefore=tempc/100;
  tempafter=tempc%(tempbefore*100);
  if (tempafter <0){
    tempafter=tempafter*-1;
  }
  tempafter2=tempafter;


  Client client = server.available();             // Prüfen, ob Client Seite aufruft
  if (client) {                                   // Seitenaufruf durch User
    server.print("HTTP/1.0 200 OK\r\nServer: arduino\r\nContent-Type: text/html\r\n\r\n");
    server.print("<HTML><HEAD><TITLE>");
    server.print("Arduino Board");
    server.print("</TITLE>");
    server.print("</HEAD><BODY>");
    server.print("<b> Mein erster Temperatur - Webserver  </b>
");
    server.print("Der ArduinoMEGA läuft seit ");
    server.print(rund);
    server.print(" Tagen ");
    server.print(runh);       
    server.print(" Stunden ");
    server.print(runm);
    server.print(" Minuten und ");
    server.print(runs);
    server.print(" Sekunden.
");
    server.print("Temperatur draussen auf der Fensterbank ");
    server.print(tempbefore);
    server.print(".");
    if (tempafter <=9){
      tempafter1=0;
      server.print(tempafter1);
    }
    server.print(tempafter2);
    server.print(" Celsius
 ");
    server.print("Der gemessene Offset beträgt: ");
    server.print(offset);
    server.print(" LSB </BODY></HTML> ");
    delay(10);                                    // Kurz warten, um Daten zu senden
    client.stop();                               // Verbindung mit dem Client trennen
  }
}

long readMAX127(byte chan)
{
  byte control = 0x80 + (chan << 4);
  byte addr = 0x28;

  Wire.beginTransmission(addr);
  Wire.send(control); // send value
  Wire.endTransmission();

  Wire.requestFrom(addr, (byte)2);

  byte b1 = Wire.receive();
  byte b2 = Wire.receive() >> 4;
  long data = (b1 << 4) | (b2 & 0x0F);

  return data;
}

Sehr Cool! Es wird Zeit, meine Google Charts Library zu veröffentlichen... :wink:

dann lass mal rüberwachsen :wink:
Könnten dann ja mal nen schönen Chart schreiben.

Auf folgender Seite findest Du meinen Code, den ich für die Library benutze: http://sebastian.setz.name/arduino-google-charts-library
Da es noch nicht fertig ist, schlecht kommentiert, usw. gibts das Passwort "arduino".
Ich fülle ein mehrdimensionales Array im kurzen Abstand (1Sek) mit unterschiedlichen Werten (Temp, Feuchte, usw.), nach einer definierten Zeit(z.Bsp. eine Stunde) wird das Array geleert und die Mittelwerte in ein weiteres Array geschoben, in dem dann ein Langzeitverlauf(z.Bsp. ein Tag) zu sehen ist.
Für Dich wird wohl der Part zur Erzeugung der Grafik am interessantesten sein. Der Teil ist von mir aber sehr gut Kommentiert.

Viel Spaß & zeig mal Ergebnisse :wink:

Sebastian

Dann sag ich schon mal dankeschön :wink:

Hihi .. Projektübereinstimmung :slight_smile:

Einziger Nachteil: Temperaturen unter Null tut es nur mit anderer Beschaltung. Bei Null Grad ist ohne weitere Beschaltung Ende .

http://home.df6ih.de:83

So kann man seine Temps weltweit verbreiten. Bis zum eintreffen der Dioden allerdings aussen erst ab Null Grad

Interessante Sache wenn man ein zufällig gleiches Projekt trifft

Kleine Formalie :

aus :

server.print("Der gemessene Offset beträgt: ");

mache:
server.print("Der gemessene Offset beträgt: ");

dann passt das ...

Da funktioniert aber mit den Temps unter null soll ich es dir mal aufmalen? Geht hervorragend hatten bei uns vor 3 Tagen mál unter Null ohne Probleme

Interessant, interessant. Welches Ethernetshield habt ihr?

Dieses http://www.watterott.com/de/Arduino-Ethernet-Shield ?

Genau dieses habe ich

@volvodani Ja immer gerne. Ich wollte die Lösung aus dem Datenblatt des LM35 nehmen.

Das ist das watterrott ethernet Kärtchen und das arbeitet ganz wunderbar, auch in diesem Familiennetz hier, welches locker 50% aller Kleinbetriebe überragt :slight_smile: (s.a. Port 83 ggg )

Ich mache jetzt den dritten LM35 an die Heizung und dann ist meine Versuchsanordnung fertig. Danach wird das eine Heizungssteuerung für Aussengehege mit Hütten und Kleintierhäuser in einem Tierheim.

Das nächste Spielzeug was unterwegs ist ist ein 4 zeiliges Display, die seed relaiskarte zieht auch noch auf die Kisten.

Ich suche noch eine Möglichkeit die einzelnen Breakaout Schalteinheiten miteinander zu vernetzen ... I2C ? Was ist da die günstigste Variante ?

Ich mach dies genauso nur ich benutzte nicht eine Negative Spannung sondern hebe die Bezugsmasse des Lm35 an. ein kleiner trrick den man schon mal in analogen Schaltungen macht wenn man keine negative Spannung hat, aber genug Reserven in der Normalen Positiven Versorgungsspannung. Diese Virtuelle Masse macht man normalerweise mit einem LM358 der ist zuverlässiger ist aber wie halt geschrieben mehr Aufwand.

Wobei ich anstatt der originalen Arduino Analogeingange den MAX127 benutzt habe um auf eine bessere Auflösung zu kommen. Man muss dafür hingegen einen Analog Eingang opfern für die genauigkeit. Du kannst aber auch mit einem Messegerät die Dioden Spannung beobachten und dann selber entscheiden ob die abweichung dir zu groß ist.

Sehr Cool! Es wird Zeit, meine Google Charts Library zu veröffentlichen...

@stundenblume
Die Lösung mit Google Charts API und deinem Beipiel bietet sehr viele Möglichkeiten.
Herzlichen Dank für deine Arbeit.

Danke :slight_smile:

Wenn ich den Code konsistent, mit sinnvollen Variablennamen und ausreichend Kommentaren versehen habe wird er auch vernünftig veröffentlicht.

Gruß

Sebastian

Ich bekomme den nicht kompilier da bei dem Url http:// die doppel Slash kommen und meherer "" dadurch wird der Pint nicht als ganzes gesehen und ab // halt als kommentar

escapen....

du schreibst im quellcode:

"http://example.com" ..... und schon geht das

Das ist mir bekannt ich zeige dir mal die Zeile:

client.print("<img src='http://chart.apis.google.com/chart?");

Jetzt schau mal nach den " und den // in deiner IDE und du wirst mein Problem sehen

client.print("<img src=\"http://chart.apis.google.com/chart\" title=\"Linkification: http://chart.apis.google.com/chart\">http://chart.apis.google.com/chart</a>?");

Den Title Tag hätte ich mal weggelassen.... das <a .. also der Link war ohne Sinn und Ziel, deswegen mal rausgenommen. Jedenfalls kann die IDE das, weil sie hat mir ja auch meine MANOMETER ;D von googlechen eingebaut

Du musst der API aber etwas übergeben, sonst weiss sie nicht was sie tun soll.

ich habe hoier eine Zimmertemp Anzeige bei der 26C 100% sind, dann sieht das hier so aus:

     xtemp=((100/26)*xtemp);
            client.print((analogRead(analogChannel)* 4 * 100.0)/1023.0);
            client.print("<img src=\"https://chart.googleapis.com/chart?chs=200x125&cht=gom&chd=t:");
            client.print(xtemp);
            client.print("&chco=66FFFF,CC0000&chl=");
            client.print((analogRead(analogChannel)* 4 * 100.0)/1023.0);
            client.print(" \" / >");

Oder Du benutzt die einfachen Anführungszeichen. Anstatt " also '

spätestens bei Javascript ist dann auch damit Ende :-X

spätestens bei Javascript ist dann auch damit Ende

Sobald JavaScript in Spiel kommt oder die Ausgaberoutine zu komplex wird, würde ich den webbasierten Teil auf einen richtigen Webserver im Intranet oder Internet auslagern.