Hallo Leute,
ich weis, DS18S20-Themen gibt es mehr als genug, ich hab auch schon fast
alle gelesen, aber ich komme trotzdem nicht weiter, vielleicht kann mir
ja jemand helfen.
Ich möchte mit meinem tiny2313 einen DS18S20 betreiben (ohne
Parasite-Power).
Nach langem hin und her kann ich ihn jetzt endlich ansprechen und die
Temperatur auf einem LCD-Display anzeigen lassen.
Probleme macht mir allerdings die Temperaturberechnung für Auflösungen
mit mehr als 9bit.
Ich bin mir nicht sicher an was es liegt, hab ich mich verrechnet,
liegts an den Variablen-Typen… ?
Wahrscheinlich ists ganz simpel, aber ich werd noch wahnsinnig, ich kann
den Fehler nicht finden!
Hier mein C-Code (Auszug):
1
voidTH_SendCommand(unsignedcharcommand)
2
{TH_InitBus();
3
TH_WriteByte(SKIP_ROM);
4
TH_WriteByte(command);
5
// hier entweder CONVERT_TEMPERATURE oder READ_SCRATCH_PAD
// *100 um keine Kommazahl auszugeben (<-> Datentyp int)
30
// 16, da Count_Per_C „hard-wired to 16“
31
// 25,25°C wird also zu 2525°C
32
33
returniTempResult;
34
}
Abgesehen davon, dass die Temperatur ca. 1°C zu hoch ausgegeben wird,
habe ich als Nachkommastellen immer ,75.
Ich habe bereits ein paar Temperaturberechnungen im Forum gesehen, aber
aus denen werde ich nicht schlau.
Weis jemand Rat?
Grüße,
Patrick
>>Wahrscheinlich ists ganz simpel>>...>>for (i=0; i<2; i++) { ucByteRead[i] = TH_ReadByte(); }>>...>>ucByteRead[6]>Bytes einlesen vor dem Benutzen ;-)
ups, da steht ja ne 2, das muss doch nicht sein!
so kanns nicht klappen!
Danke Dir!
Diskussionsgrundlage sei das Datenblatt
http://pdfserv.maxim-ic.com/en/ds/DS18S20.pdf
Ich sehe nirgends die Stelle, wo du COUNT_REMAIN (bei dir ucByteRead[6])
ausliest. Für mich sieht es so aus, als ob du nur TEMP_READ (MSB und
LSB) aus dem Scratchpad ausliest (for (i=0; i<2; i++) { ucByt...).
Deine Formel sieht auch etwas anders aus, als die Formel im Datenblatt.
Wahrscheinlich weil du nicht mit reellen Zahlen sondern mit Ganzzahlen
arbeiten willst.
Hallo Patrick,
der DS1820 liefert in den ersten 3 Nibbels die Ganzzahl, dann im letzten
Nibbel die Nachkommastelle welche bei max. Auflösung mit 0,0625°C
multipliziert werden muß.
Daher stimmt Deine Berechnung nur für die Ganzzahl.
Sowas in der Art wie:
wert = ((value >> 4)*10) + ((value << 12) / 6553);
Sollte funktionieren, wobei value das Eingangsword ist.
Grüße
Hans-Josef
Hallo Patrick,
im Anhang habe ich hier ein Beispielsprogram von Dallas mit dem ich vor
Jahren etwas experimentiert habe. Obwohl die automatische ROM Search bei
mir nicht funktioniert hat, gab's keine Probleme mit dem Auslesen der
Temepartur bei einem einzelnen DS1820. Vielleicht hilft Dir das. Die
Berechnung des Resultats war ueberhaupt kein Problem.
Gruss,
Gerhard
Hallo Leute,
erstmal vielen Dank für Eure Antworten!
@Stefan
Ich habe die 2 jetzt durch eine 9 ausgetauscht, lese jetzt also alle
Byte ein
Ja, ich will mit Ganzzahlen arbeiten, weil mir die Einführung von longs
und floats den Speicher flutet (aber liegt wohl genau der Hund
begraben…?!)
@Hans-Josef
Deine Berechnung kann ich prinzipiell verstehen.
Aber soweit ich das Datenblatt vom ds18’S’20 verstanden habe, steht im
Byte0 die Temperatur (wobei das LSB die 0,5°C ausdrückt) und im Byte1
lediglich das Vorzeichen (die Temperatur im Byte0 ist dann im
Zwierkomplement)
…oder habs ich falsch verstanden?
@Gerhard
Vielen Dank für den Code. Allerdings komme ich damit nicht ganz klar:
Ich sehe noch wie Du tmp_in[0] und tmp_in[1] belegst.
Gleich danach machst du den Vorzeichencheck:
1
// Check for sign bit.
2
if(value.tmp_w>32767){
3
temp=(signedlong)value.tmp_w-65536;
4
}else
5
temp=(signedlong)value.tmp_w;
Allerdings kann ich nicht erkennen, wo tmp_w belegt wird und was da drin
steht.
Ist die Berechnung beim ds18’B’20 anders als beim ds18’S’20?
Für welchen Controller hast du das Programm denn geschrieben?
Ich werde jetzt erstmal versuchen alle Einträge der Bytes 0-8 auf mein
LCD auszugeben um die Rechnung evtl. auf dem Papier nachvollziehen zu
können (das kann erstmal dauern).
Vielen Dank derweil,
Grüße und schönes Wochenende,
Patrick
Hallo Patrick,
das Program ist eine Adaptierung eines Dallas Programbeispiels fuer den
8051. Das Programbeispiel wurde von mir adaptiert um auf einem
PIC18F8722 zu laufen. Der Compiler ist von CCS. Ich habe mich nur damit
etwas rumgespielt. Soweit ich mich errinnern kann, haben die ROM Search
Funktion nicht richtig gearbeitet. Konnte aber ohne weiteres DS18?20
lesen. Desahlb dachte ich das koennte Dir nuetzlich sein. Ich kann mich
nicht mehr genau errinnern ob ich den 18B20 oder den 18S20 angeschlossen
hatte.
"value.tmp_w" ist Teil der unten geschrieben Union. Da value.tmp_in[n]
den selben Speicher Platz belegen wie value.tmp_w ist das ein bequemer
Weg um den Bau eines 16-bit Wertes zu vereinfachen.
union {
int tmp_in[2];
long tmp_w;
} value;
Das ist der uebliche Weg:
u_int16_temperature = (uint8_msb_wert << 8) + uint8_lsb_wert;
Der CCS compiler hat dafuer die Funktion:
u_int16_temperature = make16(msb, lsb);
Da die restlichen bits vom DS1820 bei Temperaturen unter Null gesetzt
sind, brauchst Du nur zu prufen ob der Wert groesser als 32767 ist und
in dem Fall einfach 65536 abziehen. Dann erhaeltst Du einen "Signed
Integer" Wert mit der Temperatur.
Der DS18B20 gibt die Temperatur mit 12-bit Aufloesung aus.
Gruss,
Gerhard
Hallo Zusammen,
hab auch schon mit den DS1820, DS18S20 bzw. DS18B20 gearbeitet. Unter
folgendem Link kann der Treiber heruntergeladen werden. Der Code kann
auch alle Sensoren automatisch finden (Search ROM Algorithmus). Die
Temperatur wird als float oder als Rohwert mit einer Aufkösung von
1/256°C zurückgegeben:
http://members.aon.at/electronics/pic/projects/ds1820/ds1820.html
MfG
Patrick schrieb:> // BERECHNUNG DER TEMPERATUR>> iTempResult = (100*Temp_Read + 75 - (100*ucByteRead[6])/16);> Abgesehen davon, dass die Temperatur ca. 1°C zu hoch ausgegeben wird,> habe ich als Nachkommastellen immer ,75.
Woher kommt denn auch diese seltsame Formel? Im Datenblatt zum Sensor
steht für die Temperaturberechnung mit Nachkommastellen die Formel:
Temperatur = Gelesene_Temperatur - 0,25 + (16 - Remain) / 16
Also muss deine obige Zeile lauten:
iTempResult = (100*Temp_Read - 25 + (16 - ucByteRead[6]) / 16 * 100) ;
Dann kommt auch das Richtige raus!
Ansonsten ist für den Fall eines negativen Vorzeichens (MS-Byte != 0)
die Methode der Komplementierung, Inkrementierung und Shift um ein Bit
nach rechts (= Teilen durch 2) für das LS-Byte sehr klug, denn sie
braucht deutlich weniger Arbeitsspeicher als andere Berechnungen.
Gruß, Volker