www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik LM75 am Atmel 128 mit TWI_Master


Autor: Hans Aspacher (pfifferhannes)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag zusammen,

kann mir vielleicht jemand helfen?

Ich versuche an meinem Ethernut-kompatiblen Board mehrere LM75 
Temperatursensoren zum Laufen zu bringen.

Dafür will ich die TWI-Master von Amtel verwenden, weil auf dem Board 
ein RTC-Chip läuft, der die Routinen ebenfalls schon nutzt.

Dabei tritt folgender Effekt auf:

1. Verwende ich nur einen LM75 so wird die Temperatur angezeigt, jedoch 
ohne Nachkommastelle. Das könnte ich jedoch verschmerzen.

2. Bei mehreren LM75 wird der Wert des ersten Sensors korrekt angezeigt.
Jedoch nur einmal nach dem Neustart des Boards. Alle weiteren Sensoren 
zeigen den Temperaturwert 0 (Null). Wird die Abfrage der Sensoren 
wiederholt, so zeigt auch der erste Sensor den Wert 0 (Null) an.

3. Tausche ich die Sensoren (und deren Adressen) so ist es das selbe 
Spielchen, was aber zumindest zeigt, daß die Sensoren an sich 
funktionieren.

Meine LM75-Routinen in C habe ich mal beigepackt.

Aufruf aus dem Hauptprogramm mit:
 fprintf_P(stream, PSTR("%d"), LM75_temperature(0)); 
bzw.
 fprintf_P(stream, PSTR("%d"), LM75_temperature(1)); 
für den zweiten Sensor.

Kann da mal bitte jemand einen Blick drauf werfen?
Ich verlieren sonst noch meine eh schon wenigen restlichen Haare.

Vielen Dank für eure Mühen.
pfifferhannes

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hans,

Problem ist, dass die Funktion die Daten im 16-bit signed Integer format 
zurueckgibt. die Funkion muss man wenn man double float will als double 
deklariert werden:

   double LM75_temperature(unsigned char chip)

Das Half Bit braucht nicht ausgewertet werden, da das LM75 Resultat mit 
2 dividiert werden muss um in Celsius direkt ausgertet werden zu können.

Hier Deine etwas umgeaenderte Funktion:

double LM75_temperature(unsigned char chip)
{
   double Celsius;

...

   Celsius = 0.0;
   if ((LM75_temp.tt[1] & 128) == 128)       // process Sign-Bit (Byte2)
   {
      Celsius = LM75_temp.tt[1] - 256;       // Temperature < Null
   }
   else
   {
      Celsius = LM75_temp.tt[1];             // Temperature >= Null
   }

   Celsius = Celsius / 2.0;

   return (Celsius);
}

Übrigens, wie kommst uaf: "// Temperature *10 from desired..."?

Der LM75 gibt die Werte im positiven Bereich mit 2 multipliziert aus.

Dividieren von (25 Grad) 0x032 mit 2 und Du bekommst 0x19 = 20.0 Grad.

25.5 Grad wird also als  0x033 ausgegeben. Usw.

Ich nehme an dass Du die Addressen Pins am LM75 richtig für jeden LM75 
von "000" "001" bis "111" eingestaellt hast. ( Also jeden PIN 
entsprechend auf Masse oder Vdd legen)

Sonst kann ich mir eigentlich nicht vorstellen was Du falsch gemacht 
haben könntest. Es sei denn dass was falsches in "LM75_addr" drin steht. 
Oder dass irgendwas mit der TWI_Start_Transceiver_With_Data() Funktion 
nicht stimmt.

Hoffe dass hilft Dir weiter.

Gruss,
Gerhard

