Forum: Mikrocontroller und Digitale Elektronik LM75 mit MSP430F1611


von Markus S. (Gast)


Angehängte Dateien:

Lesenswert?

Hallo zusammen,
ich arbeite mich ganz langsam in die Programmierung von einem MSP430 ein 
und setzte meine Ziele langsam immer höher. Jetzt möchte ich gerne einen 
Temperaturfühler LM75 auslesen.
Ich möchte dabei keinen Interrupt benutzen, weil ich die Sache mit den 
Interrupts einfach noch nicht kapiere.
Als Compiler benutze ich den IAR Freeware.
Ich habe mich auch schon durch den User guide und das Datenblatt von dem 
LM75 gekämpft. Leider ist mein Englisch nicht das allerbeste, deshalb 
habe ich einige Verständnisprobleme.
Trozdem will ich noch nicht aufgeben.
Ich habe an meine Testplatine einen LM75 mit der Adresse 1001100 mit 
einem ca. 2m langem Kabel angeschlossen. Die beiden Pullup Widerstände 
haben einen Wert von 10k. Ausgeben will ich den Messwert auf eine 
7-Segmentanzeige.
Ich habe mich beim Programmieren an einem Beispiel von Texas Instruments 
gehängt, habe aber die Interrupt Routine entfernt.

Bitte hängt mich nicht gleich auf wenn ihr meinen Code seht, den ich 
zähle mich noch zu den Anfängern.
Ach ja, den Zahlenwert den der LM75 ausgeben soll habe ich noch nicht so 
gewandelt, das da ein vernünftiger Temperaturwert heraus kommt. Ich will 
ja erst mal sehen ob überhaupt was rauskommt. Denn bisher steht im 
I2CDRB immer nur 00 drin.
Ich hoffe ihr könnt mir helfen.

Danke
Markus

von MichiB (Gast)


Lesenswert?

Hallo,

ich kenne leider das I2C-Handling vom MSP430 nicht.

Aber, du musst 2 Bytes auslesen. Das erste Byte ist bei ~25°C immer 
0x00.
Du musst 2 Bytes innerhalb einer I2C-Transmission auslesen.

Ich kann leider nicht erkennen welche Baudrate du eingestellt hast. 2m 
sind schon relativ weit für I2C bei hohen Baudraten.

von XXX (Gast)


Lesenswert?

Hallo

Was soll das denn werden:
> for(int i=0; i<20000; i++);

Sowas sollte jeder gute Compiler wegoptimieren!

Gruß
Joachim

von Markus S. (Gast)


Lesenswert?

Hi MichiB,
erst mal Danke für deine Antwort. Ich habe in meinem Programm die Bytes 
auf 2 gesetzt, mit:

 U0CTL |= I2C + SYNC;       // Switch USART0 to I2C mode
  U0CTL &= ~I2CEN;          // Recommended I2C init procedure
  I2CTCTL = I2CSSEL_2;      // SMCLK
  I2CSCLH = 0x03;           // High period of SCL
  I2CSCLL = 0x03;           // Low period of SCL
  I2CNDAT = 0x02;           // Transmit two byte
  I2CSA = 0x4c;             // Slave address 1001100
  U0CTL |= I2CEN;           // Enable I2C, 7 bit addr,

leider ist das Ergebnis das Gleiche.
Werden beide übertragene Bytes im I2CDRB gespeichert oder gibt es für 
jedes Byte ein extra Register?

Die Baudrate weiss ich leider auch nicht. Das habe ich einfach aus dem 
Beispiel von TI Übernommen und gehofft dass es passt. Denn ich habe 
gelesen, dass es bei der Baudrate nicht so genau drauf ankommt.n Ich 
hoffe das war kein Fehler.

Markus

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Markus S. schrieb:
> Werden beide übertragene Bytes im I2CDRB gespeichert oder gibt es für
> jedes Byte ein extra Register?

Die landen nacheinander in diesem Register.

Du solltest Dir mal die Codebeispiele von TI ansehen, da sind auch 
mehrere dabei, die die I2C-Schnittstelle des 'F1611 betreffen.

von Markus S. (Gast)


Lesenswert?

@Joachim
weil die Temperaturauslesung in einer Enlosschleife läuft, und ich 
gelesen habe das der LM75 nur ca. 10 Messungen pro Sekunde schafft, 
dachte ich, ich gebe ihm etwas Zeit. Zumal ich es mit dem Messen nicht 
eilig habe.
:o)

Markus

von Markus S. (Gast)


Lesenswert?

@Rufus
ich werde mal versuchen ob ich Beispiele finde.

Danke
Markus

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?


von XXX (Gast)


Lesenswert?

Hallo

Ich dachte mir, daß das eine Wartezeit sein soll. Aaaaaber: Viele
Compiler denken sich, was soll denn das werden? Da passiert ja nichts
außer das eine Variable hochgezählt wird, und dann wirdse garnicht
mehr gebraucht. Also weg mit der ganzen for-Schleife.

Es kann also sein, wenn dein Compiler dazugehört, das die komplette
Schleife einfach rausgeschmissen wird.

Hast du für deinen Compiler keine delay-Funktion? Ist irgendwie
sicherer und man weiß dann auch exakt, wie lange gewartet wird.

Gruß
Joachim

von MichiB (Gast)


Lesenswert?

Hi,

leider verstehe ich das TI Beispiel nicht ohne das Datenblatt im Detail 
gelesen zu haben.

Allerdings habe ich im Beispiel gelesen:
//  ACLK = n/a, MCLK = SMCLK = TACLK = I2CCLOCK = DCO~ 800k

800k sind meiner Erfahrung nach viel zu viel für 2m.
Mach die Leitung mal so kurz wie möglich.

von Markus S. (Gast)


Lesenswert?

man ihr ja der Wahnsinn,
ich komme mit dem schreiben gar nicht so schnell nach.  :o))

@Rufus
vielen Dank für die Beispiele. Ich habe mal kurz reingschaut und ein 
paar überflogen. Es wird dort natürlich auch sehr viel mit Interrupts 
gearbeitet (was ich ja noch vermeiden will). Aber ich habe auch ein paar 
Beispiele gefunden wo drei Bytes übertragen werde. Aber den Ablauf der 
da verwendet wird den muß ich erst mal verdauen und verstehen.
Aber trozdem vielen Dank für deine Hilfe.

@Joachim
bislang habe die for Schleifen sehr gut funktioniert und wurden nie 
rausgeschmissen.
Das mit der delay-Funktion muß ich mir mal ansehen ob ich da was finde.
Vielen Dank für den Tip

Markus

von Markus S. (Gast)


Lesenswert?

@MichiB
ok, das mit der kürzeren Leitung werde ich ausprobieren. Aber wenn ich 
dich richtig verstehe, kann ich auch die Frequenz runter setzen oder? 
Ich weiß noch nicht genau wie das geht aber so viel ich weiß kann man ja 
einen Vorteiler setzten. Denn ich möchte irgendwann mal längere Kabel 
einsetzen (wenn das geht).
Gibt es eine Berechnung, Regel oder Fausformel wie man die Kabellänge 
mit der Übertragungsfrequenz abstimmt?

Markus

von Jörg S. (joerg-s)


Lesenswert?

XXX schrieb:
> Ich dachte mir, daß das eine Wartezeit sein soll. Aaaaaber: Viele
> Compiler denken sich, was soll denn das werden? Da passiert ja nichts
> außer das eine Variable hochgezählt wird, und dann wirdse garnicht
> mehr gebraucht. Also weg mit der ganzen for-Schleife.
Der IAR steht von Hause aus auf "Optimization" "None". D.h. er optimiert 
überhaupt nichts weg. Von daher geht das mit der Schleife problemlos.

von Imon (Gast)


Lesenswert?

Ich hoffe du machts auch noch ein wenig an der Temperatur
und das ist nur ein vereinfachtes Beispiel.
1
unsigned int Zahl = I2CDRB;  //Temperaturwert an Variable Übergeben

denn soweit ich das im Datenblatt sehe sind die 5 niederwertigsten bits 
immer 0, die solltest du also durch shiften oder ähnliches los werden
außerdem ist deine Zahl unsigned soweit ich das sehe ist MSB high ein 
Hinweis das die Temp negativ ist und du ein 2 Kompliment bilden musst.

was du in denn Beispiel mist sind Mond Zahlen und keine Temperatur.

das du 2 Bit lesen musst haben dir schon andere gesagt. leider hatte ich 
mit dein Prozessor noch nicht zu tun so das ich dir da keine Hinweise 
geben kann wie das geht.

von MichiB (Gast)


