LM75 Problem mit Temperaturmessung

Hi betreibe einen LM75 mit dem Arduino Leonardo un will die Temp. auf einem Display anzeigen.
HAbe das Probem, dass ich komische Werte angezeigt bekomme, wie 22""33# usw. hab alles versucht, aber es klappt nicht.

HIer ist der Sketch:

//Library, um den Temperatursensor LM75 via I2C anzusteuern
#include <Wire.h>
//Library, um LCD-Display anzusteuern
#include <LiquidCrystal.h>
//Das ist die Adresse des TemperaturSensors
#define SensorAddr 0x48  //in binär wäre das 1001000 die letzten 3 bit(000) sind A2-A0
//da auf gnd sind diese 0
// Globale LCD-VAriable und Pins vom LCD, die am Arduino angeschlossen sind
LiquidCrystal lcd(0,1,2,3,4,5,6);
//WIrd nur einmalig bei der Inbetriebnahme des Arduinos 
void setup()
{
  //Hier wird das LCD-Modul festgelegt, d.h.
  //Habe ein LCD 16x2-> bedeutet 16 spalten und 2 Zeilen
  lcd.begin(16,2); 
  //Hier wird die Cursorstellung festgelegt, beginne bei 0 spalte & 0 zeile
  lcd.setCursor(0,0);
  //Das zu ausgebende String/Variable
  lcd.print("Temperaturmessung");
  //Initialisierung von I2C-Bussystem
}

//Loop-Schleife, die immer augeführt wird
void loop()
{
  //beginne I2C-Kommunikation mit dem Sensor
  Wire.beginTransmission(SensorAddr);
  //Was soll gemacht werden?--> Wir wollen die Tempauslesen, das deshalb senden wir 0x00 (Reg P1 &P0 = 0)-> Temperatur
  Wire.write(0x00);
  //Wollen lesen, also verlangen wir 1 Byte um temperatur zu haben
  Wire.requestFrom(SensorAddr,1);
  //Variable, um die erhaltene Temperatur zwischenzuspeichern
  int tempGrad;
  //wenn Daten im SDA vorhanden sind, in tempGrad speichern
  if(Wire.available())
  {
     //zwischenspeichern in tempGrad
     tempGrad=Wire.read();
  }
  //Wenn nichts mehr in der SDA-Leitung vorhanden ist, beende I2C-Kommunikation
  Wire.endTransmission();
  //Ausgabe auf LCD-Display
  //Setzt cursor auf 1spalte und 2 zeile
  lcd.setCursor(0,1);
  //gebe an LCD aus
  lcd.print("Temp: ");
  //6-Spalte , zweite Zeile
  lcd.setCursor(6,1);
  //gebe an LCD aus
  lcd.print(tempGrad);
    
}

Weiß jemand was das Problem sein kann?

Danke sehr

milito:
hab alles versucht

Ja klar, ganz bestimmt hast Du "alles versucht"!

Und warum steht diese Zeile dann nicht in Deiner "setup"-Funktion:
Wire.begin();

HI danke sehr :D, hatte es nicht bemerkt.
Doch jetzt gibt er mi nur Buchstaben aus also wie folgt : EUEDEE

ich spreche den chip doch richtig an, warum geht das nicht?

Also folgendes: Auf dem SerialMonitor zeigt er es an als Temperatur, doch auf dem LCD bekomme ich nur Buchtaben.

IS es ein LCDProblem?

milito:
Also folgendes: Auf dem SerialMonitor zeigt er es an als Temperatur, doch auf dem LCD bekomme ich nur Buchtaben.

IS es ein LCDProblem?

Wenn Dein LCD bei der Programmzeile

lcd.print("Temp: ");

nur die Zeichen "EUEDEE" ausgibt, dann hast Du ein Problem mit einem falsch angeschlossenen / falsch beschalteten LCD-Display.

Nachtrag: Ausserdem sieht mir die I2C-Kommunikation mit Deinem Sensor nicht regelkonform aus. Meines Erachtens nach fragst Du ein Byte aus Register 0 eher so ab:

  Wire.beginTransmission(SensorAddr);  // Sensor mit seiner Adresse ansprechen
  Wire.write(0x00); // Register auswählen, indem wir so tun als wollten wir schreiben
  Wire.endTransmission();  // Wir schreiben aber nicht ...
  Wire.requestFrom(SensorAddr,1); // ... sondern wir fordern ein Byte von dieser Adresse an
  int tempGrad=Wire.read(); // und lesen das Byte aus und weisen es an eine int-Variable zu

AH ok, d.h. die pins die vom Arduino zum LCD gehen sind falsch bzw vertauscht?

Habe dazu das gefunden:

Nur die frage ist wie weß ich welche das ist? Muss alle prüfen

Meinst du das auf Seite 11 z.b?

milito:
AH ok, d.h. die pins die vom Arduino zum LCD gehen sind falsch bzw vertauscht?

Ein Profi sieht das.
Unsereins muss anhand von Datenblättern und Verkabelungsbeispielen genau kontrollieren.

