Forum: Compiler & IDEs ds18s20: Wie implementiert Ihr die Formel ?


von Gast^2 (Gast)


Lesenswert?

Hallo,

ich möchte auf meinem Eigenbau-Wecker die Temperatur in Zehntel-Grad 
anzeigen. Dazu muss diese ( erg=lsb-0.25+((0x10-cnt_r)/0x10) ) Formel 
implementiert werden.

Wenn ich jedoch mit double loslege, dann fliegt mir der Flash um die 
Ohren, da der Controller schon ziemlich voll ist.

Welche Ideen gibts hier ?

Gruß

Andreas

von Steffen (Gast)


Lesenswert?

Das ganze mit Hundert (oder noch mehr) Multiplizieren und dann mit 
ganzen Zahlen rechnen. Ne Division durch 0x10 sollte doch das gleiche 
sein wie Division durch 16 (?). Dann entspricht das ganze einer 
Rechtverschiebung um 4. Vielleicht hilft dir das.

Steffen

von (prx) A. K. (prx)


Lesenswert?

Zunächst obige Formel etwas umbauen um alles ganzzahlig in 1/16 Grad zu 
rechnen. Danach ganzzahlig mal 10 durch 16.

von 900ss (900ss)


Lesenswert?

Falls Du es selber nicht hinbekommst....

Stichwort wäre dann: fixed point arithmetic, siehe Artikel
Festkommaarithmetik

Oder du bemühst die Forensuche, es gibt einige Threads zu dem Thema.

Oder die "Abschreiblösung" für den DS18S20:
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&t=24879

900ss

von Gast^2 (Gast)


Lesenswert?

Hi 900ss,

vielen Dank! Das ist de richtige Tipp ...

Gruß

Andreas

von 900ss (900ss)


Lesenswert?

Gast^2 wrote:
> vielen Dank! Das ist de richtige Tipp ...

Du meinst den Link zu AVRFreaks?
Hab ich befürchtet ;-) Damit lernst du es nicht. :-)

Gruß 900ss

von Christian L. (lorio)


Lesenswert?

A. K. wrote:
> Zunächst obige Formel etwas umbauen um alles ganzzahlig in 1/16 Grad zu
> rechnen. Danach ganzzahlig mal 10 durch 16.

Alles ganzahlig, wie A. K. schon geschriben hat.

erg = Ergebnis der Wandlung
erg_10 = Ergebnis in 1/10 Grad

1
int16_t erg_10 = 0;
2
int16_t erg    = getWandlungsErgebnis();
3
4
erg_10 += (erg >> 3); 
5
erg_10 += (erg >> 1);


=> erg/8 + erg/2 = erg/8 + 4*erg/8 = 5/8 * erg = 10/16 * erg


Achtung: funktioniert nur mit Werten >= 0
Hoffe aber, dass du die Idee bekommen hast, das signed-Bit noch passend 
zu manipulieren ist aber auch kein Problem.

von 900ss (900ss)


Lesenswert?

Christian L. wrote:
> => erg/8 + erg/2 = erg/8 + 4*erg/8 = 5/8 * erg = 10/16 * erg

Wenn du dir die Formel im Eingangspost mal genauer ansiehst, dann wirst 
du feststellen, dass deine Methode etwas übersieht und somit hier 
falsche Ergebnisse liefert.

900ss

von Gast^2 (Gast)


Lesenswert?

N'abend,

ich habe das jetzt so gelöst und erfolgreich getestet:

Eingabe
uint8_t -> msb, lsb, cnt_p_c, cnt_r,
uint16t -> erg
1
erg=msb; // baut 16-Bit-Zahl zusammen (9BIT Auflösung)
2
erg<<=8; //
3
erg|=lsb;//
4
erg>>=1; // eliminate bit0
5
6
//erg=lsb-0.25+((cnt_p_c-cnt_r)/cnt_p_c);
7
erg<<=4; // *16
8
erg-=4;  // -(4/16)
9
erg+=(cnt_p_c-cnt_r); // +(cnt_p_c-cnt_r)
10
erg*=10; // *10 gibt 1. Nachkommastelle, *100 gibt 1.+2. Nachkomaastelle
11
erg>>=4; // division /16
voila, erg enthält jetzt die Temp*10 bzw. *100

Gruß und Danke für die Tipps

Andreas

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.