Lesenswert?

Hi,

ich denke du benötigst folgendes.


I2CNDAT = 0x02;                           // Transmit 2 bytes

for (;;)
{
  U0CTL |= MST;                        // Master
  I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  i1 = I2CDRB;                         // Receive MSByte from DAC
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  i2 = I2CDRB;                         // Receive ControlByte from DAC
  while ((I2CTCTL & I2CSTP) == 0x02);  // Wait for Stop Condition
}

von Imon (Gast)


Lesenswert?

Hi ich habe das ganze noch um die Temperatur Berechnug ergänzt

lmreg ist ein unsignend short , temp ein double oder float in denn 
folgenden Beispiel. gegebenfalls wäre es sinnvol das double gegen ein 
int auszutauschen, in tausensdel grad zu rechnen und bei deiner ausgabe 
den Dezimal Punkt manuell zu setzen.

1
I2CNDAT = 0x02;                           // Transmit 2 bytes
2
3
for (;;)
4
{
5
  U0CTL |= MST;                        // Master
6
  I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
7
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
8
  i1 = I2CDRB;                         // Receive MSByte from DAC
9
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
10
  i2 = I2CDRB;                         // Receive ControlByte from DAC
11
  while ((I2CTCTL & I2CSTP) == 0x02);  // Wait for Stop Condition
12
13
  lmreg= ( (i1 & 0xFFUL) << 8 ) | ( i2 & 0xFFUL) ; // build ushort value
14
  lmreg >>= 5;                         // Remove unneeded 0 Bytes
15
16
  if ( lmreg & ( 1 << 10 ) ) {
17
        // Temp less 0°C
18
        lmreg = ~lmreg & 0x01FFUL ; //  1 compliment of 9 bit value
19
        lmreg++;                    //  2 compliment 
20
        temp = lmreg * -0.125;      //  calculate Temp in degree
21
  }
22
  else {
23
        temp = lmreg * 0.125;       // calculate Temp in degree      
24
  }
25
26
}

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Imon schrieb:
> gegebenfalls wäre es sinnvol [...] in tausensdel grad zu rechnen

Definitiv nicht. Es ist bereits ein nur selten erreichtes Kunststück, 
die Temperatur auf 0.1° genau zu messen, wirklich sinnvoll ist bei den 
meisten elektronischen Messverfahren eine Rundung auf ganze 0.5°- oder 
gar ganze 1°-Schritte.
Die 0.1°-Anzeige der meisten elektronischen Thermometer ist schlichtweg 
gelogen.

von Markus S. (Gast)


Lesenswert?

@Imon,
ich hatte ja oben schon geschrieben dass ich den Wert von dem 
Temperaturfühler noch umwandeln muß. Dass du das jetzt schon gemacht 
hast, ist super klasse!! Vielen Dank dafür.

@MichiB
Danke für das Beispiel. Genau das hatte ich mir auch schon rausgesucht, 
aber ich hatte bislang noch keine Zeit es auszuprobieren.

@Rufus
das mit der Nachkommastelle bei der Temperatur ist für mich kein 
Problem. Ich brauche nur die Stellen vor dem Komma das reicht mir völlig 
aus

Vielen Dank noch mal für Eure Hilfe

Markus

von Markus S. (Gast)


Lesenswert?

Hi zusammen,
ich habe mal den Programvorschlag von MichiB und Imon getestet. Hat 
leider nicht funktioniert.
Das lange Kabel zu meinem Temeraturfühler habe ich auf 10cm gekürzt.
Um zu testen wie weit das Programm überhaupt kommt, habe ich mal an 
verschiedenen Stellen einen Ausgang (an denen je eine LED angeschlossen 
ist) Programmiert.

POUT1=0x01;    //LED 1

for (;;)
{
  U0CTL |= MST;                        // Master
  POUT1=0x02;     //LED 2
  I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  POUT1=0x04;     //LED 3
  i1 = I2CDRB;                         // Receive MSByte from DAC
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  i2 = I2CDRB;                         // Receive ControlByte from DAC
  while ((I2CTCTL & I2CSTP) == 0x02);  // Wait for Stop Condition
}

LED3 leuchtet leider nicht. Das heißt das Programm kommt nicht aus der 
while Schleife (while ((I2CIFG & RXRDYIFG) == 0);) heraus.
Ich habe daraufhin noch  mal die Anschlüsse an meinem LM75 überprüft. 
Ich habe die Adresse Überprüft d.h. ich habe an den A0 bis A2 gemessen 
ob die Anschlüsse richtig angelötet sind. Aber das ist alles ok.
Dann habe ich versucht das SCL Signal mit einem Oscilloscope zu messen. 
Das Ergebnis ist schwer zu beschreiben. Es war ein high Signal von 1.5V 
mit schmalen Impulsen zu low. Die Pulsabstände waren 10ms. Dieses Signal 
hatte ich auf SCL und SDA.
Kann jemand damit etwas anfangen?

Markus

von Markus S. (Gast)


Lesenswert?

Hallo Leute,
verzeiht mir meine Dämlichkeit.
Ich habe meinen Fehler gefunden. Ich habe bei der Adresse des LM75 die 
Reihenfolge A0 bis A2 vertauscht. Die Adresse von meinem Fühler ist 
1001001 und nicht 1001100. Und siehe da es kommt was zurück. Jetzt 
versuche ich das Ergebnis zu wandeln und auf meine 7-Segment Anzeige 
auszugeben.
Sollte ich damit noch Probleme haben, dann melde ich mich noch mal.

Markus

von Wolfgang-G (Gast)


Lesenswert?

>Es ist bereits ein nur selten erreichtes Kunststück,
>die Temperatur auf 0.1° genau zu messen, wirklich sinnvoll ist bei den
>meisten elektronischen Messverfahren eine Rundung auf ganze 0.5°- oder
>gar ganze 1°-Schritte.
Da hast Du schon Recht. Man muss immer den Messwert beurteilen, wie viel 
Stellen nach oder auch vor dem Komma brauchbar sind.
Aber um einen Trend erkennen zu können, kann man auch die 0,1° Stelle 
gut verwenden. Deshalb alle Stellen anzeigen, und danach beurteilen.
MfG

von Markus S. (Gast)


Lesenswert?

Hallo zusammen,
ich habe gestern verzweifelt versucht meinen LM75 auszulesen und den 
Messwert über die UART Schnittstelle auf dem PC auszugeben.
Hat natürlich nicht geklappt.
Nach stundenlangen versuchen bin ich zu dem Entschluss gekommen das mit 
dem Auslesen des LM75 irgend was nicht stimmt.


for (;;)
{
  U0CTL |= MST;                        // Master
  POUT1=0x02;     //LED 2
  I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  i = I2CDRB;                          // Receive MSByte from LM75
  i = i << 8;
  highbyte = I2CDRB;
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  i = i + I2CDRB;                      // Receive ControlByte from LM75
  lowbyte = I2CDRB;
while ((I2CTCTL & I2CSTP) == 0x02);    // Wait for Stop Condition

i= i/2;

i per UART auf PC schicken
}

Zahlen auf dem PC schicken funktioniert super. Habe ich ausreichend 
getestet.
Ich habe die einzelnen Bytes (low und high) zum Testen einzeln 
ausgelesen und auf dem PC ausgegeben, aber leider machen die Zahlen die 
da rauskommen überhaut keinen Sinn. Teilweise kommen auch nur 
Hieroglyphen.
nach dem Datenblatt von dem LM75 wird eine 9 Bit breite Zahl ausgegeben. 
Teilt der LM75 diese automatisch in zwei 8 Bit Signale auf und schickt 
die? Dann müsste das eine Bit (high) ja immer Null anzeigen solange ich 
einen positiven Temperaturwert messe. Ist das so? oder habe ich das 
System total falsch verstanden?

@Imon,
ich habe versucht deine Auswertung zu verstehen. Leider ist es mir nicht 
gelungen.
Was heißt 0xFFUL?
Das verschieben der Stellen um 8 Positionen nach links verstehe ich auch 
noch, aber wieso schiebst du um 5 Stellen nach rechts?
Und warum multipizierst du dem Messwert mit 0.125?
Ich hätte den Wert durch 2 geteilt.