Wenn Du 6 Zeichen per "print" ausgibst und es werden auch genau 6 Zeichen ausgegeben, und zwar falsche Zeichen, dann kannst Du jedenfalls davon ausgehen, dass Du die Steuerleitungen korrekt angeschlossen hast und nur die 4 Data-Leitungen sind irgendwie vertauscht.

Bitte auch oben den Nachtrag in meinem Beitrag zur I2C-Kommunikation beachten!

jurs:
Meines Erachtens nach fragst Du ein Byte aus Register 0 eher so ab:

Korrekt. Es ist erst endTransmission() was den Sende Puffer auf den Bus schreibt. Das muss also gemacht werden bevor man Daten anfordert und ausliest.

Serenifly:

jurs:
Meines Erachtens nach fragst Du ein Byte aus Register 0 eher so ab:

Korrekt. Es ist erst endTransmission() was den Sende Puffer auf den Bus schreibt. Das muss also gemacht werden bevor man Daten anfordert und ausliest.

Außerdem muss er an der Anzeige des Temperaturwertes noch nacharbeiten, wenn er sein LCD soweit richtig verkabelt hat, dass es funktioniert: Momentan liest er ja nur das HighByte des Temperaturwertes aus und stellt es als Integerwert dar. Damit werden (nachdem ich mal ins Datenblatt geschaut habe) wohl nur korrekt angezeigt:

  • positive Temperaturen
  • in ganzen Grad Celsius

Sein Sensor stellt aber 9-Bit Temperaturwerte bereit, so dass er im Prinzip auch das LowByte des Temperaturregisters auslesen müßte, wenn er die halben Grade .0 und .5 auch noch auslesen möchte. Und für eine korrekte Darstellung von Temperaturen unter 0°C müßte er das Vorzeichenbit noch korrekt auswerten.

