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.
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 !
>> 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
intwert=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?
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_twert;
2
floattmp=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.
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