lmreg= ( (i1 & 0xFFUL) << 8 ) | ( i2 & 0xFFUL) ; // build ushort value
  lmreg >>= 5;                         // Remove unneeded 0 Bytes

  if ( lmreg & ( 1 << 10 ) ) {
        // Temp less 0°C
        lmreg = ~lmreg & 0x01FFUL ; //  1 compliment of 9 bit value
        lmreg++;                    //  2 compliment
        temp = lmreg * -0.125;      //  calculate Temp in degree
  }
  else {
        temp = lmreg * 0.125;       // calculate Temp in degree


Markus

von Jörg S. (joerg-s)


Lesenswert?

Markus S. schrieb:
> nach dem Datenblatt von dem LM75 wird eine 9 Bit breite Zahl ausgegeben.
> Teilt der LM75 diese automatisch in zwei 8 Bit Signale auf und schickt
> die?
Ja

> Dann müsste das eine Bit (high) ja immer Null anzeigen solange ich
> einen positiven Temperaturwert messe. Ist das so?
Wenn du das MSB meinst, ja.

>Und warum multipizierst du dem Messwert mit 0.125?
Imon scheint einem LM75A zu haben, der hat eine größere Auflösung wie 
der "normale" LM75. Bei dem ist im Low Byte noch Bit 6 und 5 definiert.

von Markus S. (Gast)


Lesenswert?

Hallo Jörg,

>> Dann müsste das eine Bit (high) ja immer Null anzeigen solange ich
>> einen positiven Temperaturwert messe. Ist das so?
>Wenn du das MSB meinst, ja.

Was heißt MSB?

Leider habe ich bei dem highbyte nicht Null als Ergebnis sondern, 
Zahlenwerte. Das verstehe ich leider nicht.

Danke
Markus

von Markus S. (Gast)


Lesenswert?

Hallo,
ich war in letzter Zeit sehr mit anderen Dingen beschäftigt. Aber jetzt 
soll es wieder mit Hochdruck weiter gehen.
Leider hat sich mein Problem nicht geändert. Hat noch jemand einen Tip 
für mich?

Danke
Markus

von Markus S. (Gast)


Lesenswert?

hat wirklich niehmand eine Idee

Markus

von Jörg S. (joerg-s)


Angehängte Dateien:

Lesenswert?

Markus S. schrieb:
> Was heißt MSB?
http://de.wikipedia.org/wiki/Bitwertigkeit

> Leider habe ich bei dem highbyte nicht Null als Ergebnis sondern,
> Zahlenwerte. Das verstehe ich leider nicht.
Das High-Byte ist ja auch deine Vorkommastelle.

von Imon (Gast)


Lesenswert?

Markus S. schrieb:
> @Imon,
> ich habe versucht deine Auswertung zu verstehen. Leider ist es mir nicht
> gelungen.
> Was heißt 0xFFUL?

das beutetet ich will die Konstante 0xFF als unsigned long (UL) haben, 
damit gebe ich den Kompiler einen Hinweiss wie breit die Konstante ist
um nicht ggf mit Schmutz effekten zu rechen ist also wie
0x00000000000000FF nur leichter zu schreiben.

> Das verschieben der Stellen um 8 Positionen nach links verstehe ich auch
> noch, aber wieso schiebst du um 5 Stellen nach rechts?
weil das Datenblatt sagt die unteren 5 Bits sind 0 die brauche ich also 
nicht und will sie los werden sonst muss ich sie in der Rechnung 
berücksichtigen.

> Und warum multipizierst du dem Messwert mit 0.125?
> Ich hätte den Wert durch 2 geteilt.

weil das so in denn Datenblatt steht das ich hatte. Ich habe das ganze 
nach den NXP Datenblatt für den LM75B entwickelt dort steht die Formel 
drin

www.nxp.com/documents/data_sheet/LM75B.pdf

wobei wenn ich den LM75B mit den Ausschnitt vergleiche den Jörg S. 
gepostet hat, musst du Tatsächlich um 6 Bits schieben (statt der 5) und 
durch 2 Teilen.Der LM75B scheint eine gering höhere Auflösung zu haben 
als der LM75.

>
>
> lmreg= ( (i1 & 0xFFUL) << 8 ) | ( i2 & 0xFFUL) ; // build ushort value

>   lmreg >>= 5;                         // Remove unneeded 0 Bytes
>
>   if ( lmreg & ( 1 << 10 ) ) {
>         // Temp less 0°C
>         lmreg = ~lmreg & 0x01FFUL ; //  1 compliment of 9 bit value
>         lmreg++;                    //  2 compliment
>         temp = lmreg * -0.125;      //  calculate Temp in degree
>   }
>   else {
>         temp = lmreg * 0.125;       // calculate Temp in degree
>
>
> Markus

von Markus S. (Gast)


Lesenswert?

Herlichen Dank euch beiden,
das hilft mir erst mal wieder weiter. Zumindest kann ich jetzt erst mal 
weiter probieren.

@Jörg,
da ich die Nachkommastelle sowieso nicht brauche, müsste es doch 
reichen, wenn ich das High-Byte auslese. Oder ist das Falsch?

@Imon,
>das beutetet ich will die Konstante 0xFF als unsigned long (UL) haben,
>damit gebe ich den Kompiler einen Hinweiss wie breit die Konstante ist
>um nicht ggf mit Schmutz effekten zu rechen ist also wie
>0x00000000000000FF nur leichter zu schreiben.

Das ist sehr interessant. Wo kann man so etwas nachlesen? Sind das 
Grundkenndnisse der C-Programmierung? Oder ist das speziell beim MSP 
(oder auch bei anderen µC) so?

Danke
Markus

von Tom A. (thomas_a)


Lesenswert?

Nur das High Byte auslesen geht meines wissens nicht. Wenn du eine 
anfrage schickst, dann werden über den i2c bus aufjedenfall das High und 
low Byte verwendet.

Du kannst auf der µC Seite aber nur das High Byte auswerten.

(Ich hab jetzt nicht alles durchgelesen, aber ich habe oben irgendwas 
von 0,1°C gelesen. Das LSB hat meines wissens nur die Wertigkeit x,0 
oder x,5)
Wahrscheinlich ist das aber schon gelöst, weil ich hab beim 
runterscrollen iwo das Datenblatt gesehen ;)

Grüße Tom

von Jörg S. (joerg-s)


Lesenswert?

Tom A. schrieb:
> Nur das High Byte auslesen geht meines wissens nicht. Wenn du eine
> anfrage schickst, dann werden über den i2c bus aufjedenfall das High und
> low Byte verwendet.
Der LM75 ist ja nur Slave. Wenn der Master nach dem ersten Byte ein 
Stop/NAK sendet kann der LM ja nichts weiter senden :)

von Tom A. (thomas_a)


Lesenswert?

ja gut, das ist richtig. Ist halt die Frage ob das der aufwand wert ist 
oder ob man die Daten halt verwirft ;)

Kommt halt immer auf die Anforderungen drauf an. In meinem Fall hat es 
ausgereicht die Daten zu verwerfen :D

von Oliver J. (skriptkiddy)


Lesenswert?

Tom A. schrieb:
> Kommt halt immer auf die Anforderungen drauf an. In meinem Fall hat es
> ausgereicht die Daten zu verwerfen :D

Wenn man sich überlegt, dass der LM75 in allen seiner Ausführungen nur 
auf 2 bis 3 Kelvin genau ist, macht es nur Sinn, das Lowbyte 
auszuwerten, wenn man das Quantisierungsrauschen klein halten will (z.B. 
für eine Temperaturregelung). Für ne einfache Temperaturmessung mit 
Anzeige, ist das Highbyte mehr als ausreichend.

Gruß Skriptkiddy

von Imon (Gast)


Lesenswert?

Markus S. schrieb:
> Das ist sehr interessant. Wo kann man so etwas nachlesen? Sind das
> Grundkenndnisse der C-Programmierung? Oder ist das speziell beim MSP
> (oder auch bei anderen µC) so?

das sind grundlagen der Sprache C sollte irgendwo im ISO9899:1990 
aufgeführt sein (Hoffe ich ), denn um ehrlich zu sein weiss ich garnicht 
mehr genau wo ich mir das abgeschaut habe, aber es ist allgemein 
gültiges C und Grade bei Bitopertationen habe ich mir schon ein paar mal 
ins Knie geschossen weil die
Konstanten zu klein gewählt habe.

von Markus S. (Gast)


Lesenswert?

Hallo zusammen,
ich denke das mit dem Auslesen von den Bits habe ich dank eurer Hilfe 
jetzt im Griff bekommen. Durch Bitverschiebung habe ich auch 
herausgefunden wie ich das Bit für die Nachkommastelle wegbekomme. Dann 
habe ich auch mal nur das Highbyte ausgewertet. Das Ergebnis war das 
gleiche. Nämlich das die Zahlenwerte nicht stimmen können.
Denn wenn ich das ausgelesene Highbit durch 2 teile, dann schwankt die 
Temperatur zwischen 9 und 7 Grad C. Bei einer Raumtemperatur um die 23 
Grad (gemessen mit einem anderen Thermometer).
Muss man den LM75 vorher doch noch irgendwie programmieren (abgleichen)?
Ist das normal das die Ausgegebene Temperatur dauernd um 3 Grad schwankt 
(ich lese jede Sekunden einen Wert aus)
Danke für eure Hilfe
Markus

