Hallo, folgendes Problem: Mit dem Programm unten lese ich die Temperatur aus dem ds18b20 aus. Beispiel: PortB ( zeigt bei einem int-Typ die unteren 8 Bits an) Bits 0,1,2 und 4 leuchten = 23 dezimal. Das Zimmerthermometer zeigt 23,2 Grad an. Wenn ich den Sensor und das Thermometer ungefähr gleichermassen erwärme, steigt an Port B auch der Wert an, fast genauso wie beim Thermometer. Beim Abkühlen (Fön) zeigt sich der gleiche Effekt. An Port D zeigt sich nichts. Ich habe die Routine ds18b20_temperature... aus der Hilfe-Datei, nichts weiter beschrieben. Kann es sein, dass diese Routine die Temperatur auf 8 Bits reduziert ausgibt? Mit einer Genauigkeit von 1 Grad (LSB wäre hier 1 Grad). Was ich eigentlich haben will und erwarte, ist aber das vom DS18B20 gelieferte 16-Bit Wort der Temperatur. Da ich nur einen Sensor verwende,ist kein ROM code array notwendig und die addr muss Null (0) sein, siehe Hilfe-Datei über den DS18B20. Was mache ich falsch? Eine Bitte: Ich verwende nur einen Sensor, bitte keine Vorschläge mit mehreren Sensoren und auch keine Displayzusätze. Ich möchte das 16Bit-Wort der Temperatur nur in einer Variablen (hier z.B. wert) haben. Ich bin über jede Anregung sehr dankbar! ........ ........ // 1 Wire Bus initialization // 1 Wire Data port: PORTA // 1 Wire Data bit: 7 // Note: 1 Wire port settings are specified in the // Project|Configure|C Compiler|Libraries|1 Wire menu. w1_init(); ds18b20_init((0),15,35,DS18B20_12BIT_RES); while (1) { // Place your code here int wert; wert=ds18b20_temperature(0); delay_ms(100); PORTB=wert; wert=wert/256; PORTD=wert; delay_ms(1000); }
Beitrag "Re: DS18S20 - extended resolution bei Temperaturen um 0°C" Dein Wert steht in temp12 (bzw. weiter unten alternativ berechnet t12) als 12-Bit-Wert. Die entscheidenden Zeilen sind: if(d[1]){temp12=63491+8*d[0]-((d[6]-1)&7);} else {temp12= 3+8*d[0]-((d[6]-1)&7);} d[0] .. d[7] ist das Scratchpad. Vergiss die anderen kilometerlangen Programme.
Danke für die Antwort, eProfi ! Nur, ganz so gut habe ich Codevision nicht im Griff, wie füge ich die Zeilen ein ? Danke im voraus !
Evtl. habe ich nicht aufgeführt: Es geht um die Programmierung mit Codevision und dem DS18B20. Ich weiss nicht, ob der DS18B20 voll kompatibel mit dem DS1820 und DS18S20 ist !
> Es geht um die Programmierung mit Codevision und dem DS18B20. Doku zu CodevisionAVR http://nubielab.com/online_help/codevisionavr/ds18b20functions.htm >>> float ds18b20_temperature(unsigned char *addr) d.h. >> int wert; >> wert=ds18b20_temperature(0); ist ein Fail.
>> Was ich eigentlich haben will und erwarte, ist aber das vom DS18B20 >> gelieferte 16-Bit Wort der Temperatur. Dafür kannst du die Funktion ds18b20_read_spd() benutzen und die 8-Bit Werte temp_lsb und temp_msb aus der internen struct __ds18b20_scratch_pad; auslesen und in wert ablegen.
Hallo Krapao, vielen Dank für Deine Antwort! Zu der Antwort um 17:27 Uhr: 1. In dieser Doku steht nicht mehr als in der original Codevision Hilfe. 2. float ds18b20_temperature..... funktioniert nicht (bei mir) 3. Den letzte Teil in der Antwort habe ich ja in meinem Programm, ich bekomme aber kein 16-Bit Wort zurück, was ja mein Problem ist. Zu der letzen Antwort: Ich werde die Version mit dem Scratch pad versuchen. Hatte dies erstmal nicht in Betracht, weil dies doch umfangreicher ist. Ich dachte, es gibt eine kurze Lösung meines Problems. Nochmals vielen Dank !
Moment mal, es geht vielleicht doch ganz einfach: > Doku zu CodevisionAVR > > http://nubielab.com/online_help/codevisionavr/ds18... > >> float ds18b20_temperature(unsigned char *addr) > d.h. > > >> int wert; > >> wert=ds18b20_temperature(0); > > ist ein Fail. Vielleicht doch nicht? Führt er eine automatische Typkonvertierung durch? versuche mal folgendes: wert=10.0*ds18b20_temperature(0)+0.5; oder wert=16.0*ds18b20_temperature(0)+0.5; Wenn er meckert wg. nicht verträglichem Typ, schreibe wert=(int)(16.0*ds18b20_temperature(0)+0.5); Wenn Du es mit dem Scratchpad versuchen willst (diesmal mit der alternativen Formel): t12=3+8*a[0]-((a[6]-1)&7);//alternative way of calculation if(a[1]){t12-=128*16;} //correct by -128° heißt bei Dir: ds18b20_read_spd(0); wert=3+8*__ds18b20_scratch_pad.temp_lsb-((__ds18b20_scratch_pad.res2-1)& 7); if(__ds18b20_scratch_pad.temp_msb){wert-=128*16;}
> 1. In dieser Doku steht nicht mehr als in der original Codevision Hilfe. Deine original Codevision Hilfe habe ich nicht. Du hattest geschrieben >> Ich habe die Routine ds18b20_temperature... >> aus der Hilfe-Datei, nichts weiter beschrieben. daher habe ich eine, in meinen Augen ausreichende, Hilfeseite genannt. > 2. float ds18b20_temperature..... funktioniert nicht (bei mir) ds18b20_temperature() gibt die Temperatur als Gleitkommazahl zurück, der intern in der Funktion aus dem 16-Bit Messwert berechnet wird. > 3. Den letzte Teil in der Antwort habe ich ja in meinem Programm, ich > bekomme aber kein 16-Bit Wort zurück, was ja mein Problem ist. Du wandelst den Rückgabewert der Funktion zwar implizit in eine Ganzzahl, aber diese Ganzzahl wert ist nicht der originale 16-Bit Wert. Bei der Umwandlung einer Gleitkommazahl (float 20.3) in eine Ganzzahl (int 20) gehen dir aus Werte verloren! Du kannst das berücksichtigen z.B. in dem du in wert das 10- oder 100-fache der Temperatur speicherst
1 | #define TEMP_FAKTOR 10f
|
2 | int wert = TEMP_FAKTOR * ds18b20_temperature(0); |
und den TEMP_FAKTOR bei der Ausgabe/Anzeige berücksichtigst
1 | printf("Temperatur = %f", wert/TEMP_FAKTOR); |
> Zu der letzen Antwort: Ich werde die Version mit dem Scratch pad > versuchen. > Hatte dies erstmal nicht in Betracht, weil dies doch umfangreicher ist. > Ich dachte, es gibt eine kurze Lösung meines Problems. Bei dem Problem an den orginalen 16-Bit Wert zukommen?
1 | // originaler 16-Bit Wert auslesen
|
2 | if ( ds18b20_read_spd(0) ) |
3 | {
|
4 | wert = __ds18b20_scratch_pad.temp_msb; |
5 | wert <<= 8; |
6 | wert |= __ds18b20_scratch_pad.temp_lsb; |
7 | } else |
8 | wert = 0xFFFF; // Error |
Stimmt, der B-Typ gibt ja direkt 12 Bit aus, nur beim S muss man nach der einfachen Formel umrechnen. Beim 1820 braucht man die ausführliche Formel, da er mit 2 Oszillatoren arbeitet und das CountPerC nicht konstant 16 ist. NB: Der DS1820 (falsch beschriftet) von Pollin (180014) ist ein DS18S20. > Du kannst das berücksichtigen z.B. in dem du in wert das 10- > oder 100-fache der Temperatur speicherst > #define TEMP_FAKTOR 10f > int wert = TEMP_FAKTOR * ds18b20_temperature(0); > > und den TEMP_FAKTOR bei der Ausgabe/Anzeige berücksichtigst > printf("Temperatur = %f", wert/TEMP_FAKTOR); Dann kannst Du auch gleich direkt ausgeben: printf("Temperatur = %f", ds18b20_temperature(0)); Wozu erst * und dann / ? > } else > wert = 0xFFFF; // Error Würde ich nicht machen, da FFFF das Ergebnis bei -0.0625°C ist, siehe Beitrag "Re: DS18S20 - extended resolution bei Temperaturen um 0°C"
> Wozu erst * und dann / ?
Um ein Konzept zu zeigen, wie man eine Gleikommazahl in einer
Ganzzahlvariablen unterbringen kann.
Ein anderes Konzept (an der Stelle des TO würde ich das nehmen) wäre,
die Vorkommastellen im oberen Byte von wert unterbringen und die
Nachkommastellen im unteren Byte.
1 | uint16_t wert; |
2 | float tmp = ds18b20_temperature(0); |
3 | wert = tmp; // Nachkomma abschneiden |
4 | wert <<= 8; // ins obere Byte |
5 | wert |= tmp*100; // 2 Stellen Nachkomma abschneiden und ins untere Byte |
Mit der Ausgabe auf die beiden Ports, hat man dann quasi eine Binäranzeige einer Dezimalgleitkommazahl mit Vorkomma/Nachkomma auf 2x8 LEDs (?). > Würde ich nicht machen, da FFFF das Ergebnis bei -0.0625°C ist, D'accord. Der Errorwert war nur ein Bsp.
Mist zu schnell abgeschickt... wert |= (tmp*100)&0x00FF; // 2 Stellen Nachkomma abschneiden und ins untere Byte
Hallo eProfi und Krapao ! Ich habe die Möglichkeit genommen, die Temperatur mit der SPD (Scratch Pad) -Funktion auszulesen. Und das funktioniert super !!!!!!!!!! Ich musste allerdings sehr viel herumprobieren und nachlesen, weil die Werte in einer Struktur abgelegt werden, und das Auslesen war nicht einfach (kannte die struct Funktion nicht). Jetzt geht es, man kann sogar kontrollieren, ob temp_low und temp_high (Über-Untertemperturwerte) richtig übertragen worden sind. Mit 4 Zeilen ist alles erledigt. Nochmals vielen Dank! Ohne Eure Denkanstösse hätte ich das nicht hinbekommen! Gruss, Wolfgang
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.