double in IAR für AVR

Hallo, benutzt hier jemand den IAR für den AVR?

Ich verzweifele gerade .....

Folgende Routine läuft unter Codevision AVR :

double PT100_Temp(double R) {

double T = 0; double x1 , x2 , x3 , x4 , x5 ;

x1 = ( 3.908302E-3 * (double)100 ) * ( 3.908302E-3 * (double)100 ) ; x2 = ( 2 * -5.802E-7 * (double)100 ) ; x3 = ( 4 * -5.802E-7 * (double)100* ( (double)100-R)) ; x4 = (-3.908302E-3 * (double)100 ) ;

T = ((-3.908302E-3*(double)100)+( sqrt( ( ((3.908302E-

3*(double)100)*(3.908302E-3*(double)100))- (4*-5.802E-7*(double)100*((double)100-R))) ) ))/(2*-5.802E-7*(double)100);

x5 = x1 - x3 ; x5 = sqrt(x5) ;

T = x4 + x5 ; T = T / x2 ;

return T; }

Unter dem IAR kommt schon bei x1 0 Raus !!! Und bei T= zerlegt es das ganze Programm ( Stack overflow ??)

Verwendet wird ein AtMega88.

Der IAR soll verwendet werden, weil der wohl der einzige AVR Compiler ist der double unterstützt.

Im Moment verwenden wir zum Test die 30 Tage Eval Version. Wenn das mit der Genauigkeit funktioniert wie gewünscht, dann würden wir die Vollversion kaufen. Im Moment haben wir daher auch keinen Support von IAR.

Andreas

Reply to
Andreas Ruetten
Loading thread data ...

Kenne den IAR nicht, aber hast du acuh die entsprechende Bibliothek eingebunden? 64-bit-Fliesskomma-Arithmetik auf einem 8-bit Processor zu implementieren, duerfte so viel Code/Performance erfordern, dass der Compiler/Linker dass bestimmt nicht automatisch unterstuetzt, sondern nur auf Anforderung.

Warum eigentlich? In deinem geposteten Code Beispiel, kann ich nicht unmittelbar sehen, warum 32-bit Fliesskomma nicht ausreichend sein sollte. Und du willst vermutlich auch nicht Temperatur einer Aufloesung von mehr als 5-6 Nachkommastellen messen.

Ich denke, wenn du denen sagst, dass dieses Feature kaufentscheiden ist, dann werden dir die schon weiterhelfen.

Gruss Klaus

Reply to
Klaus Bahner

Am 26.03.2010 16:55, schrieb Andreas Ruetten:

Hallo,