von Jörg S. (joerg-s)


Lesenswert?

>Denn wenn ich das ausgelesene Highbit durch 2 teile
Wozu das? Das brauchst du nur wenn du die 0,5° noch in das Ergebnis 
"hineingeschoben" hast. Das high-Byte für sich allein ist genau der 
Temperaturwert den du haben willst.

von Markus S. (Gast)


Lesenswert?

Stimmt du hast recht.
Aber dann schwanke die Werte von 15 bis 18 Grad und nicht um 23 Grad

von Markus S. (Gast)


Lesenswert?

Hallo zusammen,
da ich nach langem herumprobieren nicht herausbekommen habe, warum der 
LM75 eine zur niedriegere Temparatur ausgibt habe ich den Wert einfach 
mit 1,25 multipliziert und damit funktioniert es ganz gut. wenn jemand 
noch einen besseren Tip hat, würde ich mich sehr darüber freuen.
Das schwanker der Temperatur konnte ich etwas reduzieren in dem ich 10 
Werte ermittelt habe und daraus den Mittelwert gebildet habe.
Nochmal danke für eure Hilfe

Markus

von Tom A. (thomas_a)


Lesenswert?

Warum schwankt sie den so. Also mein LM ist auch etwas launisch und gibt 
je nach Tagesverfassung ein wenig einen unterschiedlichen Wert aus.

Wie oben schon von jmd. gesagt und wie es auch aufm Datenblatt auf der 
ersten Seite steht ist der Fehler des Sensors max. +-3 bzw +-2 Grad.

Ich weiß nicht ob man dann von einem Offset reden kann und denn einfach 
mit einem Faktor ausgleichen kann.

Bei mir ist der Fehler ehr gleichverteilt und schwankt um die 
Raumtemperatur.

Grüße Tom

von Jörg S. (joerg-s)


Lesenswert?

Mein LM75 schwankt nicht. Da springt höchtens das letzte Bit mal.

Bist du sicher das kein NAK zurück kommt?
Wie sehen die Werte denn jetzt aus (in HEX)?
Was sendest du genau zum Sensor?

von Markus S. (Gast)


Lesenswert?

Hallo Tom und Jörg,
ich bin immer noch am verzweifeln. Ich kriege das Problem mit dem 
Temperaturauslesen einfach nicht in den Griff.
Ich hatte zwischendurch mal gedacht es funktioniert, aber das war ein 
Fehler.

Ich lese bei den LM75 nur noch das Highbyte aus. Die Zahlenwerte waren 
zu tief. Dashalb habe ich sie mit dem Faktor 1,25 multipliziert. Das war 
dann so weit in Ordung aber die Werte habe immer noch geschwankt. Ich 
habe die Werte in einer for Schleife 32 mal ausgelesen und das mit Hilfe 
von >> 5 durch 32 dividiert.
Die ganze Messung und die Ausgabe läuft in einer Enlosschleife. Am Ende 
der Schleife habe ich noch eine Wartezeit von ca. einer Sekunde 
eingebaut so das ich jede Sekunde einen neuen Messwert bekommen. Aber 
der Wert wechselt bei Raumtemperatur pro Sekunde zwischen 14 und 19 Grad 
und das sehr regelmäßig.

Dann habe ich versucht dass der LM75 dauernd Werte misst aber ich nur 
ca. jede Sekunde den Wert anzeigen lasse. Da war der angezeigte Wert 
stabil bei 18 Grad aber er hat sich auch nicht geändert wenn ich den 
Fühler an meiner Heizung erhitzt habe.
Dann habe ich einen zweiten LM75 an die Busleitung geklemmt. Der 
schwankt noch schlimmer (zwischen -13 und 11 Grad) und das sehr 
unregelmäßig, obwohl er über die selbe Funktion ausgelesen wird wie der 
erste Fühler.

Ich habe schon so viel probiert und umgeklemmt, aber leider kein 
positives Ergebnis erhalten.
Denn ich nehme an, wenn ich einen Hardware Fehler hätte, dann dürften 
doch eigenlich gar keine Werte aus dem LM75 kommen oder?

Jörg schrieb:
>Bist du sicher das kein NAK zurück kommt?
>Wie sehen die Werte denn jetzt aus (in HEX)?
>Was sendest du genau zum Sensor?

wie kann ich rausfinden ob ein NAK zurückkommt?
Wie die Werte in HEX aussehen weiss ich nicht ich pflücke sie mit einer 
Funktion auseinander, addiere 30 HEX dazu und schicke sieh dann auf dem 
PC und Hyperterminal zeigt mir nur die richtigen Zahlenwerte an.
Die Funktion um den Sensor auszulesen sieht zur Zeit so aus:


diese zwei Zeilen stehen im Main Programm
I2CSA = 0x49;                             // Slave address 1001001
int Zahl = fAuslesen();

int fAuslesen()
{
 int Mitteltemp = 0;
 int Zahlx = 0;
 int highbyte = 0;
  for(int l=0; l<32;l++)
  {
    U0CTL |= MST;                        // Master
    I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
    while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be 
ready
    highbyte = I2CDRB;                   // Receive MSByte from LM75
    while ((I2CTCTL & I2CSTP) == 0x02);  // Wait for Stop Condition
    Mitteltemp += highbyte;              //Werte addieren
    for(int p=0;p<100;p++);              //kleine Pause
  }
  Zahlx = Mitteltemp >> 5;          //alle addierten Werte durch 32 
teilen
  return Zahlx;
}

Ich hoffe jemand kann mir noch einen Tip geben.

Danke
Markus

von Tom A. (thomas_a)


Lesenswert?

mh... also hast du dir mal den Datenstrom auf dem Oszi angeschaut?
Ich würde mal damit starten. Dann kannst du auch gleich mal ausrechnen, 
ob die Daten die gesendet werden mit deinen Empfangenen übereinstimmen.

Also Oszi auf SDA und SCL hängen.

Im Datenblatt vom LM75 ist eigentlich für jeden Fall das passende 
Diagramm.

Dann siehst du mal ob der LM75 die richtige Temperatur liefert. So 
kannst du mal Software und Hardware Fehler separieren.

Grüße
Thomas

von Jörg S. (joerg-s)


Lesenswert?

>wie kann ich rausfinden ob ein NAK zurückkommt?
Was passiert denn wenn du die falsche Adresse ansprichst (z.B. anstatt 
0x49 mal 0x50)?

>Wie die Werte in HEX aussehen weiss ich nicht ich pflücke sie mit einer
>Funktion auseinander, addiere 30 HEX dazu und schicke sieh dann auf dem
>PC und Hyperterminal zeigt mir nur die richtigen Zahlenwerte an.
Dann bau das mal um das du die empfangen Werte mal direkt sehen kannst.


>I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
Ich hab jetzt nicht im Manual nachgesehen, aber das sieht irgendwie 
falsch aus Start und Stop gleichzeitig zu setzen.

Wo wird in deinem Code I2CEN auf 1 gesetzt?
Wo ist der Rest der initialisierung vom I2C-Bus?

von Markus S. (Gast)


Lesenswert?

@Thomas,
nein das mit dem Oszi habe ich noch nicht versucht. Mal sehen ob ich was 
damit rauskriege.
Ich versuche auch noch die Zahlen direkt auf eine Siebensegmentanzeigen 
auszugeben aber leider habe ich da noch einen Hardware Fehler.
Danke für den Tip.

@Jörg,
>>wie kann ich rausfinden ob ein NAK zurückkommt?
>Was passiert denn wenn du die falsche Adresse ansprichst (z.B. anstatt
>0x49 mal 0x50)?

Dann bleibt das Programm in dieser Zeile stehen:

while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready

>>Wie die Werte in HEX aussehen weiss ich nicht ich pflücke sie mit einer
>>Funktion auseinander, addiere 30 HEX dazu und schicke sieh dann auf dem
>>PC und Hyperterminal zeigt mir nur die richtigen Zahlenwerte an.
>Dann bau das mal um das du die empfangen Werte mal direkt sehen kannst.

