Forum: Mikrocontroller und Digitale Elektronik DS18s20 Temperatur über 20Grad


von armin (Gast)


Lesenswert?

Ich nutze den DS18s20 die Temperatur wird korrekt angezeigt aber nur bis 
20.1 Grad alles was höher ist kommt bei mir 127 als Anzeige.

Könnte mir einer weiterhelfen was bei der Berechnung falsch ist



1
   uint8_t  Vorkommastelle;
2
    int16_t Nachkommastelle;
3
   uint8_t scratchpad[9];
4
  
5
  
6
7
  uint8_t temp_lsb, temp_msb;
8
  float temp_float=0.0;
9
  float count_per_c=0.0, count_remain=0.0, bruch=0.0;
10
11
12
  // Auswertung
13
  temp_msb = scratchpad[1]; // Byte 1 enthält das Vorzeichen, 0 = +, 1 = -
14
  temp_lsb = scratchpad[0]; // Byte 0 enthält die Temperatur
15
  
16
  // temp_lsb um 1 nach rechts schieben, dann erhält man ganze Grad
17
  temp_float = temp_lsb >> 1;
18
  
19
  // Vorzeichen ist Minus, wenn temp_msb > 0
20
  // Da es ab und zu zu Vorzeichenfehlern kommt, muss temp_msb größer als 0x80 (128) sein,
21
  // damit das Vorzeichen wechselt (ist auch in der app-note so gemacht)
22
  if (temp_msb > 0x80)
23
    {
24
    temp_float = temp_float * -127.0;//-1.0;
25
    }
26
  
27
  // Nachkommazahl mit einer höheren Auflösung aus den Bytes 6 und 7 berechnen
28
  // Berechnung gemäss Datenblatt
29
  // Die Werte in Byte 6 und 7 müssen erst in eine float-Variable geschrieben werden,
30
  // ansonsten stimmt das Ergebnis nicht.
31
  count_per_c = scratchpad[7];
32
  count_remain = scratchpad[6];
33
  bruch = ((count_per_c - count_remain) / count_per_c);
34
  temp_float = temp_float - 0.25 + bruch;
35
36
    //sprintf(txbuf, "%f",temp_float);
37
38
39
  // float wird int zugewiesen -> Nachkommastelle fallen automatisch weg
40
  Vorkommastelle = temp_float;
41
  
42
  // Temperatur wird mal 10 genommen und dann Modulo 100 und Modulo 10 genommen,
43
  // danach der Betrag gebildet.
44
  // Das Ergebnis ist die Nachkommastelle als Integer
45
  Nachkommastelle = (temp_float * 10.0);
46
  Nachkommastelle = (Nachkommastelle % 100);
47
  Nachkommastelle = Nachkommastelle % 10;
48
  Nachkommastelle = fabs(Nachkommastelle);
49
    sprintf(txbuf,"%d,%d", Vorkommastelle, Nachkommastelle);

von Falk B. (falk)


Lesenswert?

@ armin (Gast)

Alles reichlich komliziert. Mit ein bisschen Festkommaarithmetik 
kriegt man das deutlich einfacher hin.

Beitrag "Onewire + DS18x20 Library"

Der IC liefert doch schon eine echte Zahl im Zweirkomplement, da muss 
man KEINE Vorzeichenerweiterung machen! Das mit der Zusatzauflösung ist 
Spielerei, wenn du einen höher auflösenden Sensor willst, nimm den 
DS18B20 und gut, der kostet kaum mehr.
1
    int16_t temp, vorkomma, nachkomma;
2
3
    // 2 Bytes in int16_t zusammenbauen, Temperatur in 0,5C Auflösung
4
    temp = ((int16_t)scratchpad[1] << 8) | scratchpad[0];
5
    
6
    // in 0.1 C Auflösung "umrechnen"
7
    temp *= 5;
8
   
9
    vorkomma = temp/10;
10
    nachkomma = abs(temp) % 10;

Wenn man unbedingt die erweiterte Auflösung haben will, dann so.
1
    int16_t temp, vorkomma, nachkomma;
2
3
    // 2 Bytes in int16_t zusammenbauen, Temperatur in 0,5C Auflösung
4
    temp = ((int16_t)scratchpad[1] << 8) | scratchpad[0];
5
    temp &= ~1;  // bit 0 loeschen
6
    temp <<= 3;  // x8 -> Auflösung 1/16 C
7
    temp = temp - 4 + (16-scratchpad[6]);
8
    // das /16 entfällt, denn wir rechnen mit 1/16 Grad Auflöung
9
    temp = (temp * 640L) >> 10;
10
    // Erklärung: Umrechung von 1/16 Grad Auflösung in 1/10 Grad
11
    // mittels Festkommaarithmetik
12
13
    // t(0.1C)  = t(1/16C) * 0.625
14
    //          = t(1/16C) * 625 / 1000
15
    //          = t(1/16C) * 625 * 1.024 / 1024
16
    //          = t(1/16C) * 640 / 1024 
17
   
18
    vorkomma = temp/10;
19
    nachkomma = abs(temp) % 10;