Autor: Nils (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich hatte mal einen ähnlichen Fehler. Abhilfe schaffte ein bisschen 
Wartezeit zwischen 2 Abfragen auf den gleichen Sensor, da dieser sonst 
immer 0° ausgibt. Ich glaube es war 1s Pause.

Autor: Hans Aspacher (pfifferhannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, Gerhard & Nils,

für die Antworten.

>Gerhard: "// Temperature *10 from desired.. stammt aus meiner ursprünglichen 
Routine. Habe ich anders gelöst und nach Deiner Anmerkung auch bei mir im 
Quelltext korrigiert. Danke schön.

>Nils: Die Idee hatte ich schon. Bringta aber keine Lösung zumal die Abfragen 
nacheinander auf unterschiedliche Chips laufen. Trotzdem Danke.


Zusatzinfo: Ich habe mal nach der Abfrage den Wert aus dem 
Status-Register der LM75 ausgelesen mit
fprintf_P(stream, PSTR(" %u"), TWI_Get_State_Info());


Für die erste Abfrage ist das
248 = 0xF8  // No relevant state information available; TWINT = “0”

Für alle folgenden kommt der Wert 72 zurück.
72 = 0x48  // SLA+R has been tramsmitted and NACK received


Hilft das jemand zur Lösungsfindung?

Grüße
pfifferhannes

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hans,

vielleicht liegt es daran dass Deine TWI routine nicht weiss wenn 
ACK/NACK verwendet werden muss. (Obwohl nach Datenblatt das nicht 
wichtig ist):

"...At the end of a read, the LM75 can accept either
Acknowledge or No Acknowledge from the Master (No Acknowledge
is typically used as a signal for the slave that the
Master has read its last byte)."

Es gibt moeglicherweise auch ein Problem wie hier im Datenblatt 
beschrieben:

"An inadvertent 8-bit read from a 16-bit register, with the D7
bit low, can cause the LM75 to stop in a state where the SDA
line is held low as shown in Figure 5. This can prevent any
further bus communication until at least 9 additional clock
cycles have occurred.
Alternatively, the master can issue
clock cycles until SDA goes high, at which time issuing a
“Stop” condition will reset the LM75."

Vielleicht solltest Du mit dem Oszillographen die SDA Leitung 
ueberwachen um zu sehen ob das obige Problem die Ursache sein koennte.

Bei mir verende ich diese I2C Sequenz wenn ich den CCS Compiler 
verwende:
(I2C verwendet nicht die I2C hardware im IC, sondern nur irgendwelche 
PORT 2 PORT pins im PIC, da SPI und I2C die gleichen PINS haben)

...
    i2c_start();        //
    i2c_write(0x90);    // Screib Mode ist aktiv
    i2c_write(0x00);    // Das Pointer register ist auf Temperatur 
register gerichtet
    i2c_start();        //
    i2c_write(0x91);    // Lese Modus eingestellt
    value.tmp_in[1]=i2c_read();     // Lese MSB mit ACK
    value.tmp_in[0]=i2c_read(0);    // Lese LSB mit NACK
    i2c_stop();

Dem Datenblatt nach ist das die korrekte Kommunikation fuer den LM71 um 
ein 16-bit Datenwort zu verlangen.

Du solltest vielleicht nachpruefen inwieweit bei Deiner TWI Funktion die 
ACK/NACK individuell fuer jedes Byte eingestellt werden kann. Ich rieche 
den Hasen irgendwie hier;:-)

Ohne selber zu experimentieren ist so ein Problem schwierig 
diagnostizier bar. Ich habe vor wenn ich Zeit habe einen zweiten LM75 
anzuhaengen um zu sehen ob ich aehnliche Problem haben wuerde.

Gruss und viel Glueck,
Gerhard

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hans,

besitzt Du die Source fuer:

TWI_Start_Transceiver_With_Data(...);
TWI_Get_Data_From_Transceiver(...);
TWI_Get_State_Info();

Ich wuerde mir die gerne ansehen,

Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Gerhard
schau mal bei Atmel bei den AVR-Appnotes 
(http://www.atmel.com/dyn/products/app_notes.asp?fa...) nach 315 
(vl. auch 311)

hth. Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke, Jorg!

Gruss,
Gerhard

Autor: Hans Aspacher (pfifferhannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Guten Tag zusammen,

Danke an alle, die sich so hilfreich meinem Thema annehmen.

Gerhard:
Habe Deine Routine ausprobiert, liefert aber im Moment noch ein falsches 
Ergebnis. Reale Temperatur / 2 - warum auch immer. Mein Ansatz hatte 
zumindest die annähernd richtige Zahl vor dem Komma.

ACK/NACK: Wird ja offenbar von der Routine in TWI_Master automatisch 
generiert, wenn die Anzahl der über den Bus angeforderten Byte  erreicht 
ist.

Ein Oszi steht mir nicht zur Verfügung. Ich habe aber über Google einen 
PC-Oszi an LPT1 gefunden. Wenn nicht anders möglich werde ich mal die 
Bauteile zusammensuchen und löten. Letzte Option - ich habe immer noch 
Hoffnung, daß mein Problem "nur" Software-Ursachen hat.

Danke Jörg X. - warst schneller als ich mit dem Link.

mfg
pfifferhannes

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hans,

den Fehler habe ich gemacht
Da habe ich mich aber jetzt schoen blamiert :-( .

Du musst den Teil den ich geloescht habe wieder reingeben. Dann geht's.

if ((LM75_temp.tt[0] & 128) == 128)// process Half-Bit (Byte1, Bit7)
{
    Celsius = Celsius + 0.5;
}

Habe aus irgendeinen Grund den LM75_temp.tt[0] nicht beachtet, wo das 
Half Bit sitzt.

Das andere Problem ist leider etwas schwieriger. Vielleicht geht es ohne 
Oszi. Sollte die SDA Leitung permanent auf Null gehen, brauchst Du nur 
eine LED im Pullup der SDA einfuegen, und schon wird es durch staendiges 
Leuchten angezeigt.

Um aus diesem Zustand rauszukommen sende dann einfach ein oder zwei 
Bytes auf den Bus bis sich die SDA Leitung wieder benimmt.

Lasse mich bitte wissen ob es hilft. Das ist sehr nuetzlich zu wissen. 
Wie gross sind die Werte der Widerstaende? Ich verwende meistens 3.9K. 
Vielelicht verringere sie etwas. Aber ohne Oszi ist das natuerlich schon 
ein Schuss ins Dunkle.

Eine Frage habe ich noch: Was passiert wenn nur ein LM75 dran ist, aber 
auf andere Adressen eingestellt wird?

Gruss,
Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Geht die (wahrscheinlich unnötige) Umwandlung in float nicht einfacher?
so à la:
float temperature;
int temp2;
int lm75val = get_lm75val(SENSOR);
temperature = lm75val / 256.0; //Low-byte enthält Nachkommastellen
if (temperature >= 0)
    temp2 = temperature + 0.5; //wird ja abgerundet
else
    temp2 = temperature - 0.5; // nur abrunden wäre verkehrt
Und wenn eigentlich gar keine Floats gebraucht werden: 
http://www.mikrocontroller.net/articles/Festkommaarithmetik

sry for klugscheißing ;)
--Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hi Jörg,

der untengenannte Teil ist doch nicht notwendig, weil das Resultat ja 
schon die 0.5 Grad Aufloesung aufweist? Oder bin ich da irgendwie jetzt 
blind?

if (temperature >= 0)
    temp2 = temperature + 0.5; //wird ja abgerundet
else
    temp2 = temperature - 0.5; // nur abrunden wäre verkehrt

Kanns Du mir das erklaeren?

Was mich uebriegens interessiert ist, wie der Compiler die Sache mit dem 
Sign Bit beachtet. Z.B. wenn der LM75 den Wert 0xFF80 ausgibt fuer -0.5 
Grad, dann muss (signed) int lm75val = 0x7F80 ergeben, damit Deine 
Rechnung auch tatsaechlich

(float) -128 / 256.0 = -0.5 Grad ergibt.

Ich nehme an, dass das in der Praxis auch tatsaechlich funktioniert, da 
ich es auf diese Weise noch nie gemacht habe.

Ich glaube auch, dass so wie Hans das im Original geschrieben hat, 
warscheinlich weniger Speicher Platzaufwendig ist, da keine float 
Division gebraucht wird. Die einzige float Rechnung die bei Hans 
gebraucht wird, ist die Addition vom Halb-Bit.

Gruss,
Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> if (temperature >= 0)
>    temp2 = temperature + 0.5; //wird ja abgerundet
> else
>    temp2 = temperature - 0.5; // nur abrunden wäre verkehrt
Danach stehen nur noch ganze Grad-Zahlen im temp2, hätte ich erwähnen 
sollen. Bei der Konvertierung nach int werden die Nachpommastellen 
einfach abgeschnitten, deshalb wird die Zahl vorher in die 'richtige' 
Richtung korrigiert: z.B. (int)0.6 soll 1 und nicht 0 werden, (int)-0.6 
soll -1 werden...

Und der Sensor liefert - wenn man die ganze Zahl betrachtet - das 
256fache der Temperatur als Zweierkomplement (das ist kein Hexenwerk, 
sondern meistens die normale Darstellung für (negative) int: 
http://de.wikipedia.org/wiki/Zweierkomplement )
Wenn der Sensor 0xFF80 liefert, dann ist das -128 (a.k.a -0.5*256). Da 
brauchts keine extra Berechnung.

hth. Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joerg,

Deine Loesung ist tatsaechlich sehr einfach. Das mit der Aufrundung 
verstehe ich jetzt. Danke.

Ich war mir nicht sicher ob man ohne Nachpruefen, sich auf die 
automatische Umwandlung von unsigned auf signed immer verlassen kann.

Gruss,
Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> ... automatische Umwandlung von unsigned auf signed immer verlassen kann...
Kann man ganz sicher nicht - ist hier aber nicht der Fall, weil der 
Sensor einen signed Wert liefert ;) (egal was -für einen int-Typ- die 
TWI-Funktion liefert)

hth. Jörg

Autor: Falk Brunner (falk)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@ Gerhard. (Gast)

>der untengenannte Teil ist doch nicht notwendig, weil das Resultat ja
>schon die 0.5 Grad Aufloesung aufweist? Oder bin ich da irgendwie jetzt
>blind?

Es wird gerundet. Dabei muss man zwischen positiven und negativen Zahlen 
unterscheiden.

>Was mich uebriegens interessiert ist, wie der Compiler die Sache mit dem
>Sign Bit beachtet. Z.B. wenn der LM75 den Wert 0xFF80 ausgibt fuer -0.5

Es ist ein ganz normales Zweierkomplement. Damit arbeitet jeder 
Compiler.

>Division gebraucht wird. Die einzige float Rechnung die bei Hans
>gebraucht wird, ist die Addition vom Halb-Bit.

AHHHH! Was bitte? Halb-Bits?

MFG
Falk

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Falk, Joerg,

danke fuer Eure Erklaerungen.

Das mit dem Halb-bit ist nur ein ungluecklicher Ausdruck fuer das LSB 
Bit im LM75 welches einen Wert von 0.5 Grad hat.

Gruss,
Gerhard

Autor: Hans Aspacher (pfifferhannes)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo zusammen,

Lieber Gerhard - Pullups sind 4K7.
Ich habe mal einen Logiktester angeklemmt.
SDA Geht am Schluss auf 1 - scheint also nicht zu klemmen.

LM75 mit anderer Adresse funktioniert - sobald ich jedoch ein zweites 
anschließe, ergibt sich wieder der selbe Effekt.

Senden von weiteren Bytes auf den Bus bringt ebenfalls keine Lösung.

Bin echt ratlos. Ich hab mal meine Routinen ergänzt und gebe Adressen 
etc. auf Seriell aus. Scheint soweit alles i.O. Adressierung stimmt, 
Register ebenfalls.

Beim Lesen ist mir allerdings aufgefallen, daß für messageBuf[0] die 
Adresse vom LM75 zurückkommt. In messageBuf[1] steht die Temperatur als 
(Ganz)-Zahl. messageBuf[2] = ist bisher immer null.

Du sprachst von unbeabsichtigten 8-bit Lesevorgängen auf den Bus.
Wie mache ich denn einen 16-bit Lesevorgang (meine C-Kenntnisse sind 
sehr rudimetär...)

mfg
pfifferhannes

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hannes,

das ist wirklich schlimm. Ich werde mal sehen ob ich dieses Wochenende 
bei mir mehr als einen LM75 auf einer Leitung ansteuern kann. Nur 
verwende ich bei mir einen PIC und CCS C. Habe bis jetzt auch nur immer 
einen LM75 oder TMP101 verwendet.

4.7K sollte OK sein. Wie lange sind Deine Verbindungsleitungen? 
Vielleicht brauchen die LM75 0.1uF Abblockkondensatoren.

Ich kann nur bestaetigen dass bei mir mit meinem PIC18F452 ein DS1307, 
LM75 oder TMP101, und eine 24ATC1024 EEPROM problemlos angesteuert 
werden koennen. Funktioniert 100%.

Vielleicht sollte man das Datenblatt vom AVR in Bezug auf I2C noch 
einmal sorgfaeltig durchgehen.

Dein Problem hat bestimmt nichts mit C zu tun. Ich verdaechtige im 
Augenblick eher Hardware.

Ueber das Problem mit den 8-bits wuerde ich mir Augenblick keine 
Gedanken machen, da das bei Dir anscheinend sowiso kein Problem ist. 
Solange Deine TWI Funktion nicht unvollstaendige Zugriffe macht, 
passiert das nicht so wie ich das selber verstehe.

Sollte ich was herausfinden werde ich mich in den naechsten paar Tagen 
wieder melden. Gib nicht auf - das Problem muss loesbar sein! Muss nur 
nachsehen wie viele LM75 ich zuhause habe.

Gerhard

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Hannes,

habe vergessen Deine Frage zu beantworten: Den 16-Bit Lesevorgang macht 
Deine TWI Funktion. Ich will mir die Sources fuer diese Funktionen 
dieses Wochenende ansehen. Vielleicht hilft es.

"Beim Lesen ist mir allerdings aufgefallen, daß für messageBuf[0] die
Adresse vom LM75 zurückkommt. In messageBuf[1] steht die Temperatur als
(Ganz)-Zahl. messageBuf[2] = ist bisher immer null."

Das ist warscheinlich die TWI Funktion. WIe gesagt ich kenne diese 
Funktionen leider noch nicht.

Gruss,
Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> "Beim Lesen ist mir allerdings aufgefallen, daß für messageBuf[0] die
> Adresse vom LM75 zurückkommt. In messageBuf[1] steht die Temperatur als
> (Ganz)-Zahl. messageBuf[2] = ist bisher immer null."
Ich hab mir den Code von Atmel noch mal gründlich (hoffe ich ;) ) 
angeschaut:
messageBuf[0]=(LM75_addr) | (1<<TWI_READ_BIT);  // Setup for Chip read
messageBuf[1] = 0;        // unnoetig, weil...
messageBuf[2] = 0;                
TWI_Start_Transceiver_With_Data(messageBuf,3 );  /* die ISR auf die Adresse+R
 reagiert und NACH der adresse 3 Bytes liest- sicherlich ungewollt */

_delay_ms(LM75_CONVERSION_TIME_MS);    /* funktioniert auch nicht: die 
maximale Wartezeit ist 262.14ms/F_CPU[MHz] -> 262.14/14.7 ? */
TWI_Get_Data_From_Transceiver(messageBuf,3);  /* liest NUR den Puffer aus,
 deine Daten wurden schon VOR der warteschleife 'geholt'*/

Der TWI-Code ist irgendwie kompliziert, aber es scheint nicht einfacher 
zu gehen, wenn man die TWI-Hardware 'richtig' nutzen will.

hth. Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Joerg,

ich habe mir die Source vom Hannes angesehen und ich habe eine Frage wie 
Zeile 30 zu verstehen ist:

messageBuf[0]=(LM75_addr) | (1<<TWI_READ_BIT); // Setup for Chip read

ISt das nicht falsch? So wie ich das lese, wird TWI_READ_BIT (ist 0) um 
ein bit nach links geschoben und zerstoert bit 1 von der Addresse.

Zum Beispiel wenn LM75_addr = 0x92 nach Zeile 30 ist es dann 0x90

Oder nicht?

Ich glaube, dass ist das Problem.

Um einen Schreibvorgang zu setzen muss BIT1 = 1 sein, dann muesste 
LM75_addr = 0x93 sein. (0x92 | 0x01)

Gruss,
Gerhard

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Joerg,

das war falsch von mir:

Um einen Schreibvorgang zu setzen muss BIT0 = 0 sein, dann muesste
LM75_addr = 0x92 sein. (0x92)

Lesen: LM75_addr = 0x93 sein (0x92 | 0x01)

Sorry!

Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Und " a << b" heißt:
(Zahl) a wird b Bits nach links geschoben (nicht umgekehrt ;) ) -> a * 
2^b

:) Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke Joerg,