Ich habe keine Ahnung wie ich das machen soll. Denn Hyperterminal 
scheint die Daten immer als Hexwert auszulesen. (ich schicke ja Ziffer 
für Ziffer). Und damit der richtige Zifferwert auf dem Bildschirm 
erschient muß man immer 30HEX zu jeder Ziffer dazu addieren.
Aber das mit dem Übertragen auf dem PC Funktioniert gut denn wenn ich 
eine Feste Zahl z.B. 1234 übertragen lasse, erscheint die genaus so auf 
dem PC.

>>I2CTCTL = I2CSTT+I2CSTP;             // Initiate transfer
>Ich hab jetzt nicht im Manual nachgesehen, aber das sieht irgendwie
>falsch aus Start und Stop gleichzeitig zu setzen.
Ich habe das so verstanden, dass bei dieser Schreibweise nur gesagt 
wird, dass Startbit und Stopbit verwendet werden sollen. Und wann sie 
gesendet werden, dass macht das Protokoll automatisch (hoffentlich). Ich 
habe es auch so aus einem Beispiel von TI übernommen und Imon hat es 
weiter oben in seinem Beispiel auch so angegeben.

>Wo wird in deinem Code I2CEN auf 1 gesetzt?
>Wo ist der Rest der initialisierung vom I2C-Bus?

Main Programm

Deklaration vom UART

  P2SEL|=0x00;     // Port2 als input output benutzten
  P1DIR|=0xFF;    // Port1 sind die 8 LEDs
  P2DIR|=0xFF;      //Port2 sind die Latschsignale für 7-Segment decoder
  P3SEL |= 0x0a;    // Assign I2C pins to module
  P3OUT |= 0x05;     //am Port3 Pin 1+3 auf High setzen (Latch Pins)
  P1OUT = 0x00;
  U0CTL |= I2C + SYNC;     // Switch USART0 to I2C mode
  U0CTL &= ~I2CEN;         // Recommended I2C init procedure
  I2CTCTL = I2CSSEL_2;                      // SMCLK
  I2CPSC = 0x02;                            // Vorteiler
  I2CSCLH = 0x03;                           // High period of SCL
  I2CSCLL = 0x03;                           // Low period of SCL
  I2CNDAT = 0x01;                           // Transmit two byte
  U0CTL |= I2CEN;                           // Enable I2C, 7 bit addr,

  for (;;)
  {
    I2CSA = 0x49;                             // Slave address 1001001
    int Zahl = fAuslesen();
    TempSenden(Zahl);
             .
             .
             .

Gruß
Markus

von Jörg S. (joerg-s)


Lesenswert?

>Ich habe keine Ahnung wie ich das machen soll. Denn Hyperterminal
>scheint die Daten immer als Hexwert auszulesen.
Du hast doch ein JTAG Debugger, oder? Dann kannst dir die Werte doch mal 
in ein Array schreiben lassen und im Debugger ansehen.

>I2CTCTL = I2CSTT+I2CSTP;
Das Start, Stop scheint richtig zu sein. Allerdings ist das = Zeichen 
denke ich falsch. Damit überscheibst du dir die Werte die du vorher in 
I2CTCTL geschrieben hast. Besser wäre also |=
Auf welchen TI Beispiel basiert dein Code?

Kannst du mal einen Schaltplan von deinem Aufbau posten?

von Markus S. (Gast)


Angehängte Dateien:

Lesenswert?

Hi Jörg,

>Du hast doch ein JTAG Debugger, oder? Dann kannst dir die Werte doch mal
>in ein Array schreiben lassen und im Debugger ansehen.
Jetzt bringst du mich ein bisschen in Verlegenheit, denn ich habe so ein 
paar Verständnissprobleme bzgl. Debugger und Compiler (was, was 
bedeutet).
Also, ich verwende als Compiler das IAR Programm von TI. Die Daten 
übertrage ich mit dem JTAG Kabel auf eine OLMEX Platine. Ich kann, 
nachdem ich das Programm kompiliert habe, mit der Taste F11 die einzelen 
Programmschritte durchlaufen. Ich kann dabei auch die einzelnen 
Variablen anzeigen lassen. Aber wenn ich zu der Zeile komme wo der LM75 
ausgelesen wird (while ((I2CIFG & RXRDYIFG) == 0);  ), dann kann ich 
nicht weiterspringen. Ich denke in dem Einzelschrittmodus funktioniert 
die Kommunikation mit dem LM75 nicht.

>Das Start, Stop scheint richtig zu sein. Allerdings ist das = Zeichen
>denke ich falsch. Damit überscheibst du dir die Werte die du vorher in
>I2CTCTL geschrieben hast. Besser wäre also |=
habe ich ausprobiert, aber es macht keinen Unterschied

>Auf welchen TI Beispiel basiert dein Code?
fet140_i2c_13.c

>Kannst du mal einen Schaltplan von deinem Aufbau posten?
Mein Aufbau ist provisorisch auf einer Lochrasterplatine gebastelt mit 
Tastern am Port1 LEDs am Port2 und I2C und UART1 am Port3. Ich weiss 
nicht genau was du sehen willst. Ich bin leider noch kein großer Experte 
von eagle o.ä. Programme. Am liebsten hätte schnell ich eine Skizze 
gemacht aber ich kann im Moment nicht scannen. Also habe ich mal was in 
PowerPoint aufgemalt.
Ich hoffe du hast das gemeint (siehe Anhang).

Gruß
Markus

von Jörg S. (joerg-s)


Lesenswert?

>Also habe ich mal was in PowerPoint aufgemalt.
>Ich hoffe du hast das gemeint (siehe Anhang).
Ja, das hatte ich gemeint.

>Aber wenn ich zu der Zeile komme wo der LM75
>ausgelesen wird (while ((I2CIFG & RXRDYIFG) == 0);  ), dann kann ich
>nicht weiterspringen. Ich denke in dem Einzelschrittmodus funktioniert
>die Kommunikation mit dem LM75 nicht.
Doch, die funktioniert schon, nur sind die Unterbrechungen vom 
Einzelschrittmodus nicht so günstig und können zum abbruch der I2C 
Kommuniktion führen, dann bleibt der µC in der Schleife hängen.

Du könntest aber z.B. einen Breakpoint an die Stelle
Mitteltemp += highbyte;
setzen und dir anschauen was für ein Byte tatsächlich empfangen wurde.

>>Auf welchen TI Beispiel basiert dein Code?
>fet140_i2c_13.c
Schau dir auch mal fet140_i2c_1.c an, das ist eine Kommunikation mit 
einem LM75 (TMP100 ist die Version von Ti).

Bei der fet140_i2c_13.c könntest du auch mal die TXBytes() Funktion 
nutzen um ein Byte (0x00) zu senden. Dann steht der LM75 sicher auf dem 
Temperaturregister wenn du die Bytes abrufst.

Vielleicht wäre es auch besser beide (low und high) Bytes abzurufen. 
Nicht das es doch Probleme macht wenn nur immer das high-Byte gelesen 
wird.

von Markus S. (Gast)


Lesenswert?

Hi Jörg,

>Doch, die funktioniert schon, nur sind die Unterbrechungen vom
>Einzelschrittmodus nicht so günstig und können zum abbruch der I2C
>Kommuniktion führen, dann bleibt der µC in der Schleife hängen.
Danke jetzt weis ich endlich wofür der Breakpoint da ist und wie man ihn 
benutzt :o)
Leider brachte er keine neuen Erkenntnisse. Denn die empfangenen Bytes 
beinhalten genau das was der PC anzeigt ich habe ca. 20 mal das Programm 
gestartet, aber die ausgelesenen Bytes schwanken genauso wie es der PC 
anzeigt. Ich habe das Highbyte ausgelesen und auch den über 32 Werte 
gemittelten Wert. Es passt mit dem zusammen was der PC anzeigt.
Was ich überhaupt nicht verstehe das gemittelte Werte so gleichmäsig 
schwanken können zB. 27, 19, 27, 19, 27, 19, 26, 19, 26, 18, 26, 18, 
usw.
Die Werte erscheinen so ca. im Sekunden Abstand.
Ich habe versucht aus nur 2 Werten den Mittelwert zu ermitteln und habe 
auch versucht aus 64 Werten den Mittelwert zu ermitteln. Du kannst es 
glauben oder nicht, das Ergebnis ist immer fast das Gleiche. Ich drehe
noch durch.
Hier ist meine Funktion:

int fAuslesen()
{
 int Mitteltemp = 0;
 int Zahlx = 0;
 int highbyte = 0;
 int lowbyte = 0;
 for(int l=0; l<64;l++)
  {
  U0CTL |= MST;                        // Master
  I2CTCTL |= I2CSTT+I2CSTP;            // Initiate transfer
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  highbyte = I2CDRB;                   // Receive MSByte from LM75
  while ((I2CIFG & RXRDYIFG) == 0);    // Wait for Receiver to be ready
  lowbyte = I2CDRB;                    // Receive ControlByte from LM75
  while ((I2CTCTL & I2CSTP) == 0x02);  // Wait for Stop Condition
  Mitteltemp += highbyte;
  for(int p=0;p<1000;p++);
  }
 Zahlx = Mitteltemp >> 6;
 lowbyte >>=7;
 return Zahlx;
}


>Schau dir auch mal fet140_i2c_1.c an, das ist eine Kommunikation mit
>einem LM75 (TMP100 ist die Version von Ti).
Habe ich schon gemacht, aber da ich mit den Interrupts noch meine 
Schwierigkeiten habe, habe ich mir das anderes Beispiel rausgesucht.
Aber wenn ich das richtig sehe wird da nichts anderes gemacht als in 
meinen Programm. Ausser das dort ein Interrupt genutzt wird.
Ich habe auch schon versucht diesel Zeile:
while ((I2CIFG & RXRDYIFG) == 0);
duch duch eine Warteschleife zu ersetzten. Leider mit dem selben 
Ergebnis


>Bei der fet140_i2c_13.c könntest du auch mal die TXBytes() Funktion
>nutzen um ein Byte (0x00) zu senden. Dann steht der LM75 sicher auf dem
>Temperaturregister wenn du die Bytes abrufst.
Habe ich versucht. Kein Unterschied.

>Vielleicht wäre es auch besser beide (low und high) Bytes abzurufen.
>Nicht das es doch Probleme macht wenn nur immer das high-Byte gelesen
Wie du oben in meiner Funktion siehst habe ich das wieder gemacht, aber 
mit dem selben Ergebnis.

Danke bis hierhin für deinen Geduld und deine Tips.
Markus

von Jörg S. (joerg-s)


Lesenswert?

>Denn die empfangenen Bytes beinhalten genau das was der PC anzeigt..
Am PC kommen doch aber nur die gemittelten Werte an.
Wenn wir dem Problem auf den Grund gehen wollen brauchen wir die 
Rohdaten! Also nichts mehr mitteln sondern low und high-Byte getrennt an 
den PC senden oder halt im Debugger ansehen und aufschreiben.

von Markus S. (Gast)


Lesenswert?

>Am PC kommen doch aber nur die gemittelten Werte an.
>Wenn wir dem Problem auf den Grund gehen wollen brauchen wir die
>Rohdaten! Also nichts mehr mitteln sondern low und high-Byte getrennt an
>den PC senden oder halt im Debugger ansehen und aufschreiben.
Das hatte ich ja gemeint, dass ich das Programm 20 mal gestartet habe. 
Da habe ich sowohl nur das Highbyte und danach auch die gemittelten 
Werte mehrer Male ausgelesen. mit dem Ergebnis dass sie geschwank haben. 
Sorry hatte ich oben vielleicht ein bisschen blöd formuliert.
jetzt habe ich es noch mal versucht und das Highbyte und das Lowbyte 
mehrer
Male ausgelesen. Das Lowbyte schwankt zwischen 127 und 255 aber das ist 
ja auch so in Ordnung da ja nur Bit 8 zählt. Und das Highbyte schwankt 
zwischen 15 und 17 bei ca. 1 Messwert alle 2 Sekunden. Aber das erklärt 
nicht warum das bei den gemittelten Werten aus so ist. Ich habe das 
Gefühl als ob meinen Mittelwert Berechnung nicht stimmt. Als ob er nur 
einen gemmessen Wert übergibt und nicht den Durchschnittswert.

Markus

von Markus S. (Gast)


Lesenswert?

ich habe jetzt noch mal ein bisschen mit dem IAR herumprobiert und habe 
rausgefunden wie man das Programm bis zu Breakpoimt viel schneller 
hintereinander starten kann und dabei habei ich gemerkt das die Rohdaten 
vom Highbyte doch relativ stabil sind. Es schwankt zwar leicht wie oben 
angegeben, aber das ist lange nicht so schlimm wie die gemittelten 
Werte.
Ich habe auch mal wieder einen zweiten LM75 angeschlossen weil der noch 
schlimmer geschwankt hat, aber hier war die Schwankungen bei den 
Rohdaten auch wesentlich weniger als bei den gemittelten Werten. Leider 
sind die gemessenen Werte immer noch viel zu tief. Bei Raumtemperatur 
misst der eine Fühler zwischen 15 und 18°C und der Zweite zwischen 7 und 
9°C.

Markus

von Jörg S. (joerg-s)


Lesenswert?

Poste doch mal bitte die Daten.

von Tom A. (thomas_a)


Angehängte Dateien:

Lesenswert?

Oder wie gesagt schau dir die Daten einfach mal mit dem Oszi an, dann 
siehst du auch gleich viel mehr ... und kannst das einfach mal 
anschauen.

Dann weißt du ob die Sensoren defekt sind oder nicht.

Im angehängten Bild wird der Sensor mit der Adresse 0x4E ausgelesen. Die 
Temperatur dürfte der Raumtemperatur hier entsprechen 18-24°C je nach 
dem was hier alles an ist ;)

Bitte beachte nur die ersten 3 "Bursts" weiter hinten kommt bei mir der 
nächste Temperatursensor.

Grüße tom

von Markus S. (Gast)


Lesenswert?

@Jörg,
ich muß erst mal meine Daten erst mal aufräumen denn da sind noch sehr 
viele Versuche drinn die ich mit // ausgeblendet habe. Sobald ich das 
fertig habe poste ich es.

@Tom,
ich habe leider nicht so einen schönen Oszi wie du der mir die Signale 
so sauber darstellt wie deiner. Ich habe noch einen alten HAMEG 30MHz 
bei dem ist es sehr schwierig die SDA Signale sauber zu erkennen. Ich 
hab leider nichts genaues erkennen können. Ich habe aber meine SCL 
Frequenz einstellen können. Sie liegt jetzt bei 10.74 KHz (wenn ich mich 
nicht verrechnet habe). Ich bin mit der Frequenz so weit runtergegangen, 
weil ich gelesen haben, dass man dadurch längere Leitungen verwenden 
kann, und mehrere Fühler an einer Leitung hängen kann. Das Ergebnis der 
ausgelesen Fühler hat sich dadurch aber nicht verändert.

Gruß
Markus

von Markus S. (Gast)


Angehängte Dateien:

Lesenswert?

Hi Jörg,
hier ist mein (Experimentier) Programm.
Ich habe bei Untersuchungen mit Hilfe des Breackpoint herausgefunden das 
auch Messwerte von über 200 dabei waren. Deshalb habe ich einen Funktion 
Programmiert die alle Werte über 150 übergeht. Und deshalb lese ich nur 
noch das Highbyte aus, weil ich mir einbilde, dass das weniger Fehler 
gibt.

Übrigens habe ich hier in der Artikelsammlung über Temperaturfühler 
gelesen das sich der LM75 kalibrieren läst. Kann mir jemand erklären wie 
das Funktionieren soll. Kann man (muß man) den LM75 vor dem Einsatz 
programmieren?
Gruß
Markus

von Jörg S. (joerg-s)


Lesenswert?

Markus S. schrieb:
> Ich habe bei Untersuchungen mit Hilfe des Breackpoint herausgefunden das
> auch Messwerte von über 200 dabei waren. Deshalb habe ich einen Funktion
> Programmiert die alle Werte über 150 übergeht.
Wozu soll das gut sein?

>muß man) den LM75 vor dem Einsatz programmieren?
Nein.

>Und deshalb lese ich nur noch das Highbyte aus, weil ich mir einbilde,
>dass das weniger Fehler gibt.
Irgendwo hast du einen grundsätzlichen Fehler drin. Es bringt überhaupt 
nichts zu versuchen etwas weniger Fehler zu bekommen oder die Messwerte 
durch irgenwelche erfundenen Faktoren und Offsets zurech zu biegen. 
Damit löst du nicht das Problem! Der LM75 MUSS IMMER ordentliche 
Messwerte liefern. Solange das noch nicht der Fall ist solltest du nicht 
die Symptome bekämpfen sondern die Ursache finden.


Wie lang ist denn jetzt noch das Kabel zum Sensor? Wenn das immer noch 
so lang ist würde ich erst mal ein ganz kurzes dran machen um die 
Fehlerquelle erst mal auszuschliessen.
Wie schaut es mit einer Liste der Rohdaten aus?