AVR Compiler benutze ich nicht, aber diverse andere für µC. Im Zweifelsfalle würde ich IAR trotzdem kontaktieren, genau mit deinem Argument des Kaufes wenn es ok ist. Wenn die nicht auf den Kopp gefallen sind, dann werden sie schon helfen. Ansonsten was soll das Ding machen? Die Routine scheint ziemlich "um die Ecke" gedacht. Die Konstanten ausmultiplizieren, ansonsten die Multiplikationen aufteilen. Manche Kompiler reagieren merkwürdig, wenn die Formel zu kompliziert werden. Wenn die Konstanten veränderbar sein sollten, dann bitte schön als const deklarieren (oder per #define) und die Berechnungen beim Startup machen.

Waldemar

PS.

Unten habe ich etwas bereinigt, wenigstens den Anfang

double PT100_Temp(double R) {

double T = 0; double x1 , x2 , x3 , x4 , x5 ;

// besser so, wenn man sowieso nicht von vorne es ausrechnet und // einsetzt. Hier erspart man mehrere Multiplikationen und Konversionen x1 = 3.908302E-3; x1 *= (double) 100.0; x4 = -x1; x1 *= x1;

x2 = ( 2 * -5.802E-7 * (double)100 ) ; // hier das gleiche: konstanten ausmultipliziert einsetzen x3 = (double) 2.0 * x2 * (double(100) -R);

// und so weiter. Hier T = x4 * sqrt(x1 - ...

T = ((-3.908302E-3*(double)100)+( sqrt( ( ((3.908302E- 3*(double)100)*(3.908302E-3*(double)100))- (4*-5.802E-7*(double)100*((double)100-R))) ) ))/ (2*-5.802E-7*(double)100);

x5 = x1 - x3 ; x5 = sqrt(x5) ;

T = x4 + x5 ; T = T / x2 ;

return T; }

Reply to
Waldemar Krzok

Am 26.03.2010 17:20, schrieb Waldemar Krzok:

Hatte ich zuerst auch, und so soll es eigentlich auch sein, ich dachte es liegt vieleicht an den Konstanten....

Jepp

Reply to
Andreas Ruetten

Am 26.03.2010 16:55, schrieb Andreas Ruetten:

Was hat der Prozessor Dir getan? Frau ausgespannt?

Ich hab's gerade mal mit gcc für ATmega168 übersetzt (liegt hier gerade herum). Kompiliert und läuft.

Ich habe PT100_Temp mal drei Werte vorgeworfen: PT100_Temp(10) ->-222 PT100_Temp(1) ->-244 PT100_Temp(-10)->-270

Bezüglich der "Genauigkeit" würde mich mal interessieren, welchen ADC Du benutzt, daß Du nicht mit int auskommst...

Falk

Reply to
Falk Willberg

Am 26.03.2010 17:16, schrieb Klaus Bahner:

Ja, es gibt unter Optionen einen Schalter "64bit double" . Ich denke der sagt dann dem Linker was er tun soll ...

Naja nach einigen Berechnungen sind es dann keine 6 Stellen mehr. BTDT ...

Andreas

Reply to
Andreas Ruetten

Am 26.03.2010 17:23, schrieb Falk Willberg:

Was hat denn die Auflösung des ADC mit der Genauigkeit der Float Berechnung zu tun? Das sind völlig verschiedene Dinge!

-> Rundungsfehler.

Wie auch immer ADC -> 12Bit.

Andreas

Reply to
Andreas Ruetten

Der IAR ist (im Gegensatz zum GCC) ein zwei-Stack-Compiler, d. h. der Parameterstack unterscheidet sich vom Returnstack. Zwar wird die Behandlung der Parameter (und lokalen Variablen) auf dem Stack damit einfacher, aber der Preis ist, dass man keinen "automatischen" Stack mehr für beide implementieren kann, einer von beiden ist in der Größe zwangsläufig limitiert (und bei zu großer Reservierung ist er nicht genutzter RAM).

Langer Rede kurzer Unsinn: hast du dir die Stack-Einstellungen mal angeguckt? Ich weiß nicht mehr ganz genau, welcher von beiden den anderen zerstören könnte.

--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Am 26.03.2010 17:29, schrieb Andreas Ruetten:

Ich sehe gerade, daß "double" beim avr-gcc "nur" 32 Bit hat.

Ich weiß ja nicht, was am Ende herauskommen soll, aber wenn die Datenquelle 12Bit Auflösung hat, kann ich mir nicht vorstellen, welche Anwendung für einen Microcontroller 64Bit-Operationen erfordern sollte...

Falk

Reply to
Falk Willberg

Am 26.03.2010 17:29, schrieb Andreas Ruetten:

irgendwie glaube ich, dass du etwas von der Arschseite an das Problem rangehst, aber vielleicht irre ich mich. Benutzt du irgendwelche Filter, die sehr empfindlich auf Koeffizientengenauigkeit sind? Hast du es schon simmuliert auf einem PC? Manchmal kann solche Analyse ziemlich viel Ärger ersparen. Dann sieht man, wo sich die Fehler kummulieren und ob 64 Bit wirklich notwendig sind. Auf einem 8-Bitter würde ich es vermeiden wollen. Bei 12 Bit ADC hast du 10-11 signifikante Stellen. Bis 32 ist noch ziemlich viel Luft.

Waldemar

Reply to
Waldemar Krzok

Am 26.03.2010 17:45, schrieb Waldemar Krzok:

??? Ein float belegt zwar 32Bit aber hat keine 32 Stellen!! Er besteht aus Mantisse und Exponent.

Reply to
Andreas Ruetten

Am 26.03.2010 17:47, schrieb Andreas Ruetten:

Stimmt. Ist die Frage wie genau willst du sein. Ich glaube, bei 32 Bit hast du 24+8 für Mantisse und Exponent. Ansonsten kann man im Integer-Bereich herumwursteln, aber das ist für hard-cores :-)