waere ja auch zu leicht gewesen; :-(

Gruss,
gerhard

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Jörg und Hannes,

habe mir noch mal das Datenblatt durchgestöbert und bin (immer noch) der 
Ansicht dass die 100+ms Warteschleife unnoetig ist. Solange das Shutdown 
bit auf 0 ist, konvertiert der Chip das automatisch und man kan den LM75 
so oft ansprechen wie man will. Das würde auch die Funktion schneller 
machen.

Ich habe mir meinen eigenen PIC source angesehen und da verwende ich 
auch keine Warteschleife. Es gibt ja auch kein "Start Measurement" Bit.

Nur wenn man den LM75 andauerend abschalten möchte im Start/Stop 
Betrieb, müsste man ca. 120ms warten.

Übriegens, irgendwie wäre es praktischer, einfachere I2C function wie
I2C_start, I2C_read usw. zur Verfügung zu haben.

Zum Beispiel wenn man den LM75 auf Lese Modus umschalten möchte werden 
jetzt 3 Bytes gesendet wenn eigentlich nur die Addresse mit dem Read-Bit 
notwendig ist.

Zum Lesen der Temperatur genügt doch eigentlich:

i2c_start();        //
i2c_write(0x91);    // Auf Lese Modus eingestellt
value.tmp_in[1]=i2c_read();     // Lese MSB mit ACK
value.tmp_in[0]=i2c_read(0);    // Lese LSB mit NACK
i2c_stop();

Was mir auch noch auffällt ist, dass beim Setzen des Pointer Registers 
das
messageBuf[2] keinen definierten Wert hat. Ob das was ausmacht weiss ich 
nicht. Sollte man das nicht so senden dass nur zwei Bytes gesendet 
werden:

...
messageBuf[0]=(LM75_addr) | (0<<TWI_READ_BIT);
messageBuf[1] = 0;  // Pointer register auf Temperatur
TWI_Start_Transceiver_With_Data(messageBuf,2 );

// Sende dem LM75 den Read Befehl
messageBuf[0]=(LM75_addr) | (1<<TWI_READ_BIT);
TWI_Start_Transceiver_With_Data(messageBuf,1 );

// Warte auf die Interrupts mit den zwei Bytes
TWI_Get_Data_From_Transceiver(messageBuf,2); // Nur 2 Bytes erwartet
LM75_temp.tt[0]= messageBuf[0];
LM75_temp.tt[1]= messageBuf[1];
...

Jörg, Hannes was meint Ihr?

Gruss,
Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Warteschleife wird irgendwann nötig sein (dann, wenn man neue 
Messwerte haben will ;-) ):
> The LM75 can be accessed at any time and reading the Temperature Register
> will yield result from the last temperature conversion. When the LM75 is
> accessed, the conversion that is in process will be interrupted and it will
> be restarted after the end of the communication. Accessing the LM75
> continuously without waiting at least one conversion time between
> communications will prevent the device from updating the Temperature
> Register with a new temperature conversion result. Consequently, the LM75
> should not be accessed continuously with a wait time of less than 300 ms
(eine Fußnote aus dem Datasheet)
i2c_start();        //
i2c_write(0x91);    // Auf Lese Modus eingestellt
/*
value.tmp_in[1]=i2c_read();     // Lese MSB mit ACK
value.tmp_in[0]=i2c_read(0);    // Lese LSB mit NACK
*/
// mir gefaellt das so aber besser ;)
int value;
value = ((int)i2c_read()<<8);
value|= i2cread;
i2c_stop();
Da spricht nichts dagegen (außer dem Zitat oben). Wenn die aktuelle 
I2C-Routine zu komplex ist, geht z.B. die TWI-Lib von Peter Fleury 
(www.jump.to/fleury), eben ohne Interrupts.