Falls alle Stricke reissen würde ich dir empfehlen erst mal mit einem 
PCA9554 I²C I/O Baustein weiter zu machen. Da sieht man wenigstens 
direkt ob die Daten die man sendet und empfängt genau dem entsprechen 
die am Baustein anliegen. Wäre noch eine Fehlerquelle weniger. Wenn das 
dann alles läuft kann man zurück zum LM75.

von Markus S. (Gast)


Lesenswert?

Hi Jörg,
>Irgendwo hast du einen grundsätzlichen Fehler drin. Es bringt überhaupt
>nichts zu versuchen etwas weniger Fehler zu bekommen oder die Messwerte
>durch irgenwelche erfundenen Faktoren und Offsets zurech zu biegen.
>Damit löst du nicht das Problem! Der LM75 MUSS IMMER ordentliche
>Messwerte liefern. Solange das noch nicht der Fall ist solltest du nicht
>die Symptome bekämpfen sondern die Ursache finden.
ich gebe dir voll und ganz recht. Aber durch meine ganzen Fehlversuche 
habe ich gedacht es wäre normal das manche Fühler nicht die richtigen 
Werte ausgeben.

>Wie lang ist denn jetzt noch das Kabel zum Sensor? Wenn das immer noch
>so lang ist würde ich erst mal ein ganz kurzes dran machen um die
>Fehlerquelle erst mal auszuschliessen.
im Moment ist mein Kabel wieder ca. 2.5m lang um auch mal 
Aussentemperaturen messen zu können. Ich habe es aber schon mit einem 
kurzem Kabel (ca. 15cm) Versucht. Aber die Messwerte waren die Gleichen. 
Ausserdem hat der zweite Fühler nur eine 10cm Leitung aber wie oben 
schon erwähnt gibt der noch schlechtere Werte aus.

>Wie schaut es mit einer Liste der Rohdaten aus?
sobald ich aufgeschrieben habe, poste ich sie.

>Falls alle Stricke reissen würde ich dir empfehlen erst mal mit einem
>PCA9554 I²C I/O Baustein weiter zu machen. Da sieht man wenigstens
>direkt ob die Daten die man sendet und empfängt genau dem entsprechen
>die am Baustein anliegen. Wäre noch eine Fehlerquelle weniger. Wenn das
>dann alles läuft kann man zurück zum LM75.
Au backe, das wir aber ein harte Brett. Ich habe mir gerade mal das 
Datenblatt angesehen bis ich das alles verstanden habe, werden einige 
Tage (Wochen) ins Land gehen. Aber ich versuche es mal

Danke
Markus

von Jörg S. (joerg-s)


Lesenswert?

Markus S. schrieb:
> Au backe, das wir aber ein harte Brett. Ich habe mir gerade mal das
> Datenblatt angesehen bis ich das alles verstanden habe, werden einige
> Tage (Wochen) ins Land gehen.
Alternativ den PCF8574, der ist einfacher aufgebaut, aber der 9554 kommt 
mit seiner Register Struktur näher an das ran was du beim LM75 brauchst.

Siehe:
http://www.mikrocontroller.net/articles/Port-Expander_PCF8574

von Markus S. (Gast)


Lesenswert?

Jörg schrieb:
>Wie schaut es mit einer Liste der Rohdaten aus?

So, ich habe mal die Rohwerte gesammelt. Ich habe das Programm mit einem 
Breakboint unterbrochen und jedes mal den Wert, so wie er im Highbyte 
angezeigt wird, mitgeschrieben.
 18, 15, 18, 14, 18, 15, 18, 14, 19, 16, 18, 14, 18, 14, 19, 16, 18, 14, 
18, 15, 18, 14, 19, 17, 20, 15, 18, 14, 18, 14, 19, 17, 19, 17, 20, 14, 
18, 14
Das erstaunliche ist, ob ich die Werte schnell auslese (ca im 
Sekundenabstand) oder ob ich mir Zeit lasse (ca 5 Sekunden), das 
Ergebnis ist das Gleiche. Es wechseln sich immer ein höherer Wert und 
ein niedriger Wert ab. Ganz selten kommt zwei mal der gleiche Wert.

In letzter Zeit hatte ich das Problem, dass das Programm oft an einer 
der for Schleifen (Warteschleife) hängen geblieben ist. Sind for 
Schleifen ungünstig?

>Alternativ den PCF8574, der ist einfacher aufgebaut, aber der 9554 kommt
>mit seiner Register Struktur näher an das ran was du beim LM75 brauchst.
Das sehe ich mir mal an.

Zwischendurch mal wieder ein Dankeschön für deine Geduld und Tips.
Gruß
Markus

von Harald (Gast)


Lesenswert?

Mach mal:

int highbyte = 0;
 int lowbyte = 0;

zu
unsigned char highbyte = 0;
unsigned char lowbyte = 0;

von Jörg S. (joerg-s)


Lesenswert?

Markus S. schrieb:
> So, ich habe mal die Rohwerte gesammelt. Ich habe das Programm mit einem
> Breakboint unterbrochen und jedes mal den Wert, so wie er im Highbyte
> angezeigt wird, mitgeschrieben.
> 18, 15, 18, 14, 18, 15, 18, 14, 19, 16, 18, 14, 18, 14, 19, 16, 18, 14,
> 18, 15, 18, 14, 19, 17, 20, 15, 18, 14, 18, 14, 19, 17, 19, 17, 20, 14,
> 18, 14
> Es wechseln sich immer ein höherer Wert und ein niedriger Wert ab.
Was mich glauben lässt das es sich bei hohen Werten um das high-Byte 
handelt.


Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch 
noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B. 
das Hystherese Register liest, müssen die Werte ja auch IMMER gleich 
sein. Und wenn du was in das Register schreibst, musst du auch immer das 
lesen was geschrieben wurde.
Wenn die Daten immer gleich sind kannst du auch vernünftig mit dem Oszi 
schauen was übertragen wird.

von Markus S. (Gast)


Lesenswert?

Harald schrieb:
>int highbyte = 0;
> int lowbyte = 0;
>
>zu
>unsigned char highbyte = 0;
>unsigned char lowbyte = 0;
Danke werde ich mal versuchen, aber was bringt das?

Jörg schrieb:
>Was mich glauben lässt das es sich bei hohen Werten um das high-Byte
>handelt.
aber ich lese doch sowieso nur das high-Byte aus. Ich verstehe nicht so 
ganz was du meinst. Und wo kommen den die kleineren Werte her?


>Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch
>noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.
>das Hystherese Register liest, müssen die Werte ja auch IMMER gleich
>sein.
Wieso? Was steht in dem Hystherese Register? Was kann man oder muß mit 
dem Configurations Register machen?

>Und wenn du was in das Register schreibst, musst du auch immer das
>lesen was geschrieben wurde.
Und was heisst das? Ich schreibe doch gar nichts in ein Register.

Gruß
Markus

von Tom A. (thomas_a)


Angehängte Dateien:

Lesenswert?

Markus S. schrieb:
> Harald schrieb:
>>int highbyte = 0;
>> int lowbyte = 0;
>>
>>zu
>>unsigned char highbyte = 0;
>>unsigned char lowbyte = 0;
> Danke werde ich mal versuchen, aber was bringt das?
>
Du hast ja eine Schleife die immer wieder das Highbyte überschreibt. 
Wenn keine neuer Wert vom LM75 reinkommt bleibt der Wert bestehen und du 
denkst du hast den Wert 18 bekommen. Es könnte also sein, das der LM75 
nicht jedesmal mit 18 geantwortet hat sondern nur beim ersten mal.

> Jörg schrieb:
>>Was mich glauben lässt das es sich bei hohen Werten um das high-Byte
>>handelt.
> aber ich lese doch sowieso nur das high-Byte aus. Ich verstehe nicht so
> ganz was du meinst. Und wo kommen den die kleineren Werte her?
>
>
>>Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch
>>noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.
>>das Hystherese Register liest, müssen die Werte ja auch IMMER gleich
>>sein.
> Wieso? Was steht in dem Hystherese Register? Was kann man oder muß mit
> dem Configurations Register machen?
>
>>Und wenn du was in das Register schreibst, musst du auch immer das
>>lesen was geschrieben wurde.
> Und was heisst das? Ich schreibe doch gar nichts in ein Register.
>
mh... also schau dir doch bitte mal das Datenblatt an. Da steht so 
einiges drin. Wie man dan LM75 konfiguriert und wie man ihn richtig 
ausliest. Wenn man ihn auslesen möchte muss man z.b. erst einen 0x00 
Pointer an den LM75 schicken, damit dieser aus dem richtigen Register 
(Temp) die Werte ließt und "dir" zuschicken.

