www.mikrocontroller.net

Forum: Compiler & IDEs auflösung ds18s20


Autor: Steffen K. (steffen3)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,

ich möchte die Auflösung des ds18s20 auf 0.5° steigern, noch feiner 
aufgelöst wäre schön muss aber nicht sein.
Bisher gebe ich die Temperatur nur ganzzahlig aus, indem ich folgenden 
Code verwende
int temperatur=data[0]/2;
uart_puts(itoa(temperatur,buffer,10));
alle meine bisherigen Ansätze führten dazu, dass der Speicherverbrauch 
von ca.20% auf 105% stieg, so bspw.
double t=data[0];
double temperatur=t/2;
uart_puts(dtostrf(temperatur,2,1,buffer));
Hat jemand eine Idee wie ich es schaffen könnte?
gruss steffen

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Gib die Temperatur in 1/10 Grad aus:
char buffer[10];
int temperatur=(int)data[0]*5;      // Temperatur in 1/10°C
uart_puts(itoa(temperatur,buffer,10));


Oder füge den Dezimalpunkt von Hand ein:
char buffer[10];
int temperatur=(int)data[0]*5; // Temperatur in 1/10°C
itoa(temperatur,buffer,10);
i=0;
while(i<9&&buffer[i]) i++;     // Stringende suchen
buffer[i+1]=0;
buffer[i]  =buffer[i-1]; // Nachkommastelle
buffer[i-1]='.';         // Dezimalpunkt
uart_puts(buffer);

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Steffen K. schrieb:

> Hat jemand eine Idee wie ich es schaffen könnte?

Warum so kompliziert über floating point?
Du kannst nur 2 mögliche Nachkommastellen haben: entweder .0 oder .5
  int temperatur=data[0]/2;
  uart_puts(itoa(temperatur,buffer,10));

  if( data[0] % 2 ==  0 )
    uart_puts( ".0" );
  else
    uart_puts( ".5" );

manchmal ist es besser, vorhandenes Wissen auszunutzen, anstatt lange 
rumzurechnen :-)

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Die Idee mit dem LSB ist gut, ich hätte das aber so geschrieben:
  int temperatur=data[0]/2;
  uart_puts(itoa(temperatur,buffer,10));

  uart_puts(data[0]&1?".5":".0");
Liest sich irgendwie kopiergeschützt  ;-)

BTW:
Macht der Compiler aus %2 ein &1?

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:

> Liest sich irgendwie kopiergeschützt  ;-)

:-)

> Macht der Compiler aus %2 ein &1?

Wenn er das nicht hinkriegt, sollte sich der Compilerbauer lieber ein 
anderes Hobby suchen. zb. Holzschnitzen :-)

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
So simpel ist das wahrlich nicht. In diesem Fall lässt sich das nur 
deshalb direkt mit &1 abwickeln, weil die Daten wahrscheinlich aus einem 
uchar stammen und zumindest GCC deshalb spitz kriegt, dass er negative 
Werte nicht berücksichtigen muss.

Denn formell ist das trotzdem eine Division mit Vorzeichen und nicht 
jeder Compiler kriegt das spitz. Andere optimieren zwar die Division 
raus, aber die Ersatzsequenz ist deutlich komplexer als AND.

Denn -3 % 2 = -1, aber -3 & 1 = 1.

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> So simpel ist das wahrlich nicht. In diesem Fall lässt sich das nur
> deshalb direkt mit &1 abwickeln, weil die Daten wahrscheinlich aus einem
> uchar stammen und zumindest GCC deshalb spitz kriegt, dass er negative
> Werte nicht berücksichtigen muss.
>
> Denn formell ist das trotzdem eine Division mit Vorzeichen und nicht
> jeder Compiler kriegt das spitz. Andere optimieren zwar die Division
> raus, aber die Ersatzsequenz ist deutlich komplexer als AND.
>
> Denn -3 % 2 = -1, aber -3 & 1 = 1.

Und beides ist nicht gleich 0
Und nur darum geht es letztendlich in dieser Abfrage. Und das kriegen 
auch die Optimizer raus.

Autor: Lothar Miller (lkmiller) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Interessant wird die Berechnung zudem bei negativen Temperaturen (aber 
da is ja noch ein halbes Jahr hin ;-)

 0,5°C = 0x0001
   0°C = 0x0000
-0,5°C = 0xffff

Und das heißt: bei -0,5°C wird erst mal -1 ausgegeben (sofern die 
Übertragung aus data[0] nach temperatur erst mal vorzeichenrichtig 
korrigiert ist), danach wird (weil das LSB gesetzt ist) noch .5 
angehängt...
Daher wird eher die gefühlte als die gemessene Temperatur ausgegeben.

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
extern unsigned char data[];

int f(void)
{
    if (data[0] % 2)
        return 2;
    return 1;
}

int g(void)
{
    if (data[0] & 1)
        return 2;
    return 1;
}

läuft bei Digital Mars beispielsweise darauf raus:
_f              xor     EAX,EAX
                mov     AL,_data
                cdq
                xor     EAX,EDX
                and     EAX,1
                add     EDX,EAX
                cmp     EDX,1
                sbb     EAX,EAX
                add     EAX,2
                ret

_g              test    byte ptr _data,1
                mov     EAX,2
                jne     LF
                dec     EAX
                ret

Autor: A. K. (prx)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Lothar Miller schrieb:

> Daher wird eher die gefühlte als die gemessene Temperatur ausgegeben.

Lustig kann es allerdings werden, wenn man höher als 0.5° auflösen will, 
das geradeaus mit / und % bastelt und nicht an solche Effekte denkt. 
Also /10 vor und %10 nach dem Komma. Gibt dann so illustre Temperaturen 
wie "0.-3°C".

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
A. K. schrieb:
> Lothar Miller schrieb:
>
>> Daher wird eher die gefühlte als die gemessene Temperatur ausgegeben.
>
> Lustig kann es allerdings werden, wenn man höher als 0.5° auflösen will,
> das geradeaus mit / und % bastelt und nicht an solche Effekte denkt.
> Also /10 vor und %10 nach dem Komma. Gibt dann so illustre Temperaturen
> wie "0.-3°C".

LOL. Ja da ist was drann :-)

Wenns allerdings bei mir in der Wohnung 0.-3 Grad hat, dann ist die 
Anzeige mein geringstes Problem :-)

Autor: Steffen K. (steffen3)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
danke für die guten Vorschläge. Ich gebe die Temperatur jetzt mit einer 
Auflösung von 0.5° aus, indem ich überprüfe ob das LSB "1" oder "0" ist, 
das reicht mir doch aus für die Anwendung als normales Raumthermometer.

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.