DS18s20 Temperatur über 20Grad

Gast #4429559
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);
#4429603
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;
Gast #4429605
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...
Gast #4429730
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.
#4429750
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
Gast #4429819
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;

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren