Im Rahmen der Weiterverarbeitung einer vom ADC eines Atmega8 gewandelten Spannung muss ich den eingelesenen Wert mit einer recht kleinen Kommazahl multiplizieren. Also in der Art: Ergebnis = ADC-Wert * 0,000000071351753 In Bascom ist das ja kein Problem. Nur muss ich das leider in Assembler lösen. Allerdings fehlt mir da im Moment ein gescheiter Lösungsansatz. Kann mir da jemand evtl. weiterhelfen?
Du kannst Ergebnis=0 schreiben, wenn du mit 16bit Ganzzahlen rechnest. Beschreib doch mal was du vorhast. Es gibt bestimmt eine einfachere Lösung die auch funktioniert.
in welcher Zahlendarstellung soll denn das Ergebnis sein, wie wird es weiterverarbeitet?
Ein word mal diese Konstante gibt nicht mehr sehr viel. Versuch doch mal ADC*71351753, behalte *0,000000000000001 RT
Es geht hierbei um die Aufloesung eines Polynoms 6. Grades, welches die nichtlineare Kennlinie eines Sensors beschreibt. Also ich muss da nicht nur einmal ADC*0.0000000xxxxx rechnen sondern im Prinzip so: Ergebnis = ADC*0.0000000xxxxxxxx Ergebnis = Ergebnis - 0.000000xxxxxxxx Ergebnis = Ergebnis * ADC Ergebnis = Ergebnis + 0.00000000xxxxxxxx Ergebnis = Ergebnis * ADC Ergebnis = Ergebnis - 0.00000xxxxxxxx Ergebnis = Ergebnis * ADC Ergebnis = Ergebnis + 0.000xxxxxxxx Ergebnis = Ergebnis * ADC Ergebnis = Ergebnis - 0.0xxxxxxxx Ergebnis = Ergebnis * ADC Ergebnis = Ergebnis + 0.0xxxxxxxx
Brauchst du dabei wirklich 8 Stellen Auflösung ? Der ADC liefert doch gerade mal 3 Stellen, da kannst du eigentlich spätestens ab der 5. Stelle aufhören ohne dass sich am Ergebnis wirklich was ändert.
Das kann man evtl. schon machen, da muss ich noch mal schauen. Mir geht es aber halt darum, wie ich die Multiplikationen möglichst effizient hinbekomme. Und da fehlt mit irgendwie immer noch der richtige Ansatz.
>>0,000000071351753
das ist 15 Stellen, nur hiterm Komma. Kann man sicher irgentwie anders
rum interpretieren (Float?)
/XlR.
Mach doch erstmal ne Genauigkeitsabschätzung, wieviel Iterationen überhaupt nen Sinn ergeben. Aus 0..1023 kannst Du doch nie 8 Digits rauskitzeln ! Maximal 3 Digits, eher noch weniger je nach Nichtlinearität, dann ist Ende der Fahnenstange. Wenn ich das in Assembler machen müßte, würde ich mit Excel ne Tabelle von etwa 50 Stützwerten ausrechnen lassen und dazwischen einfach linear interpolieren. Peter
Max, Deine kleinste Zahl ist ~10e-8, die größte ~10-2, macht 6 Zehnerpotenzen Dynamik, das entspricht 20Bit, 10Bit AD Wandler macht nochmal 10Bit, zusammen 30, da muß Du in Integer schon mit 64Bit rechnen, 32 reichen da nicht mehr. Oder Du muß in Assembler und float rechnen. Beides nicht so schön. Ich schließe mich meinen Vorrednern an: Die Genauigkeit, die Du anstrebst, brauchst Du sicher nicht. 20Bit Rechendynamik bei 10Bit AD Wandler Eingangsdynamik ist bullshit, das geht immer anders. Die Genauigkeitsanforderungen solltest Du nochmal überdenken. Cheers Detlef
@Max: Ein Polynom 6. Grades sieht normalerweise so aus: Ergebnis = a0 + a1*ADC + a2*ADC^2 + a3*ADC^3 + ... + a6*ADC^6 Im Prinzip geht das immer mit einfacher Festkommaarithmetik. Das ist in Assembler nicht so schwierig. Die sehr kleinen Werte, z.B. a6, werden vermutlich mit den Polynomtermen höheren Grades multipliziert, sodass das die einzelnen Terme am Ende immer einen "normalen" Wert ergeben. I.d.R. reicht dann eine 32-Bit-Festkommaarithmetik, z.B. mit 16 Vorkomma- und 16 Nachkommastellen oder auch 24 Vorkomma- und 8 Nachkommastellen. Wenn Du jetzt z.B. den Term a6*ADC^6 wie folgt aufspaltest a6*ADC^6 = a6^(1/6)*ADC * a6^(1/6)*ADC * ... * a6^(1/6) bleibst Du idealerweise immer in Deinem 32-Bit-Zahlenbereich. Du mußt Dir halt vorher überlegen, in welchem Wertebereich der ADC liegt, damit eine 32-Bit x 32-Bit-Multiplikation ein vernünftiges Ergebnis liefert. Du mußt ja nach der Multiplikation, die 64 Bits liefert, immer 32 Bits abschneiden können, ohne das Ergebnis nennenswert zu verfälschen. Sinnvollerweise verschiebt man die Binärzahlen vor der Multiplikation soweit nach links, dass die MSBs möglichst aufgefüllt werden und teilt das Produkt entsprechend wieder durch Rechtsschiebung. Dadurch erreicht man maximale Rechengenauigkeit. Bei komplizierten Formeln würde ich dann aber lieber eine Fließkommaarithmetik verwenden. Jörg
@Peter Dannegger >Mach doch erstmal ne Genauigkeitsabschätzung, wieviel Iterationen >überhaupt nen Sinn ergeben. >Aus 0..1023 kannst Du doch nie 8 Digits rauskitzeln ! Klar, sogar 10! Allerdings nur binäre ;-) MFG Falk
>Bei komplizierten Formeln würde ich dann aber lieber eine >Fließkommaarithmetik verwenden Du hast ihm gerade nachgewiesen, das er auch bei 32Bit Festkomma arithmetik aufpassen muss, das er nichts verliert. Ein float (und auch double) auf dem AVR hat 32Bit, 8 Bit Exponent, Mantisse: 23 Bit Mit deiner Mantisse von 23Bit wird die Situation wohl nur noch verschlechtert. Obwohl bei: >Ergebnis = ADC-Wert * 0,000000071351753 also wenn BASCOM nicht mit 64bit double rechnet wird es wohl kaum schlechter. Stichwort: Maschinengenauigkeit Mach es wie Peter vorschlägt mit einer Tabelle und Interpolation, selbst mit nur 50 Stützwerten würde ich davon ausgehen das das schon genauer ist, als dein jetziges BASCOM Programm. Warum muss das eigentlich unbedingt in Assembler sein?
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.