Waldemar

Reply to
Waldemar Krzok

Am 26.03.2010 17:23, schrieb Falk Willberg:

und welche Referenzspannung, Gruß vom LTZ1000 :-)

Butzo

Reply to
Klaus Butzmann

Nein, sind es nicht.

Spätestens ab dem Moment nicht mehr, wenn die per ADC gewonnene Größe als Eingangsgröße für Gleitkommaberechnungen dient. Insbesondere auch dann nicht, wenn es, wie in diesem Fall, gar die einzige Eingangsgröße ist.

12 Bit? Welcher Mega88 hat denn einen 12Bit-ADC?

Und selbst, wenn tatsächlich eine externe hochgenaue 12Bit-ADC am Werkeln sein sollte, unterstützt von einem fiktiven Pt100-Meßwiderstand, der die Kennlinie um Größenordungen genauer einhält, als der Standard verlangt, und das beides samt Verkabelung in einer Umgebung existiert, die einen SNR von 120 dB garantiert, sind es am Ende immer noch nur exakt 4096 diskrete Werte, die da letztlich aus dem ADC rauspurzeln können. Da kannst du dir den Arsch aufreißen für deinen IAR, das werden nicht mehr Werte und nicht mehr Bits, die zu ihrer Darstellung nötig sind.

Ich möchte jetzt nicht weiter ausführen, was das bezüglich der sinnvollen Rechengenauigkeit bedeutet, weil sich diese Frage für jeden Normalbegabten zumindest im Fall der konkreten Funktion erst garnicht stellt. Für die mit dem ADC-Output als einziger Input-Größe tritt nämlich eher in den Vordergrund, daß man die paar tausend Werte bzw. ihre Funktionsergebnisse locker zur Entwurfszeit (oder noch davor) vorberechnen und als (ggf. sogar massiv komprimierte) Tabelle in den Flash legen kann.

Diese Tabelle wird wahrscheinlich sogar kleiner sein als der Code für die benötigten Double-Operationen und die Laufzeiteffezienz des Table-Lookup selbst in einer stark komprimierten Tabelle dürfte gegen diese unsäglichen Double-Operationen zur Laufzeit mindestens um den Faktor 1E4 im Vorteil sein. Natürlich ohne jeden Verlust bei der von dir so dringend geforderten "Genauigkeit"...

Fazit: Leute wie du sollten lieber weiter die Fortschritte der PC-Hardware mit möglichst langsamer Software ausbremsen. Laßt die Finger von den µC. Ihr seid einfach noch nicht soweit, die wirklich effizient durch eure Unfähigkeit auszubremsen. Da müssen zuvor z.B. erst noch die Compiler beschafft werden, mit denen man den Keim der Ineffizienz wirklich so richtig sprießen lassen kann. Aber tröste euch: Auch Microsoft ist noch nicht soweit, Windows 7 auf dem ATMega88 vorzustellen. Auch Intel ist derzeit zu stark beschäftigt, die eigenen Atome auszubremsen, hat also keine freien Spitzen, um auch zu Hilfe zu kommen.

Mann, ist mir schlecht...

Reply to
Heiko Nocon

Was sollen die Beleidigungen? Mit dem falschen Fuß aufgestanden?

Am 26.03.2010 21:43, schrieb Heiko Noc>

Sind es doch.

Natürlich extern ..

Das ist schon klar, es geht aber um die Rundungsfehler der Berechnungen, und wenn die zu hoch sind, das gibt es im Ergebnis eben nicht die vollen

12Bit.

Tja im Gegensatz zu dir bin ich eben nicht "Normalbegabt" und stelle mir die Frage.

Für die mit dem ADC-Output als einziger Input-Größe tritt

Es muß aber leider Dynamisch sein, da sich Werte zur Laufzeit ändern.

Was bist du denn für ein Schmock?

/ Weitere Sinnlose Beleidigungen gelöscht ....

Wieder in den Spiegel geschaut?

Reply to
Andreas Ruetten

Andreas Ruetten schrieb:

