Hallo, ich möchte einen Temperatursensor LM75 über i²C auslesen und die Temperatur auf einem 2x16 Zeichen-Display ausgeben. Meine Hardware ist ein myavr mk2 Board mit Atmega8 und ein LCD-Add-on, ebenfalls von my avr.Weiterhin habe ich einen LM75 (auf einer Laborplatine verlötet) mit an das Board angeschlossen. Hardwaremäßig funktioniert das ganze (mit der Software mySmartusbTerminal kann ich den LM75 auslesen und auch Temperaturen für den Schaltausgang zum LM75 schreiben; ich habe ein LED am Schaltausgang, die geht also auch bei entsprechender Einstellung). Software soll in C erstellt werden. Da ich absoluter Einsteiger in die Materie bin, habe ich mir im Internet Quellcode und Libs gezogen und ein eignes kleines Main geschrieben, aber ich bekomme damit noch keine vernünftige Anzeige aufs Display, es steht nur immer für den Temperaturwert "1636" und anschließend dann abwechselnd irgendwelche Hieroglyphen auf dem Display. Hier mal mein main: #define F_CPU 3686400UL #include <util/delay.h> #include <avr/io.h> #include <avr/interrupt.h> #include <stdlib.h> #include <stdint.h> #include "lcd.h" #include "I2C.h" #include "lm75.h" volatile unsigned short temp; int main() { while(1) { lcd_init(); lcd_on(); lcd_clear(); lcd_goto(1,1); itoa(lm75_get_temperature, temp, 10 ); lcd_write_s( "Temp:" ); lcd_goto(1,6); lcd_write_s( temp ); lcd_goto(2,1); lcd_write_s( "Grad Celsius" ); _delay_ms(3000); } return 0; } und dazu der Ausschnitt aus dem lm75c, (das ich aus dem Internet habe) in dem der Sensor ausgelesen werden soll: unsigned short lm75_get_temperature (unsigned char address) { unsigned short temperature = 0; lm75_init (); lm75_send_start (); lm75_send_add_rw (address, 1); temperature = (lm75_read_byte () << 8); temperature |= lm75_read_last_byte (); lm75_send_stop (); /*returned value will be right-aligned and negative*/ if (temperature & (1<<15)) { temperature >>= 7; temperature |= 0xFEFF; return temperature; } else { /*returned value will be right-aligned and positive*/ return (temperature >> 7); } ich versteh jetzt nicht so richtig, wohin eigentlich der ausgelesene Wert aus dem Temperaturregister abgespeichert wird (nach meinem rudimantären C-Verständnis müßte es doch eine Variable geben, in die der ausgelesene Wert abgespeichert wird?) "temperature" kennt allerdings das main nicht als globale Variable, hab jetzt mal den Namen der Funktion (lm75_get_temperature) im main aufgerufen. So wie ich das verstehe, ist das lm75.c ein Unterprogramm, dass sich seinerseits wieder am Unterprogramm für die i²C-Kommunikation bedient und mir einen "fertigen" Wert für die Temperatur übergibt, den ich dann im main nur noch mit itoa umwandeln muss, damit er als ASCII-Code ins Display geschrieben werden kann? Vielleicht kann mir jemand weiterhelfen? Bei Bedarf kann ich auch mal mein Projekt-Datei (ich arbeite mit AVR-Studio 4.18) hochladen. Gruß
itoa erwartet einen char-pointer als 2. Argument.
1 | char * itoa ( int value, char * str, int base ); |
versuchs mal so:
1 | ...
|
2 | char temp[10]; |
3 | ...
|
4 | itoa(lm75_get_temperature, temp, 10 ); |
5 | ...
|
6 | lcd_write_s( temp ); |
7 | ...
|
Ok, Danke erstmal. Ich habe das jetzt mal so gemacht und bekomme nun "361" als ausgabe, ist schonmal besser als das vorher ;-) Hab jetzt beim itoa-Befehl mal Basis 2 also: itoa(lm75_get_temperature, temp, 2) eingegeben und dann die Anzeige: "101101001" bekommen. Beim Vergleich mit dem Datenblatt des LM75 passt es ja insofern, als das es 9 Bit mit Informationen sind, da ja (wenn ich das richtig verstanden habe) Bit 0-6 des Temperaturregisters nicht belegt sind, erst ab Bit 7 gehts los und Bit 15 ist das Vorzeichen, sprich eigentlich hätte ich jetzt Minus-Temperaturen? Ich weiß halt nicht, wie die Temperatur in dem Register des LM 75 kodiert ist, weil es passt ja weder mit bcd-Code, noch wenn ich es als 8-Bit Dualzahl lese und in einenDezimalwert umrechne. Ich dachte eigentlich, dass die Umkodierung schon im lm75.c erfolgt? jedenfalls ist dort die Abfrage nach dem 15.Bit wegen dem Vorzeichen drin. Gruß
Interpretier mal das erste ausgelesene Byte (MSB) als int8_t. Das ist dann die Temperatur in °C als 2er-Komplement. Daniel S. schrieb: > Ich dachte eigentlich, dass die Umkodierung schon im lm75.c > erfolgt? Zeig mal den Code. Gruß Oliver
Vielleicht hilft's ja. Geklaut aus einem STM32-Beispiel:
1 | /* Get double of Temperature value */
|
2 | TempValue = LM75_ReadTemp(); |
3 | |
4 | LM75_ShutDown(DISABLE); |
5 | |
6 | ...
|
7 | |
8 | if (TempValue == 0) { |
9 | /* Zero temperature measured */
|
10 | lcd_putchar(' '); |
11 | |
12 | /* Initialize the temperature sensor value*/
|
13 | TempValueCelsius = TempValue; |
14 | } else if (TempValue <= 250) { |
15 | /* Positive temperature measured */
|
16 | lcd_putchar('+'); |
17 | |
18 | /* Initialize the temperature sensor value*/
|
19 | TempValueCelsius = TempValue; |
20 | } else { |
21 | /* Negative temperature measured */
|
22 | lcd_putchar('-'); |
23 | /* Remove temperature value sign */
|
24 | TempValueCelsius = 0x200 - TempValue; |
25 | }
|
26 | |
27 | /* Calculate temperature digits in °C */
|
28 | if ((TempValueCelsius & 0x01) == 0x01) |
29 | {
|
30 | TempCelsiusDisplay[1] = 0x05 + 0x30; |
31 | } else { |
32 | TempCelsiusDisplay[1] = 0x00 + 0x30; |
33 | }
|
34 | |
35 | TempValueCelsius >>= 1; |
36 | |
37 | ...
|
38 | lcd_putstring("Temp: "); |
39 | ...
|
40 | printf("%i", TempValueCelsius); |
41 | lcd_putstring(TempCelsiusDisplay); |
42 | lcd_putchar(0xF8); // '°' |
43 | lcd_putchar('C'); |
Hallo Daniel, ich bin auch grad am LM75 und habe auch Probleme. Ich kann zwar Werte auslesen, doch diese haben 16er Sprünge(0..16...32...48..64...80..96..112..0...16...usw..) Man muss diesen Ascii Code in Dezimal umwandeln. Du kannst mal deinen Code schicken. Hier ist meiner Gruss Marcus
>temp.low >>=1; >temp.high<<=9; >ganzzahl= temp.low | temp.high; Ich sage mal vorsichtig: das kann nicht richtig sein. Ich würde an deiner Stelle Folgendes tun: 1. Mal nach 2er-Komplement googeln. 2. Genau überlegen was in einem 8-Bit-Wert bei einem Shift um 9 Stellen nach links alles herausfällt. 3. Nochmal das Datenblatt des LM75 zu Rate ziehen und schauen, ob auch wirklich ein Shift um eine Stelle reicht, um das LSB an die richtige Stelle zu bringen. 4. Genau überlegen, ob es auch wirklich notwendig ist das assemblermäßig über Shiftoperationen zu machen. 5. Abwägen ob es nicht eventuell reicht die Auflösung zu halbieren und das MS-Byte als Temperatur in °C zu interpretieren. Gruß Oliver
Hallo, hier mal der Code von der c-Datei für den LM75 (den hab ich wie gesagt so aus dem Internet übernommen). Außerdem das komplette AVR Studio Projekt. Wenn ich das Byte, bzw. meine 9 Bit komplementär betrachte, passt es leider immer noch nicht: also ich hatte: 101101001 macht komplemenatär 010010110 geh ich jetzt mal davon aus, dass das MSB das Vorzeichen ist, passt das zwar (0 entspricht positiver Temperatur), aber der Rest passt nicht, BCD-Code würde Dezimal 96° ergeben, als 8-Bit-Wert Dezimal 150°. Im Datenblatt stehen ja auch Beispiele: +125°C 0 11111010 +25°C 0 00110010 +0.5°C 0 00000001 0°C 0 00000000 — 0.5°C 1 11111111 auch wenn ich hier das Komplement nehem, z.B. bei 25° komm ich nicht auf den Dezimalwert, weder BCD noch als zusammenhängende 8 Bit. Das einzige, was passt, wäre das LSB als 1. Nachkommastelle zu lesen, d.h. bei 0 sind es xxx,0° ; bei 1 wären es xxx,5°. dann hätte ich aus irgendeinem Grund noch ca. die doppelte Temperatur (361=36,5=18,5°?), das deckt sich dann in etwa mit meinem Temometer hier im Zimmer? Gruß
Was mir grad noch aufgefallen ist: -wenn der MCU neu gestartet wird, erscheint beim ersten Schleifendurchlauf die zweite Zeile im Display (so will ich das eigentlich auch haben), nachdem das erste Mal die Delay-Zeit abgelaufen ist, wird nur noch die erste Zeile geschrieben, jemand ne Idee, woran das liegt? -der Wert von 361 wird nicht aktualisiert, ich habe den Sensor mal erwärmt und abgekühlt, mit dem mySmartUSBTerminal reagiert die Temperatur entsprechend, in meinem Programm passiert nichts, es sthet immer nur 361 auf dem Display. Durch die Schleife im main müßte doch etwa alle 3s der Wert neu abgefragt werden? oder ich frag irgendwas andres ab, aber nicht wie gewollt das Temperatur-Register? Gruß
Guten Morgen, danke auch für den Denkanstoss von Oli ! ich hab´s gestern abend kurz vor 12 Uhr noch geschafft. Es funktioniert jetzt.. logischerweise über das 9Bit Muster. +125°C 0 1 1 1 1 1 0 1 0 VZ 64 32 16 8 4 2 1 0,5 @Daniel Wenn du den Code haben möchtest, schreib mir eine Sms. bin aber bald in Skiurlaub ! (grins) Gruss Marcus
Hallo, ich habe gerade das gleiche Problem, dass ich den Wert 185 auf LCD habe. Der Wert aktualisiert sich nicht und ist immer der gleiche. Deer Raumtemp. bei uns ist so etwa 25 °C. Kann mir jemdand helfen die richtige Temperatur anzeigen zu lassen. Danke Alex
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.