Ließ dir das ganze mal durch und schau die mal die Abbildung b an, das 
ist was du machen musst.

Gruß
Tom
> Gruß
> Markus

von Jörg S. (joerg-s)


Lesenswert?

Markus S. schrieb:
> Jörg schrieb:
>>Was mich glauben lässt das es sich bei hohen Werten um das high-Byte
>>handelt.
> aber ich lese doch sowieso nur das high-Byte aus.
Richtig. Du willst nur das high-Byte lesen, bekommst aber evt. immer 
einmal das high-Byte und beim nächsten mal das low-Byte. Was erklären 
würde warum die Werte einmal hoch und einmal niedrig sind.

>>Irgendwie hatte ich es schon ganz verdrängt, aber der LM75 hat ja auch
>>noch andere Register. Das Configuration, Hystherese usw. Wenn du z.B.
>>das Hystherese Register liest, müssen die Werte ja auch IMMER gleich
>>sein.
> Wieso? Was steht in dem Hystherese Register? Was kann man oder muß mit
> dem Configurations Register machen?
Wie Tom schon gesagt hat: Steht im Datenblatt.
Mir gegt es nur darum das es Register sind die du schreiben und lesen 
kannst und nicht von der Temperatur abhängig sind. D.h. die Daten müssen 
immer gleich sein. Falls es beim schreiben oder lesen von diesem 
Register Fehler gibt, ist die Fehlersuche einfacher weil nicht die 
variable Temperatur stört und immer andere Werte liefert.

>>Und wenn du was in das Register schreibst, musst du auch immer das
>>lesen was geschrieben wurde.
> Und was heisst das? Ich schreibe doch gar nichts in ein Register.
Sollst du dann aber um zu schauen ob deine Kommunikation/Software/I²C OK 
ist.

von Markus S. (Gast)


Lesenswert?

Tom schrieb:
>Du hast ja eine Schleife die immer wieder das Highbyte überschreibt.
>Wenn keine neuer Wert vom LM75 reinkommt bleibt der Wert bestehen und du
>denkst du hast den Wert 18 bekommen. Es könnte also sein, das der LM75
>nicht jedesmal mit 18 geantwortet hat sondern nur beim ersten mal.
ich dachte, mit der folgenden Zeile wird verhindert, dass mal keine 
Daten ausgegeben werden.
while ((I2CIFG & RXRDYIFG) == 0); // Wait for Receiver to be ready
Ich habe aber auch schon die Werte ohne diese Schleife, die das Highbyte 
überschreibt, ausgelesen. Das heisst also jeden Wert (siehe oben meine 
Rohdatenliste). Mit dem gleichen Ergebnis wie immer.

>Wenn man ihn auslesen möchte muss man z.b. erst einen 0x00
>Pointer an den LM75 schicken, damit dieser aus dem richtigen Register
>(Temp) die Werte ließt und "dir" zuschicken.
hab ich auch schon mal versucht. Ich probiere es aber noch mal.

Jörg schrieb:
>Richtig. Du willst nur das high-Byte lesen, bekommst aber evt. immer
>einmal das high-Byte und beim nächsten mal das low-Byte. Was erklären
>würde warum die Werte einmal hoch und einmal niedrig sind.
nein das glaube ich nicht denn ich habe auch schon die Rohdaten von dem 
Lowbyte ausgelesen das schwankt nur zwischen 255 und 127 (das letzte Bit 
für die 0,5 Nachkommastelle) und das ist ja in Ordnung.

>Wie Tom schon gesagt hat: Steht im Datenblatt.
>Mir gegt es nur darum das es Register sind die du schreiben und lesen
>kannst und nicht von der Temperatur abhängig sind. D.h. die Daten müssen
>immer gleich sein. Falls es beim schreiben oder lesen von diesem
>Register Fehler gibt, ist die Fehlersuche einfacher weil nicht die
>variable Temperatur stört und immer andere Werte liefert.
ich habe mir das Datenblatt noch mal angesehen und ich denke ich habe 
den größten Teil verstanden. Ich werde mal mit den Registern ein paar 
Versuche machen mal sehen was dabei rauskommt.

Danke
Markus

von Markus S. (Gast)


Lesenswert?

Hallo zusammen,
ich habe mal wieder ein bisschen rumexperimentiert. Leider erfolglos.
Ich wollte sichergehen, dass das Pointer Register auch wirklich auf Null 
steht. Dashalb habe ich mit:

U0CTL |= MST;                           // Master mode
  I2CTCTL |= I2CSTT+I2CSTP+I2CTRX;      // Initiate transfer
  while ((I2CIFG & TXRDYIFG) == 0);     // Wait for transmitter to be 
ready
  I2CDRB = 0x00;
  while ((I2CTCTL & I2CSTP) == 0x02);   // To prevent Arbitration Lost

eine Null gesendet.

Leider bleibt die das Programm dann beim Datenauslesen in dieser Zeile 
hängen:
while ((I2CTCTL & I2CSTP) == 0x02);       // Wait for Stop Condition
das heisst es wir kein Stopsignal erzeugt.
Und mit dem Breakpoint habe ich herausgefunden, das immer nur eine Null 
ausgelesen wird.
Ich habe mal versucht den LM75 zu Konfigurieren. Als erstes habe ich 
0x01 gesendet und danach eine 0X24. Aber geändert hat das Ganze nichts. 
Wenn ich die oben genannte Sendefunktion aus dem Programm nehme, 
schwanken die Messwerte wie immer und wenn ich es mit rein nehmen, 
bleibt das Programm an der genannten Stelle hängen.
Ich glaube so ganz habe ich das Datenblat vom LM75 doch noch nicht 
verstanden. Kann mir jemand sagen ob und wie ich den LM75 konfigurieren 
muß, damit ich einfach nur die Temperatur aus lesen kann? Muß ich 
vieleicht noch etwas anderes Senden bevor ich 0x00 sende um das Pointer 
Register auf Null zu setzten?

Markus

von Jörg S. (joerg-s)


Lesenswert?

>Kann mir jemand sagen ob und wie ich den LM75 konfigurieren muß, damit
>ich einfach nur die Temperatur aus lesen kann?
Du musst nix konfigurieren.

>Muß ich vieleicht noch etwas anderes Senden bevor ich 0x00 sende um das
>Pointer Register auf Null zu setzten?
Nur die I²C Adresse.

von Markus S. (Gast)


Lesenswert?

Jörg schrieb:
>Nur die I²C Adresse.
das ist klar, aber das macht das System ja automatisch wenn ich die 
Adresse vorher angebe.

von Markus S. (Gast)


Lesenswert?

Hallo zusammen,
ihr werdet es nicht glauben, aber ich habe meinen Fehler gefunden.
Es ist eingentlich ein bisschen peinlich und ich wollte es euch nicht 
berichten, aber ich finde, nachdem ich so viel Hilfe und Tipps von euch 
bekommen habe, habt ihr es verdient zu wissen woran es lag.

Kurz gesagt, es war die Versorgungsspannung.
Ich habe mir eine Tesplatine gebastel mit Taster, LEDs, 7-Segmentanzeige 
und einer eigenen Stromversorgung (3,3V). Der Prozessor sitzt auf einer 
auf einer kleinen OLIMEX Platine mit fertigen JTAG Anschluss. Diese 
Platine wird auf meine Testplatine gesteckt. Über den JTAG Anschluss 
läuft die Programmierung. Bei meinen ersten programmier Versuchen habe 
ich gemerkt dass man gar keine Versorgungspannung braucht denn die 
Versorgungsspannung von PC reicht, damit der Prozessor arbeitet. Somit 
habe ich nur noch ganz selten eigene Versorgungsspannung genutzt.
Als ich angefangen habe mit den Temperaturfühlern zu experimentieren 
habe ich nicht eine Sekunde darüber nachgedacht, dass die Spannung, die 
vom PC kommt, niedrieger ist und dass das den Fühler beeinflussen 
könnte. Aber die Spannung beträgt nur ca. 2,5V und das bringt den LM75 
durcheinander. Wenn ich die Externe Spannung von 3,3V anschließe, dann 
funktioniert alles ganz normal.
Also noch mals vielen Dank für eure Hilfe und Geduld und ich hoffe, dass 
ihr auch meine nächsten Fragen (die bestimmt kommen werden) noch 
beantwortet.

Gruß
Markus

von Tom A. (thomas_a)


Lesenswert?

mh... ^^
beschissender Fehler ^^

Aber dann kannst ja jetzt loslegen ;)

von Jörg S. (joerg-s)


Lesenswert?

Schön das es einen erfolgreichen Abschluss gefunden hat :)

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.