mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Temperaturberechnung für DS18S20


Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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):
void TH_SendCommand (unsigned char command)
{  TH_InitBus();
  TH_WriteByte(SKIP_ROM);
  TH_WriteByte(command);    
// hier entweder CONVERT_TEMPERATURE oder READ_SCRATCH_PAD
}

int TH_GetTemp( void )
{  int i, iTempResult;
  unsigned char ucByteRead[9] = {0,0,0,0,0,0,0,0,0};
  signed char Temp_Read;

  TH_SendCommand(CONVERT_TEMPERATURE);
  _delay_us(100);
  TH_SendCommand(READ_SCRATCH_PAD);
                    
  for (i=0; i<2; i++)  { ucByteRead[i] = TH_ReadByte();  }
  
//  BERECHNUNG DER TEMPERATUR

  if (ucByteRead[1] >= 1){ Temp_Read = (-1)*(((~ucByteRead[0])+1)/2);  }
  // Temperatur kleiner Null: 
  // Zweierkomplement -> um 1 rechtsschieben -> Vorzeichen setzen
  if (ucByteRead[1] < 1) { Temp_Read = ucByteRead[0]/2;  }  
  // Temperatur größer Null:
  // um 1 rechtsschieben
  
  iTempResult = (100*Temp_Read + 75  - (100*ucByteRead[6])/16);  
  // *100 um keine Kommazahl auszugeben (<-> Datentyp int)
  // 16, da Count_Per_C „hard-wired to 16“
  // 25,25°C wird also zu 2525°C
  
  return iTempResult;  
}

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

Autor: Jan M. (mueschel)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>Wahrscheinlich ists ganz simpel
>...
>for (i=0; i<2; i++)  { ucByteRead[i] = TH_ReadByte();  }
>...
>ucByteRead[6]


Bytes einlesen vor dem Benutzen ;-)

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
>>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!

Autor: Stefan B. (stefan) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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.

Autor: Hans Josef (hjm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Gerhard. (Gast)
Datum:
Angehängte Dateien:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Patrick (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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:
// Check for sign bit.
          if(value.tmp_w > 32767){
              temp = (signed long) value.tmp_w - 65536;
          }else
              temp = (signed long) 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

Autor: Gerhard. (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: Marco M. (marco1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo Patrick hast du zwischen einen Funktionierenden Code in C?

Könntest du den mal allen zur Verfügung stellen?

Danke

Autor: Mikes (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Marco M.
hab was da, dann gib mal deine email, dann schick ich es dir

Gruß

Autor: Marco M. (marco1987)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hier meine Addy danke fürs zuschicken,



rapid11@gmx.net

Autor: Christian Stadler (picpgm)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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/ds1...

MfG

Autor: Volker (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
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

Autor: eProfi (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So geht es beim DS18S20 und DS18B20 ohne Float:
Beitrag "Re: DS18S20 - extended resolution bei Temperaturen um 0°C"

Es sind ICs mit der Aufschrift DS1820 im Umlauf (z.B. Pollin 180014 
2,50), die in Wirklichkeit DS18S20 sind, da CountsPerDegree immer 16 
ist.

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.