Temperatur mit Ethernetshield ins Netzwerk übertragen

Hallo,
ich habe vor die Temperatur im Keller mit einem LM75 zu messen und dessen über I²C auszulesen und, das dann mit einem Ethernetshield in mein Netzwerk zu übertragen. Ich habe schon den Beispiel Webserver getestet und dieser funktioniert auch. Mein Problem ist, dass wenn ich den LM75 auslesen möchte, sich der Webserver aufhängt.
Was mach ich falsch?

mfg
Michael

#include <Wire.h>
#include <SPI.h>
#include <Ethernet.h>
#define LM75_1 0b1001000
// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0x90, 0xA2, 0xDA, 0x0D, 0xD6, 0x03 };
IPAddress ip(10,0,0,177);
float temp;
// Initialize the Ethernet server library
// with the IP address and port you want to use 
// (port 80 is default for HTTP):
EthernetServer server(80);

float LM75()
{
  byte msb_1,lsb_1=0; 
    float Degrees_1=0;  
 
    // read LM75_1    
    Wire.beginTransmission(LM75_1);
    Wire.write(0x00); 
    Wire.endTransmission();
    Wire.requestFrom(LM75_1, 2); 
    while(Wire.available() < 2);     
    msb_1 = Wire.read(); lsb_1 = Wire.read();
    if(msb_1 < 0x80) 
    {
      Degrees_1=((msb_1*10)+(((lsb_1&0x80)>>7)*5));
    }
    else
    { 
      Degrees_1=((msb_1*10)+(((lsb_1&0x80)>>7)*5)); 
      Degrees_1=-(2555.0-Degrees_1);
    }
    Degrees_1=Degrees_1/10;
    
    return Degrees_1;
}
void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }
  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() 
{
  
   temp=LM75();
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply
        if (c == '\n' && currentLineIsBlank) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
                    // add a meta refresh tag, so the browser pulls again every 5 seconds:
          client.println("<meta http-equiv=\"refresh\" content=\"5\">");
          // output the temperature
            client.println("Arduino Webserver");
            client.println("Temperatur im Keller:");
            client.print("T= ");
            client.print(temp);
            client.print("°C");
            client.println("
");       
 
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disonnected");
  }
}

Hier ist der Grund:

    while(Wire.available() < 2);

Du würdest besser den Rückgabewert von Wire.requestFrom() überprüfen, dann weisst Du, ob genügend Bytes gelesen wurden.

Hallo,
das Auslesen des Sensors hat aber schon so funktionert.

mfg
Michael

Ich nehme an, dass "aufhängen" heissen soll, dass Dein Arduino einfriert und nicht mehr reagiert, bis Du den Reset-Taster drückst. Die while-Schleife ist der einzige Ort im Code, wo ein Endlos-Loop auftreten kann. Meine Vermutung ist, dass der Sensor keine gültige Antwort gibt und somit die 2 Bytes nie im Puffer landen. Weshalb das so ist, müssen wir noch herausfinden. Mach mal ein Foto Deiner Verdrahtung oder zeichne ein Schema, wie Du die Komponenten verbunden hast. Ich tippe auf fehlende oder zu kleine Pull-ups, aber das ist Finger-in-die-Luft-halten.

Die Widerstände in der Zeichnung sind keine 220R sondern 10k und natürlich ist auf dem uno noch das ethernetshield.

Aufgrund der Zeichnung gehe ich davon aus, Du hast überprüft, dass Du eine 5V-Version des LM75 hast.

Die Pull-ups sollten eher 4k7 anstatt 10k sein, aber das sollte bei nur einem Device und kurzen Leitungen keine grosse Rolle spielen.

Hast Du die while-Schleife gelöscht? Falls ja, was hat das gebracht?
Sicherheitshalber würde ich das Config-Register auch noch mit dem Default-Wert schreiben.

Hallo,
nachdem ich die while-Schleife gelöscht habe hat es funktioniert. Seltsam ist nur, dass ich mir sicher bin das ich eine 5V Version bestellt hab aber er nur funktionert wenn ich ihn an die 3.3V anschließe.

Frage zur Auswertung:
Ich glaube das die Auswertung des LM75 nicht die richtigen Werten berechnet. Ich hab die Auswertung aus einem Buch. Könnt ihr mir vl sagen wie man das besser machen kann?

Kleine Frage am Rande:

Gibt es einen speziellen Grund warum du dich für den LM entschieden hast und nicht für einen DS18B20?

Vorteil beim DS18B20: Viel einfachere Verdrahtung und durch den 1-Wire Bus eigentlich auch simpelster Code.

Das soweit nur am Rande (falls du mehrere verbauen willst).

Lg

Könnt ihr mir vl sagen wie man das besser machen kann?

Wenn Dir ganze Grade genügen:

int8_t degrees = (int8_t) msb_1;

oder in Decigraden:

int16_t degrees = (int8_t) msb_1;
degrees *= 10;
if (lsb_1 & 0x80) degrees += 5;

Aber welche Werte kriegst Du denn und welche hättest Du erwartet?