hth. Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Danke für den Hinweis. Das war mir schon bekannt. Wenn der Sensor nur ab 
un dzu abgefragt wird, dann kann man das vernachlässigen. Sonst wäre es 
besser, einen Timer Interrupt zu verwenden, der den LM75 im Hintergrund 
mit ausreichenden Zwischenpausen anspricht und dann kann man die Wert so 
oft lesen wie man will und hat dann immer frische Werte. Das läuft bei 
mir so auf einem Gerät mit einem PIC.

Dein umgewandelter Code von mir gefällt mir auch besser; :-)

Ich wünschte nur wir könnten endlich dem eigentlichen Problem vom Hannes 
zu Grunde kommen. Das scheint eine wirklich harte Nuss zum Knacken.

Wie schon gesagt, bei mir habe ich schon mindestens vier I2C ICs am PIC 
dranhängen und es läuft alles tadellos. Sind aber alles unterschiedliche 
Typen. Muss allerdings dazu bemerken, dass bei mir keine Interrupts den 
Read unterstützen so wie bei dieser Library.

(Warscheinlich ist das Problem so lächerlich einfach dass man die 
Ursache glatt übersieht)

Gruss,
Gerhard

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Jörg,

wie kriegst Du hin, die Farbe der quotierten Texte zu verändern. Ich 
kann das einfich nicht rauskriegen.

Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> wie kriegst Du hin, die Farbe der quotierten Texte zu verändern.
>> in
>>> dem
ich da ">" davor schreibe ;)

@Hannes poste bitte noch mal den aktuell verwendeten Code!

hth. Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
> Danke Joerg,

Eine Frage noch: Was bedeutet "hth"? - In Canada bin ich etwas abseits 
im heutigen Sprachgebrauch. (53N/113W)

Gerhard

Autor: Jörg X. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
"Hope This Helps"

;-) Jörg

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Darauf waree ich nicht gekommen;:-)

Gruss,
Gerhard

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.