von Maximator (Gast)


Lesenswert?

Vielleicht vergleicht Du es einmal selbst mit den tausenden, 
funktionierenden "C" Codeschnipseln im Netz.

Erst mal Hausaufgaben selbst machen.
Ferner bitte ein Schaltbild von deinem Aufbau.
Woher soll hier jemand wissen wie der angeschaltet ist?

Untersuch erst mal die HW und verzichte auf parasitäre Versorgung und 
lange Leitungen.
Ein zweiter Sensor kann zum Test auch nicht schaden...

von Falk B. (falk)


Lesenswert?

Hmm, hab gerade mal meinen Code getestet, scheint zu funktionieren, der 
DS18S20 liefert 0,1C Auflösung. Aber bitte liebe Kinder immer schön den 
Unterschied zwischen Auflösung und Genauigkeit beachten ;-)

von armin (Gast)


Lesenswert?

Maximator schrieb:
> Vielleicht vergleicht Du es einmal selbst mit den tausenden,
> funktionierenden "C" Codeschnipseln im Netz.
>
> Erst mal Hausaufgaben selbst machen.
> Ferner bitte ein Schaltbild von deinem Aufbau.
> Woher soll hier jemand wissen wie der angeschaltet ist?
>
> Untersuch erst mal die HW und verzichte auf parasitäre Versorgung und
> lange Leitungen.
> Ein zweiter Sensor kann zum Test auch nicht schaden...

Die Hardware läuft die Temperratur wird ja auch richtig ausgegeben bis 
20.1Grad.
Von daher ist also etwas in der Berechnung bei mir nich richtig.

von (prx) A. K. (prx)


Lesenswert?

Falk B. schrieb:

Wie wärs mit
>     //          = t(1/16C) * 10 / 16
statt
>     //          = t(1/16C) * 640 / 1024
weils dann in 16 Bits bleibt?

Deine Herleitung ist etwas von hinten durch die Brust ins Auge. ;-)

: Bearbeitet durch User
von Falk B. (falk)


Lesenswert?

@ A. K. (prx)

>Wie wärs mit
>>     //          = t(1/16C) * 10 / 16
>statt
>>     //          = t(1/16C) * 640 / 1024
>weils dann in 16 Bits bleibt?

Kleiner Aufmerksamkeitstest. Aber wir haben ja in diesem Thread gelernt, 
das Codeeffizienz heute nicht mehr zählt ;-)

Beitrag "Re: Portzugriff bei AVR C leserlicher machen"

>Deine Herleitung ist etwas von hinten durch die Brust ins Auge. ;-)

Das war die rein formale Vorgehensweise.

https://www.mikrocontroller.net/articles/Festkommaarithmetik#Digitaler_Temperatursensor

Jaja, manchmal ist man halt betriebsblind 8-0

: Bearbeitet durch User
von armin (Gast)


Angehängte Dateien:

Lesenswert?

so im Anhang nochmal die Berechnung bis 20,2Grad gehts alles was über 
20,2Grad ist wird als 127 angezeigt.

Auf meinem Sensor steht DS1820 die hab ich damals von pollin und da 
stand DS18S20 mit falscher Beschriftung DS1820

von (prx) A. K. (prx)


Lesenswert?

Tipp nebenbei: Es gibt beliebte und rare Formate. Was 7-zip nicht 
verdaut bleibt bei mir meistens zu.

von Falk B. (falk)


Lesenswert?

Warum beherzigst du die Hinweise nicht?

von armin (Gast)


Lesenswert?

Falk B. schrieb:
> int16_t temp, vorkomma, nachkomma;
>
>     // 2 Bytes in int16_t zusammenbauen, Temperatur in 0,5C Auflösung
>     temp = ((int16_t)scratchpad[1] << 8) | scratchpad[0];
>
>     // in 0.1 C Auflösung "umrechnen"
>     temp *= 5;
>
>     vorkomma = temp/10;
>     nachkomma = abs(temp) % 10;

von armin (Gast)


Lesenswert?

Das hab ich so gemacht aber über die 20Grad bekomm ich auch hier die 127 
als ausgabe

von (prx) A. K. (prx)


Lesenswert?

Gib mal die Rohwerte aus.

von Falk B. (falk)


Lesenswert?

@ armin (Gast)

>Das hab ich so gemacht aber über die 20Grad bekomm ich auch hier die 127
>als ausgabe

Du hast möglicherweise das falsche HEX-File auf deinen Controller 
geladen.

von W.A. (Gast)


Lesenswert?

A. K. schrieb:
> Tipp nebenbei: Es gibt beliebte und rare Formate. Was 7-zip nicht
> verdaut bleibt bei mir meistens zu.

Dann verstehe ich deinen Kommentar nicht. 7-zip, zumindest in der schon 
etwas betagten Version 9.20 hat mit der angehängten Bis_20Grad_ok.rar 
keine Probleme.

armin schrieb:
> so im Anhang ...

von (prx) A. K. (prx)


Lesenswert?

Sorry, ist wohl dessen Integration defekt.

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
Noch kein Account? Hier anmelden.