Das klappt nicht habe alles versucht wie sollen die pins angeschlossen werden :(.
Jeder hat eine Andere Pinbelegung.

Wie soll ich das LCD.Display an den Arduino nun anchließen?

milito:
Das klappt nicht habe alles versucht wie sollen die pins angeschlossen werden :(.
Jeder hat eine Andere Pinbelegung.

Wie soll ich das LCD.Display an den Arduino nun anchließen?

Ganz einfach so, dass es zu Deiner Programmierung passt.

Momentan rufst Du LiquidCrystal mit 7 Parametern auf, also auch den "RW" Pin.

Normalerweise verkabelst Du aber RW am Display fest auf "GND" und rufst nur mit sechs Parametern auf:

LiquidCrystal(rs, enable, d4, d5, d6, d7)
  1. Parameter: RS - Register Select
  2. Parameter: E - Enable
    3., 4., 5., 6. Parameter ==> Die vier Datenleitungen D4, D5, D6 und D7 am Display

Im Endeffekt ist es egal, wie diese 6 Pins wo am Board angeschlossen sind.

Du mußt nur diese 6 Pins in genau dieser Reihenfolge im Aufruf von "LiquicCrystal" stehen haben.

Mit Deinem Aufruf im Programm:

LiquidCrystal lcd(0,1,2,3,4,5,6);

wäre die korrekte Verkabelung wie folgt:

Arduino Pin-0 ==> LCD RS
Arduino Pin-1 ==> LCD RW
Arduino Pin-2 ==> LCD E
Arduino Pin-3 ==> LCD D4
Arduino Pin-4 ==> LCD D5
Arduino Pin-5 ==> LCD D6
Arduino Pin-6 ==> LCD D7

Nachtrag: Allerdings kannst Du mit der von Dir beabsichtigten LCD-Verkabelung auf einem Leonardo-Board keinen I2C-Sensor verwenden!

Auf dem Leonardo werden für I2C diese beiden Pins verwendet:
Leonardo Pin-2 (SDA)
Leonardo Pin-3 (SCL)

Die Pins 2 und 3 sind daher für das LCD ABSOLUT TABU und dürfen für das LCD nicht verwendet werden, wenn Du einen I2C Sensor am Leonardo betreiben möchtest!

Hi danke dir jurs, dann werde ich es wohl so versuchen :D.

Kurze Frage, aber bei Leonardo habe ich doch extra SCL und SDA auf die Pins stehen,
warum is Pin 2 & 3 auch fest für SCL & SDA vorgesehen?

Siehe hier in dem Bild

Ich dachte 2 und 3 wären alternativ für SCL und SDA und könnten somit auch verwendet werden zur normalen Steuerung, ist es als doh nicht der Fall?

außerdem habe ich meinen I2C-sensor an Pin SCL und SDA, geht es also nicht, dass ich 2 & 3 für den LCD verwende oder dürfen 2&3 nur standardmäßig für SCL und SDA benutzt werden?

milito:
Kurze Frage, aber bei Leonardo habe ich doch extra SCL und SDA auf die Pins stehen,
Ich dachte 2 und 3 wären alternativ für SCL und SDA und könnten somit auch verwendet werden zur normalen Steuerung, ist es als doh nicht der Fall?

Bei den neueren Board-Designs sind immer zwei zusätzliche Header-Anschlüsse "SDA" und "SDA" neben dem AREF-Pin herausgeführt, damit "Shields" entworfen werden können, die zu verschiedenen Arduino-Boards kompatibel sind.

Die mit SDA und SCL beschrifteten Extra-Pins neben AREF sind dabei auf jedem Boards mit den Controller-Pins verbunden, an denen bei dem Controller das I2C-Interface sitzt.

Bei einem Arduino-Uno sind diese beiden Extra-Pins also mit A4 und A5 parallel geschaltet.
Bei einem Arduino-Leonardo mit den Pins 2 und 3.
Und bei einem Arduino-MEGA mit den Pins 20 und 21

So dass die Hardware (Shield) für I2C immer mit denselben Pins verbunden werden kann, auch wenn das I2C-Interface auf dem jeweiligen Controller auf ganz verschiedene Pins verteilt ist.

Nichtsdestotrotz kannst Du natürlich die Pins, die schon für I2C verwendet werden, nicht noch für andere Nicht-I2C-Hardware gleichzeitig verwenden. Also kannst Du auf einem UNO-Board bei Verwendung von I2C nicht die Pins A4 und A5 für etwas anderes verwenden, auf einem MEGA-Board nicht die Pins 20 und 21 und auf einem Leonardo-Board nicht die Pins 2 und 3.

HI jurs sehr vielen Dank es hat funktioniert und ich habe einiges dazugelernt.
VIelen Dank für den Support und den großartigen Erklärungen.

Habe ein kurze Verständnisfrage, warum muss man beim Arduino bei der I2C-kommunikation das endTransmission() davor setzen, um das ankommende Byte vom Slave auszulesen?

Müsste ich nicht das Byte zuerst auslesen und dann die I2C-KOmmunikation beenden?

Das write() ist dazu da die Speicheradresse zu setzten bei der der Zugriff anfängt. Bei Devices mit mehreren Adressen wird dann bei jedem Zugriff (egal ob lesend oder schreibend) intern die Adresse um 1 erhöht. Deshalb muss man nur die Start-Adresse setzen.

Wie ich oben gesagt habe, ist endTransmission() dazu da den Sendepuffer auf den Bus zu schreiben. Vorher schreibt write() nur in einen Puffer. Aber wirklich gesendet wird da noch nichts.
Ähnlich werden die Daten schon mit requestTransmission() gelesen und mit read() aus dem Eingangspuffer entfernt.

Ah ok danke sehr frage mich nur auch in Büchern das immer falsch gemacht wird.
Siehe hier:
http://books.google.de/books?id=CSei8-a3C30C&pg=PA160&lpg=PA160&dq=lm75+arduino&source=bl&ots=qpDdlbdMlJ&sig=ghvquYx8E_zY9KaU-i-EuA_F1cY&hl=de&sa=X&ei=ol3-UscJkrWEB_TfgYAP&redir_esc=y#v=onepage&q=lm75%20arduino&f=false

Wäre das dann falsch in dem Buch?

Weiß nicht. Das ist aber falsch. Auch der LM75 hat mehrere Register und sowie es aussieht Auto-Inkrement. In dem Fall geht es vielleicht, da man immer nur das eine Register ständig ausliest. Aber wenn du das in komplexerem Code so machst, und mehr Register ausliest, bekommst du Probleme.

Aus der Doku geht das auch hervor:

Ends a transmission to a slave device that was begun by beginTransmission() and transmits the bytes that were queued by write().

Sagt klar, dass da mit nur ein Sende-Vorgang abgeschlossen wird.

Ah danke sehr :smiley:

milito:
Wäre das dann falsch in dem Buch?

Ja, Listing 5.6 in dem Buch ist fehlerhaft.
Der Zugriff entspricht nicht den üblichen Standards beim Zugriff auf I2C-Slaves.

Da aber in dem Programm stets nur das Temperaturregister beginnend mit Register 0 ausgelesen werden soll, ist es in dem Fall egal, dass das Setzen des Registers 0 mit dem Code (vermutlich) fehlschlägt: Register 0 ist ja auch bereits standardmäßig nach dem Power-On Reset des Sensors als Register gesetzt.

Wenn Du (bzw. der Buchautor) also sowieso Register 0 nach dem Power-On gesetzt hat, ist es hinterher egal, ob Du einen fehlerhaften Code zum Setzen von Register 0 programmierst. Sobald der Leserequest kommt, wird die fehlerhafte Anforderung ignoriert und das Auslesen beginnt.

Problematischer wäre es, wenn der Buchautor mit seinem Code beginnend ab Register 2 oder 4 etwas auslesen wollte: Das würde wohl kaum funktionieren.

Im seinem nachfolgenden Listing 5.7 läßt der Buchautor das (bei ihm sowieso fehlerhaft implementierte) Setzen des Registers gleich komplett weg und liest immer nur 2 Bytes von der aktuelle Registeradresse aus, also von der Default-Registeradresse 0.

Vergiss das und mache es bei I2C so wie ich es in LM75 Problem mit Temperaturmessung - #5 by jurs - Deutsch - Arduino Forum gepostet habe. Denn nicht bei jedem Sensor möchtest Du immer nur aus Register 0 etwas auslesen.