[.....]

Eventuell kann man die Berechnungen aber etwas geschickter umformen, um mit weniger Aufwand hinzukommen. Und vielleicht noch andere Fehlerquellen betrachten: Wie genau rechnet z.B. die sqrt-Funktion in dieser Library?

64Bit-Gleitkommaoperationen auf einem schnöden Temperaturwert sehen doch ein wenig nach der Taktik "Hilfe, ein Spatz - wo ist meine FLAK?" aus. Im Extremfall (und mit viel Vorüberlegungen) könnte man sowas sogar in ausreichend langen Integern rechnen, da weiss man auch genau wann Bits wegfallen.

Das ist aus dem obigen Code aber nicht ersichtlich - lauter Konstanten. Eventuell ließe sich auch eine Kennlinie oder ein Kennfeld im Flash ablegen und noch dynamisch verschieben?

--
Gruesse, Stephan
Reply to
Stephan Urban

Am 26.03.2010 22:07, schrieb Andreas Ruetten:

Guck' mal in den Header. Diesen Newsreader verwenden nicht so viele Pöbler ;-)

...

Wahrscheinlich wirst Du um die Berechnung der Rundungsfehler ohnehin nicht herumkommen. Dann kannst Du evtl. auch gleich auf 32Bit oder sogar

16Bit Integer umstellen. Am Ende könnte das deutlich zuverlässiger funktionieren.

...

Die Funktion PT100_Temp() kann nur 4096 verschiedene Werte (12 Bit) liefern weil es nur 4096 mögliche Parameter gibt. Das könnte man auch mit einer Tabelle lösen, wenn man alle Rückgabewerte im Flash unterbringen könnte ;-)

Einem Datentyp, mit dem man nie (foo == bar) schreiben kann, vertraue ich sowieso nicht.

Falk

Reply to
Falk Willberg

Andreas Ruetten schrieb:

Du hast aber selbst bei 32-bit-FP 24 bits in der Mantisse. Das ist gegenüber den 12 bits des Eingangssignals nochmal mehr als

30 dB Spielraum, um Rundungsfehler auszugleichen.
--
cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)
Reply to
Joerg Wunsch

Andreas Ruettenschrieb: "

Was steht denn im List-File?

Dirk

Reply to
Dirk Ruth

Das ist richtig. Aber bei der konkreten Funktion der Fehler auch bei der Verwendung von single längst nicht groß genug, um stören zu können.

Natürlich ändern sie sich, aber sie können niemals andere Werte annehmen, als in zwölf Bit unterzubringen sind. Und da es die einzige variable Größe der Funktion ist, kann es auch nur exakt 4096 mögliche Funktionsergebnisse geben. Und die kann man mit jeder gewünschten Genauigkeit vorberechnen und die Ergebnisse als Tabelle von 12 Bit-Werten ablegen. Eine viel genauere Darstellung der Ergebnisse macht keinerlei Sinn, weil eben am Eingang auch schon nur 12 Bit Genauigkeit vorhanden sind. Aus praktischen Gründen würde man aber wohl mit 16 Bit für die Ergebnisse arbeiten. Es werden dann exakt 8192 Byte für die unkomprimierten Ergebnisse benötigt.

Wenn man sich aber die Eigenschaften der Ergebnisse anschaut, wird sich einen gewaltige Redundanz ergeben, sie werden sich also ganz hervorragend komprimieren lassen. Dazu ist nichtmal ein richtig guter Entropie-Encoder nötig, sondern selbst mit einfachsten Mitteln (Speicherung der Differenzen benachbarter Werte mit einigen Stützpunkten in voller Genauigkeit zur Verringerung des Rechenzeitaufwandes für die "Dekomprimierung", also den Lookup in die Tabelle) ist schon eine Komprimierung knapp um den Faktor 4 erreichbar. Wir sind dann also bei gut 2k Platzbedarf.

Und in gut 2k bringst du sicher keine Double-Bibliothek unter. Die Lösung mit vorberechneten Werten ist also in absolut jeder Hinsicht weit überlegen. Sie ist zur Laufzeit viel schneller und benötigt weniger Platz im Flash.

Reply to
Heiko Nocon

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.