www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik DS18B20: Negatives Vorzeichen bei -0.0625 bis -0.9375 ohne Float


Autor: Matthias Quade (zaphod_beeblebrox)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich baue gerade einen kleinen Temp-Logger für ein Abwasserrohr, das mir 
vor ein paar Tagen eingefroren ist.

Dabei nutze ich den DS18B20. Es funktioniert soweit auch alles ganz gut.
Ich splitte Vorkommastelle und Nachkommastelle:
temp = 0x12AB; // Beispiel
vorkomma  = temp / 16;
nachkomma = temp % 16;

// Bei negativer Temperatur das Vorzeichen der Nachkommastelle korrigieren (ist sonst 0.-50 °C)
if (temp & 0xF000) {
   nachkomma |= 0xFFF0;
   nachkomma  = -nachkomma;
}
nachkomma = nachkomma * 100 / 16;

Ich hab jetzt nur das Problem, dass ich Werte negative Temperaturen, die 
vorne eine 0 haben (also z.B. -0.5°C) so nicht darstellen kann, da die 0 
weder positiv noch negativ ist, ergo auch kein Vorzeichen hat.

Ich bau mir gerade ne double-krücke, aber so ganz elegant finde ich das 
nicht. Gibt es eurer Meinung nach noch einen schöneren Weg? Ich setz 
mich morgen sonst mal ran und bau ggf. einen eigenen Converter, der das 
berücksichtigt und trotzdem schön ausrichtet (so, dass die Kommastellen 
untereinander beleiben, wie es sprintf macht).

Für Tipps bin ich sehr dankbar & viele Grüße,
Matthias

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus,

nach dem Datenblatt wird bei Minus-Temperaturen
das Ergebnis negiert.

+25.0°C 0000 0000 0011 0010 0032h
+0.5°C 0000 0000 0000 0001 0001h
0°C 0000 0000 0000 0000 0000h
-0.5°C 1111 1111 1111 1111 FFFFh
-25.0°C 1111 1111 1100 1110 FFCEh

if(temp >= 0xFC91) // Minus
{
~temp  // weiter mit negierten Temp rechnen
...

printf(" - " %d, xxxx)

}

Gruß GG

Autor: Wolfgang-G (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@GG (Gast)
bist Du sicher, dass Du das richtige Datenblatt verwendest?
MfG

Autor: GG (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Servus Matthias,

ich verwende den Code mit wechselnden Prozessoren( vom Atxmega bis 
Atmega128) laufend. Über Null Grad (temp) unter Null Grad (~temp). Was 
für eine Routine ich nehme, entscheidet die Frage >= oder <= 0xFC91. 
Diesen Wert hab ich errechnet,getestet und auch irgend wo mal gelesen. 
Das Vorzeichen "+" oder "-" übernehme ich direkt aus der if(..) Abfrage. 
Ein kleiner Anzeigefehler besteht aber dennoch, da zum Beispiel bei 
exakt 0 Grad immer ein Vorzeichen (+/-) erscheint. Das verschwindet 
aber, wenn sich die Temp. um 0,5 Grad ändert! Das war's

Datenblatt ok!

Gruß GG

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
GG schrieb:
> nach dem Datenblatt wird bei Minus-Temperaturen
> das Ergebnis negiert.

Das ist falsch. Laut Datenblatt wird nicht negiert, sondern das 2-er 
Komplement verwendet, also eine übliche Darstellung der negativen Werte.

Zitat:
The temperature data is stored as a 16-bit sign-extended
two’s complement number in the temperature register (see  Figure 2).
Zitat Ende

>
> +25.0°C 0000 0000 0011 0010 0032h
> +0.5°C 0000 0000 0000 0001 0001h
> 0°C 0000 0000 0000 0000 0000h
> -0.5°C 1111 1111 1111 1111 FFFFh
> -25.0°C 1111 1111 1100 1110 FFCEh
>

Die oben angegeben Werte stehen so nicht im Datenblatt des DS18B20.

> if(temp >= 0xFC91) // Minus
> {
> ~temp  // weiter mit negierten Temp rechnen
> ...

Damit ergibt sich ein Fehler, da nicht das 2-er Komplement verwendet 
wird.

Autor: 900ss D. (900ss)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So würde es auch funktionieren:

  int temp16;
  unsigned char sign;

  temp16 = ReadTemperature();

  if( temp16 < 0 )
  {
    sign = 1;          // merke neg. vorzeichen
    temp16 = -temp16;  // temperatur positiv machen
  }
  else
    sign = 0;          // merke pos. vorzeichen

  // ab hier weiter mit pos. Temperaturwerten

Autor: Florian Trück (florian_t)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Also ich hole nur ungern diesen alten Thread wieder hoch, aber da ich 
gestern eine gefühlte ewigkeit nach der korrekten Lösung gesucht habe, 
hier nun meine Lösung:

- DS18B20 speichert negative werte als Zweierkomplement.
- Einfaches negieren des Wertes reicht da nicht.

So gehts:

//-----------------------------------
int16_t decimal;
uint8_t digit;

// Wert vom scratchpad holen
temp = temperature[0];
temp |= temperature[1] << 8;

if(temperature[1] > 7) // Sign bits gesetzt
{
  temp = ~(temp - 1); // Rückwandeln vom zweierkomplement
  decimal = (temp / 16) * -1; // Vorzeichen setzen
}
else
{
  decimal = temp / 16;
}

*digit = temp % 16;
//-----------------------------------

Soweit ich es bisher beurteilen konnte, lieferte der sensor bisher mit 
dieser Umrechnung nur glaubhafte Werte.

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.