Hallo, Ich habe einen Drucksensor mit einem Messbereich von 0 - 10 bar
und einen mit -1 - +1 bar. Beide geben eine analoge/lineare Spannung
von 1-5 Volt aus. Die wird runter geteilt auf 1,235V und mit einem 10bit
ADC eingelesen.
Bei einer Spannungsausgabe von 0-5 Volt wäre ja die Rechnung für den
Druck ganz "normal":
U = 1,235 * (ADC/1023)
Druck = 10 * (U/1,235)
Da mein Spannungsbereich am Sensor aber erst bei einem Volt beginnt,
beträgt die Spannung am ADC 0,247 - 1,235V bzw. seine Werte von 205 -
1023 (Hab ich mir zumindest so zusammengereimt).
Kann mir jemand sagen wie ich die Formel mit dem o.ä. Spannungsbereich
aussehen müsste und wie würde sie mit dem Sensor: -1 - +1 Bar aussehen.
Danke im Voraus.
Alex
Alexander K. schrieb:> Kann mir jemand sagen wie ich die Formel mit dem o.ä. Spannungsbereich> aussehen müsste und wie würde sie mit dem Sensor: -1 - +1 Bar aussehen.
Sowas konnte früher (tm) ein Schüler der 8. Klasse berechnen. In welche
Klasse gehst du?
Siehe AD-Wandler.
na ja, der Messbereich umfasst halt 2 Bar zwischen -1 und +1. Damit
liegt "0" bar genau "in der Mitte", also bei 512, 0 enspricht "-1" Bar
und 1023 "+1" bar. Oder in deiner Formel Druck = -1 + 2*(U/Umax)
Das "Da mein Spannungsbereich am Sensor aber erst bei einem Volt
beginnt" verstehe ich nicht
Michael P. schrieb:> na ja, der Messbereich umfasst halt 2 Bar zwischen -1 und +1. Damit> liegt "0" bar genau "in der Mitte", also bei 512,
Nö. Denk nochmal nach.
> Das "Da mein Spannungsbereich am Sensor aber erst bei einem Volt> beginnt" verstehe ich nicht
Dort liegt dein Problem.
Michael P. schrieb:> Das "Da mein Spannungsbereich am Sensor aber erst bei einem Volt> beginnt" verstehe ich nichtAlexander K. schrieb:> Beide geben eine analoge/lineare Spannung> von 1-5 Volt aus.
Das bedeutet im Falle des 0-10-Bar-Sensors, daß 1V 0 Bar entsprechen,
und 5V 10 Bar.
Arduino F. schrieb:> Alexander K. schrieb:>> (ADC/1023)> Sollte da nicht 1024 stehen
Korrekterweise und schon allein um es dem Compiler einfacher zu machen
sollte da 1024 stehen.
Siehe den Beitrag "ADC-Spannung korrekt berechnen?" und den darin
verlinkten Beitrag "1023 oder 1024"
Für mich sind 1023 an dieser Stelle schlicht ein Programmfehler. Und
wenn ich diesen Fehler sehe, dann sind da sicher noch mehr...
Falk B. schrieb:> In welche> Klasse gehst du?
Ich gehe in gar keine Klasse und arbeite üblicherweise auch nicht in der
Branche ;)
Lothar M. schrieb:> Siehe den Beitrag "ADC-Spannung korrekt berechnen?" und den darin> verlinkten Beitrag "1023 oder 1024"
Danke für den Hinweis.
Alexander K. schrieb:> Ich gehe in gar keine Klasse und arbeite üblicherweise auch nicht in der> Branche ;)
Schon mal was von einer linearen Geradengleichung gehört?
1
Sensor ADC-Eingang ADC-Wert Druck1 Druck2
2
1V 0,247V 205 0bar -1bar
3
3V 0,741V 615 5bar 0bar
4
5V 1,235V 1023 10bar 1bar
5
6
p = f(adc) = M*ADC+N
7
8
// 10 Bar Sensor
9
M = dy/dx = (10bar-0bar)/(1023-205)=0,0122 bar/LSB
10
N = P2-M*ADC = 10bar - 0,0122bar/LSB*1023 = -2,506bar
11
12
// +/-1 Bar Sensor
13
M = dy/dx = (1bar- -1bar)/(1023-205)=0,002445 bar/LSB
14
N = P2-M*ADC = 1bar - 0,002445bar/LSB*1023 = -1,5bar
Man kann das mit Fließkomma rechnen und ist fertig. Man kann aber auch 5
Minuten nachdenken und Festkommaarithmetik benutzen. Wenn man alles
in Millibar rechnet, braucht es keine Kommas. Dabei darf im
Zwischenergebnis kein Überlauf auftreten, also Rechnung mit 32 Bit. Beim
+/1bar Sensor reichen die Millibar nicht, da muss man eher auf Mikrobar
gehen. Klingt komisch, ist aber so. Kann man aber am Ende wieder auf
Millibar umrechnen.
1
intp;
2
p=122*(int32_t)ADC-2506;// 10 bar Sensor
3
p=(2445*(int32_t)ADC-1500000)/1000;// +/-1 bar Sensor
Matthias S. schrieb:> Wenn da im Nullfall immer 1 Volt am Eingang steht, musst du diesen> Offset eben abziehen.
Nullfall? Ich kenn einen Wasserfall und Durchfall, aber keinen Nullfall
;-)
Moin,
ich habe so einen Drucksensor in mein Heizungsrohr eingebaut. Liefert
auch von 1 bis 5 V. Dann ist es etwas in Vergessenheit geraten. Ich
hatte vor, wie in anderen Schaltungen die Werte mit einem ATtiny84 zu
messen und zu speichern. Abfrage über I2C. Der hat die Möglichkeit über“
Differential ADC Channel“ zu messen. Leider ist der Minuspol mit dem
Gehäuse verbunden und somit der „Rauschabstand“ kleiner. Dadurch ist es
für mich günstiger mit 5V VCC ADC Input Voltage Range zu messen.
Gruß
Carsten
> M = dy/dx = (10bar-0bar)/(1023-205)=0,0122 bar/LSB
10
> N = P2-M*ADC = 10bar - 0,0122bar/LSB*1023 = -2,506bar
11
>
12
> // +/-1 Bar Sensor
13
> M = dy/dx = (1bar- -1bar)/(1023-205)=0,002445 bar/LSB
14
> N = P2-M*ADC = 1bar - 0,002445bar/LSB*1023 = -1,5bar
15
>
16
>
>> Man kann das mit Fließkomma rechnen und ist fertig. Man kann aber auch 5> Minuten nachdenken und Festkommaarithmetik benutzen. Wenn man alles> in Millibar rechnet, braucht es keine Kommas. Dabei darf im> Zwischenergebnis kein Überlauf auftreten, also Rechnung mit 32 Bit. Beim> +/1bar Sensor reichen die Millibar nicht, da muss man eher auf Mikrobar> gehen. Klingt komisch, ist aber so. Kann man aber am Ende wieder auf> Millibar umrechnen.>>
1
>intp;
2
>p=12,2*(int32_t)ADC-2506;// 10 bar Sensor
3
>p=(2445*(int32_t)ADC-1500000)/1000;// +/-1 bar Sensor
4
>
Danke für die konkrete Lösung! Funktioniert gut (nachdem ich deinen
Kommafehler ausgebessert habe ;))
Für die 10 Bar Ausführung hätte ich mir jetzt auch die Formel
zusammengereimt:
1
intp;
2
p=(10/819)*(adc-205);
Lineargleichnug dürfte aber die universellere Lösung sein.?
Alexander K. schrieb:> Beide geben eine analoge/lineare Spannung> von 1-5 Volt aus. Die wird runter geteilt auf 1,235V und mit einem 10bit> ADC eingelesen.
Diesen Satz solltest du noch mal überdenken. Herunterteilen eines
Bereichs auf einen festen Wert?? Ich nehme mal an, die wird mit 1,235/5
multipliziert. Sauber formulieren ist oft die halbe Lösung.
Ausgangslage bei dem +-1 Sensor:
U_adc = U_sensor * 1,235/5
ADC = U_adc * 1024/1,235
U_sensor = 2*Druck + 3
Wir eliminieren U_adc:
ADC = (U_sensor * 1,235/5) * 1024/1,235
U_sensor = 2*Druck + 3
Wir eliminieren U_sensor:
ADC = (2*Druck + 3) * 1,235/5 * 1024/1,235
Auflösen nach Druck:
Druck = (ADC * 5/1024 -3)/2
Kein Problem von Elektronik, kein Problem von Software. Stimmt schon,
alles nur Rechnen Klasse 8 oder so.
Falk B. schrieb:> Nullfall? Ich kenn einen Wasserfall und Durchfall, aber keinen Nullfall> ;-)
Siehste doch - eben erfunden und was für ein schönes Wort das ist...
Alexander K. schrieb:> int p;> p = (10/819) * (adc-205);>> Lineargleichnug dürfte aber die universellere Lösung sein.?
Funktioniert so nicht, weil 10/819=0 ist als Integerrechnung. Siehe
Festkommaarithmetik. Bestenfalls so.
Falk B. schrieb:> p = (((int32_t)adc-205)*10)/819;>> Erst alle Multiplikationen, dann alle Divisionen.
Wenn, dann doch wohl besser
p = (((int32_t)adc-205)*25)/2048;
Rainer W. schrieb:>> Erst alle Multiplikationen, dann alle Divisionen.>> Wenn, dann doch wohl besser>> p = (((int32_t)adc-205)*25)/2048;
Das ist der nächste Schritt zur Optimierung. Man kann und sollte aber
nicht zuviel auf einmal machen, das versteht keiner.
Alexander K. schrieb:> was spricht dagegen mit einem float oder double zu arbeiten?
Der 8-Bit Programmierer Ehrencodex ;-)
Heutzutage schert sich kaum noch einer um Resourcenbedarf und sinnvoll
Lösungen, da darf auch mal ein 32 Bit Controller ne LED blinken. Dagegen
ist ne Fließkommaberechnung harmlos. Nimm sie und gut. Es gibt andere,
echte Probleme auf dieser Welt.
Falk B. schrieb:> Heutzutage schert sich kaum noch einer um Resourcenbedarf und sinnvoll> Lösungen, da darf auch mal ein 32 Bit Controller ne LED blinken.
Wenn Moby das liest, eröffnet er gleich die nächsten 10 Threads.
Alexander K. schrieb:> was spricht dagegen mit einem float oder double zu arbeiten?
Solange Dein Arduino genug freien Speicher hat, nichts.
Falk B. schrieb:>> was spricht dagegen mit einem float oder double zu arbeiten?> Der 8-Bit Programmierer Ehrencodex ;-)> Heutzutage schert sich kaum noch einer um Resourcenbedarf und sinnvoll> Lösungen,
Man sollte sich bemühen, immer sparsam zu agieren. Im Gegensatz zum PC
kann man im Mikrocontroller nicht mal eben etwas RAM / ROM nachrüsten.
Falk B. schrieb:> Der 8-Bit Programmierer Ehrencodex ;-)
Na, nicht nur, Fließkommazahlen sind verbuggt. Mit Integern ist man da
schon eher auf der sicheren Seite.
Darüber hinaus kann man öfter auch (positive) Überraschungen erleben
wenn man sich Mühe gibt, und kommt auch eher vom Automatismus weg,
Fließkommazahlen benutzen zu müssen.
Im Zweifelsfall kann man es einfacher machen, und fehlerfreier.
Wie gesagt, im Zweifelsfall, aber nicht im Sinne von voreiliger
Optimierung. Die ist nämlich zu recht als Wurzel allen Übels verpönt.
Erstmal gucken, dass überhaupt was läuft.
Also durchaus keine triviale Frage ;)
(https://softwareengineering.stackexchange.com/questions/80084/is-premature-optimization-really-the-root-of-all-evil)
MaWin O. schrieb:> Wenn Moby das liest, eröffnet er gleich die nächsten 10 Threads.
Wäre ja gar nicht so schlimm, wenn das nicht ständig der selbe
neuaufgegossene kalte Kaffee wäre.
Ich fand z.B. diese zugeHolmten Threads gar nicht so übel, auch wenn ich
gelegentlich recht dankbar war für das ein oder andere Stoppschild da.
Rbx schrieb:> Ich fand z.B. diese zugeHolmten Threads gar nicht so übel, auch wenn ich> gelegentlich recht dankbar war für das ein oder andere Stoppschild da.
ehm... wat?
Stefan F. schrieb:> Rbx schrieb:>> Fließkommazahlen sind verbuggt>> Inwiefern?
"verbuggt" ist vielleicht der falsche Begriff.
Eine Zahl wie 1,235 lässt sich z.B. nur näherungsweise als
Fließkommazahlen darstellen. Deswegen ist beispielsweise von einem
Vergleich von Fließkommazahlen auf Gleichheit in den meisten Fällen
unbedingt abzuraten.
Rainer W. schrieb:> "verbuggt" ist vielleicht der falsche Begriff.
Ja!
Denn sie funktionieren wie spezifiziert.
Rainer W. schrieb:> Deswegen ist von einem Vergleich von> Fließkommazahlen auf Gleichheit in den meisten Fällen unbedingt> abzuraten.
Ja!
Tipp: Sage "immer"!
Denn wüsste man vorher, dass sie exakt gleich sind, bräuchte man keinen
Vergleich mehr.
Arduino F. schrieb:> Tipp: Sage "immer"!> Denn wüsste man vorher, ob sie exakt gleich sind, bräuchte man keinen> Vergleich mehr.
Nein, sag ich nicht. Und natürlich können die Binärpräsentationen zweier
Float Zahlen gleich sein, auch wenn man vorher nicht weiß, dass sie
gleich sind.
Wenn klar ist, dass die Binärpräsentation der beiden zu vergleichenden
Zahlen auf gleiche Weise entsteht, d.h. im Fall der "Gleichheit" beide
binär gleich werden müssen, kann der Vergleich kappen ;-)
Rainer W. schrieb:> Deswegen ist beispielsweise von einem Vergleich von> Fließkommazahlen auf Gleichheit in den meisten Fällen> unbedingt abzuraten.
Das sind Grundlagen in praktisch jeder Programmiersprache.
Stefan F. schrieb:> Das sind Grundlagen in praktisch jeder Programmiersprache.
Welche Programmiersprache verbietet dir, Floats auf Gleichheit zu
prüfen?
Rainer W. schrieb:> Welche Programmiersprache verbietet dir, Floats auf Gleichheit zu> prüfen?
Welche Programmiersprachen erlaubt dir keine Dummheiten zu begehen?
Rainer W. schrieb:> Welche Programmiersprache verbietet dir, Floats auf Gleichheit zu> prüfen?
Warum sollte eine Programmiersprache das verbieten? Float Variablen
können den gleichen Wert enthalten.
Stefan F. schrieb:> Warum sollte eine Programmiersprache das verbieten? Float Variablen> können den gleichen Wert enthalten.
Naja, sie können schon, aber häufig tun sie es nicht obwohl sie gleich
sein müssten - wenn man es mit dem Taschenrechner nachrechnet.
Verbieten muss man es nicht, aber vielleicht warnen? [Vielleicht tut das
ein Compiler auch, habe schon lange keine Floats mehr verwendet].
Ich möchte nicht wissen, wie viele da schon darüber gestolpert sind ...
Wie wäre es mit |Wert1 - Wert2| < epsilon?
Stefan F. schrieb:> Das sind Grundlagen in praktisch jeder Programmiersprache.
Das sind die Grundlagen des üblichen binary32 Zahlentyps der IEEE754:
- https://de.wikipedia.org/wiki/IEEE_754Stefan F. schrieb:> Rbx schrieb:>> Fließkommazahlen sind verbuggt> Inwiefern?
Wenn man sie noch nicht ganz verstanden hat, dann mutet es einen leicht
so an, wenn man einen Vergleich wie z.B.
1
f=2.0+1.33
2
if(f==3.33)
3
tuwas();
macht und tuwas() nicht aufgeriufen wird.
Mich stört an floats eher, dass sie zwar eine gewaltige Dynamik haben,
aber nur 6 signifikante Stellen. Man kann also nicht sicher sein, dass
nach dieser Rechnung wie erwartet f = 100.001 ist.
1
f=1000.0;
2
f+=0.001;
Drum nehme ich float nur dort, wo es nötig ist. Und sonst eben einen
Integer in "Dezigrad" oder "Centibar" oder "Millimeter", wenn ich wegen
einer höheren Auflösung 0,1 Grad oder 0,01 bar oder 0,001 m auflösen
will.
Lothar M. schrieb:> Mich stört an floats eher, dass sie zwar eine gewaltige Dynamik haben,> aber nur 6 signifikante Stellen.
Es gibt ja auch noch double (64 Bit) und long double (80 Bit).
> Man kann also nicht sicher sein, dass> nach dieser Rechnung iwe erwartet f = 100.001 ist. f = 1000.0;> f+= 0.001;
Nix ist perfekt.
Falk B. schrieb:> Es gibt ja auch noch double (64 Bit) und long double (80 Bit).
Klar. Aber das macht den 8-Bit-Andruiden nicht schneller oder das
Ergebnis besser.
Lothar M. schrieb:> Klar. Aber das macht den 8-Bit-Andruiden nicht schneller oder das> Ergebnis besser.
Von einem 8-Bit Andruiden war in der gesamten Diskussion, bis auf meine
Anmerkung des 8-Bit Programmierer Ehrenkodex, keine Rede.
Falk B. schrieb:> Von einem 8-Bit Andruiden war in der gesamten Diskussion, bis auf meine> Anmerkung des 8-Bit Programmierer Ehrenkodex, keine Rede.
Da hast du durchaus Recht.
Allerdings habe ich einfach auf den Eröffnungspost einen
Wahrscheilichkeitsalgorithmus angewendet und besonders diese Information
linear extrapoliert, wo
Alexander K. schrieb:>>>> mit einem 10bit ADC eingelesen.
Lothar M. schrieb:>> Es gibt ja auch noch double (64 Bit) und long double (80 Bit).> Klar. Aber das macht den 8-Bit-Andruiden nicht schneller
Und auch FPU der ARM Coretx-M Controller kann nur 32 Bit float.
Klaus H. schrieb:> Wie wäre es mit |Wert1 - Wert2| < epsilon?
Dazu müsstest du vorher immer erst epsilon anhand des absolut größeren
Wertes von Wert1 und Wert2 festlegen.
Stefan F. schrieb:> Inwiefern?
Könntest du die Frage noch etwas genauer stellen? Auf Stackoverflow gibt
es immerhin 10 Reputationpoints für eine gute Antwort auf eine ähnliche,
allerdings genauere Frage.
https://stackoverflow.com/questions/588004/is-floating-point-math-broken
So allgemein kann man nur sagen, dass Zahlen, wie z.B. 3,1415 für sich
gesehen erstmal nicht problematisch sind. Die Probleme kommen in der
Computeranwendung u.a. durch (statisches) Rundungsverhalten bei
(iterierenden) Funktionen oder beim Zahlen konvertieren oder rund um
Registerbitbreiten.
Beim Heron-Verfahren zum Wurzelziehen, da sind die Fließkommazahlen ganz
gut, denn das funktioniert über Annäherungen an die Genauigkeit.
Wenn es aber um hergeleitete Genauigkeit geht:
- die Fließkommazahlen gaukeln Genauigkeit vor, obwohl sie nur als
Annäherung zu verstehen sind und man aufpassen muss.
- die Probleme, die sie mitbringen sind mehrdimensional, und man kann
nicht alle Problemfälle überblicken -
- man muss aber die Schwierigkeiten verstehen z.B. für Testprogramme,
die dann wichtiger werden. Gibt man sich keine Mühe, kann es zum Unfall
kommen, und das ist sch..
Fuzzy Logic könnte man eventuell auf Fließkommazahlen anwenden. Das ist
aber wo implementiert?
Lothar M. schrieb:> Und sonst eben einen> Integer in "Dezigrad" oder "Centibar" oder "Millimeter", wenn ich wegen> einer höheren Auflösung Z0,1 Grad oder 0,01 bar oder 0,01 m auflösen> will.
me too und wenn ich größer oder gleich wissen will nehme ich strcmp will
ich Kommata einsetzen durch umrechnen mache ich das im String um aus 500
CentiVolt 5,00V zu machen.
Ich frage mich, wie viele sich die Mühe gemacht und wirklich einmal
überprüft haben wie lange einfache FP-Rechenoperationen dauern.
Ich hab's vor langer Zeit schon, deshalb benutze ich FP selbst auf
8-Bittern ziemlich oft.
WIMRE waren das nämlich so um die 300-500 CPU-Zyklen pro Operation bei
den kleinen AVRs.
Also 1/2ms bei einer CPU Geschwindigkeit von 1MHz.
Oder 1/32ms bei 16MHz.
Wenn man eine Berechnung nur ein paar zehn- oder hundertmal pro Sekunde
macht, interessiert das fast niemanden.(#)
Bei einer simplen Mul/Div Operation um ADC Werte umzurechnen, muss man
sich auch keine Gedanken um die Genauigkeit von float/double machen.
Oder um Error-Propagation, …
Wollt's nur mal erwähnen. ;-)
(#) Nitpicker mal ausgeschlossen.
Norbert schrieb:> Wenn man eine Berechnung nur ein paar zehn- oder hundertmal pro Sekunde> macht, interessiert das fast niemanden.
Außer, wenn man Strom sparen muss, z. B. bei Batteriebetrieb. Da ist es
schon ein Unterschied, ob der µP in den Tiefschlaf gehen kann oder in
der Zeit rechnen muss.
Rolf schrieb:> Außer, wenn man Strom sparen muss,
Sicherlich richtig.
Wenn man im Batteriebetrieb ist. Dann weiß man aber auch um diese
Dinge.
Nebenbei: Auch die FixPoint Arithmetik braucht ein Tütchen CPU-Zyklen.
Vor allem wenn man versucht eine halbwegs akzeptable Genauigkeit heraus
zu holen und mit 16, evtl. sogar 32 Bit rechnet.
Rolf schrieb:> Außer, wenn man Strom sparen muss
Oder wenn man z.B. solche Operationen auf ein größeres Array wiederholt
anwenden muss.
Norbert schrieb:> WIMRE waren das nämlich so um die 300-500 CPU-Zyklen pro Operation bei> den kleinen AVRs.> Also 1/2ms
Eine einzige Rechenoperation macht kein Programm. Der Witz ist, dass
jede einzelne derartige float-Rechnung eben 50 mal langsamer ist als
die integer-Rechnung, die das selbe Ergebnis bringt.
Und dann nennt der Programmierer den Controller "zu langsam", statt sein
Programm "ungeeignet geschrieben".
Wenn man ein klein wenig Gehirnschmalz in sein Programm steckt, dann
muss man oft überhaupt gar nicht umrechnen. Oder erst dann, wenn
irgendwer irgendwelche Werte auf einer Anzeige sehen will.
Lothar M. schrieb:> Der Witz ist, dass> jede einzelne derartige float-Rechnung eben 50 mal langsamer ist als> die integer-Rechnung
Nö Lothar, das ist kein Witz, das ist einfach so. Allerdings muss ich
zugeben, das die CPUs nun nicht mehr zu 90% herum-idlen, sondern nur
noch zu 89%.
Das ist zugegebenermaßen nur schwer zu ertragen, aber man muss auch mal
bereit sein ein Opfer zu bringen.
PS. Wenn ich auf anderen Systemen 500ksps per DMA vom ADC bekomme, diese
verarbeiten und weiterschieben muss, dann nehme ich auch FixPoint.
Dann, nur dann.
Lothar M. schrieb:> Eine einzige Rechenoperation macht kein Programm. Der Witz ist, dass> jede einzelne derartige float-Rechnung eben 50 mal langsamer ist als> die integer-Rechnung, die das selbe Ergebnis bringt.
Das halte ich für einen Irrtum. Miss mal nach, wenn mit 16 oder eher 32
Bit grerechnet wird! Ich würde vermuten, daß Float weniger als Faktor 5
langsamer ist.
Norbert schrieb:> Ich frage mich, wie viele sich die Mühe gemacht und wirklich einmal> überprüft haben wie lange einfache FP-Rechenoperationen dauern.
meist geht es nicht um die Dauer sondern das einem der RAM ausgeht weil
alles auf dem Stack passiert, das kann schöne versteckte Fehler ergeben.
Joachim B. schrieb:> meist geht es nicht um die Dauer sondern das einem der RAM ausgeht weil> alles auf dem Stack passiert, das kann schöne versteckte Fehler ergeben.
Und morgen geht die Welt unter! Nein! Der Norbert hat schon recht!
Joachim B. schrieb:> meist geht es nicht um die Dauer sondern das einem der RAM ausgeht weil> alles auf dem Stack passiert, das kann schöne versteckte Fehler ergeben.
Das tritt aber auch mit anderen Funktionalitäten auf und hat nichts
direkt mit Floatingpoint zu tun.
Ich empfehle bei Embedded Systemen immer Stacküberwachung einzubauen.
Die Diskussion scheint Richtung Glaubenskrieg zu gehen.
Ich nutze das was am besten passt. Und auch auf kleinen 8Bittern
funktioniert float gut.
Und manchmal braucht man auch Integer/Fixpoint Operationen auf
32Bittern.
Falk B. schrieb:> Und morgen geht die Welt unter! Nein! Der Norbert hat schon recht!
Nein, man redet hier ein Problem herbei, was man in einfachen
Anwendungen kaum hat.
Mit dem Rechnen ist das auch so eine Sache: 16 MHz sind 0,0625µs. Mal
500 komme ich auf 32 MIKROsekunden, nicht ms!
Mein 8MHz-Arduino liest vom angeschlossenen ADS1115 alle 10 Sekunden
zwei Spannungen und schreibt diese auf eine SD-Karte. Ich habe mich um
Variablentypen nicht geschert, da fliegen 4 Nachkommastellen herum. Das
läuft mit einer 18650-LiIon an die 500 Stunden, mit aktivem OLED
natürlich weniger.
Mein Spannungslogger kann auch jede Sekunde zur Karte schreiben, da bin
ich weder in Zeitnot noch stürzt irgendwas ab.
Zeitnot habe ich mal an anderer Stelle gefangen, wo die A/D des ATMega
benutzt werden und damit eine Regelung im Millisekunden-Bereich läuft.
Das war nicht die Float-Rechnerei, sondern zweistellige Millisekunden
für mein I2C-LCD.
Ich hätte gerne ein Problem passt hier wohl besser.
Ich hab mal gemessen. Einmal im Simulator im staubigen AVR-Studio mit
dem ollen 2010er avr gcc (der noch einen "Bug" hat und sich in einigen
Situationen viel RAM gönnt, so auch hier) und einmal mit Arduino UNO. Im
AVR-Studio mit Optimierung -Os (minimale Codegröße) compiliert. Beim
Arduino wurde die Zeit per Oszi gemessen. In beiden Fällen mit 16 MHz
CPU-Takt.
1
WinAVR-20100110
2
FLASH /B RAM /B Zeit /us
3
float 2860 264 197,0
4
int32 186 0 4,1
5
6
Arduino 1.8.13
7
FLASH /B RAM /B Zeit /us
8
float 1666 9 23,0
9
int32 920 9 4,2
Ziemliche Unterschiede! Aber bei ein paar handvoll oder auch hundert
Berechnungen/s kein wirkliches Problem. Bei größeren Arduinos mit 32 Bit
geht es noch schneller, wenn ne FPU vorhanden ist bedeutungslos.
Eine Sache die hier nicht berücksichtigt wird:
Bei Integer-Operationen kann es unüberlegt schnell zu Überläufen kommen.
So geschehen bei der Kalibration eines Sensors über eine
Polynom-Funktion.
Trotz Optimierungen konnte der Überlauf nur sehr aufwändig abgefangen
werden,
da sich die Faktoren in den Einzelgeräten stark unterschieden.
Mit float hatte sich das Problem erledigt.
Hallo,
wenn man über “ Differential ADC Channel“ messen würde und dir
Referenzspannung und Eingang mit einem Trimmer auf 4 V und 1V regeln
würde, würden 1V =0bar =0 und 10bar =4V =1023 bzw. 1000 ergeben können
(je nach Trimmung). Dadurch würden 1/5 der Werte nicht „verschenkt“
werden also 0-1V.
Gruß
Carsten
Carsten-Peter C. schrieb:> wenn man über “ Differential ADC Channel“ messen würde und
Du hast mitbekommen, dass Alexander K. ausgestiegen ist und hofft, nach
den Schulferien endlich Grundrechnen zu lernen?
Differential ist nett gedacht, aber er hat es ja nicht nötig, seinen ADC
zu benennen. 10-Bit lässt einen AVR vermuten, der das vermutlich nicht
kann.
Es fehlen auch Details zu den Drucksensoren. Dass die als Endwert 5 Volt
liefern, lässt vermuten, dass es deren Betriebsspannung sein könnte. Da
wäre eine ratiometrische Messung sinnvoll - also µC-Referenz und
Sensoren an der selben Versorgung.
Klaus H. schrieb:> Bei Integer-Operationen kann es unüberlegt schnell zu Überläufen kommen.
Richtig, "unüberlegt" und "Integer-Operation" passt nicht wirklich
zusammen, sobald Multiplikationen ins Spiel kommen.
Rainer W. schrieb:> "unüberlegt" und "Integer-Operation" passt nicht wirklich zusammen
Generell finde ich, dass "unüberlegt" und "programmieren" nicht
zusammenpassen.
Denn ich kann z.B.
1
inti=1000000000;
2
i+=1;
schreiben und bekomme 1000000001 heraus.
Wenn ich aber
1
floatf=1000000000.0;
2
f+=1.0;
schreibe, dann ist f nach dem ersten Befehl annähernd 1000000000. Und
nsch der Addition kommt unverändert annähernd 1000000000 heraus.
Lothar M. schrieb:> Generell finde ich, dass "unüberlegt" und "programmieren" nicht> zusammenpassen.
Mit immer leistungsfähigeren Prozessoren und immer unübersichtlicheren
Abstraktionsebenen/Bibliotheken fällt das leider immer häufiger
zusammen.
Die Beziehung zu dem, was der µC wirklich tut, gerät oft weit ins
Hintertreffen.
Rainer W. schrieb:>> Generell finde ich, dass "unüberlegt" und "programmieren" nicht>> zusammenpassen.>> Mit immer leistungsfähigeren Prozessoren und immer unübersichtlicheren> Abstraktionsebenen/Bibliotheken fällt das leider immer häufiger> zusammen.> Die Beziehung zu dem, was der µC wirklich tut, gerät oft weit ins> Hintertreffen.
Bist du des Mobys! ;-)
Stimmt aber leider. Sieht man auch fast jeden Tag, was da an
Softwareungetümen zusammengebacken wird, die immmer größer und träger
werden! Bloatware at it's best!
Falk B. schrieb:> Ich hab mal gemessen. Einmal im Simulator im staubigen AVR-Studio mit> dem ollen 2010er avr gcc (der noch einen "Bug" hat und sich in einigen> Situationen viel RAM gönnt, so auch hier) und einmal mit Arduino UNO.
Der Ramverbrauch its das eine, aber daß der (leicht staubige)
arduino-gcc (7.3.0) bei float einen fast um den Faktor 10 schnelleren
Code produzieren soll als der staubige 2010er (vermutlich ein 4.5), ist
dann doch nicht nachvollziehbar.
Oliver
Norbert schrieb:> yf /= 2.0;
Irgendwie eine sehr vorteilhafte Wahl, wenn der Rechner sowieso im
Binärsystem arbeitet und die Schleife genau rechtzeitig abgebrochen
eird.
Mit ein paar Iterationen mehr oder einer unbinären Zahl sieht man das
dann besser, dass dich der xf Wert nicht mehr ändert, obwohl yf nicht 0
ist.
1
#include<stdio.h>
2
intmain(void){
3
floatxf,yf;
4
5
xf=0.0,yf=1.0;
6
for(inti=0;i<30;i++){
7
xf+=yf;
8
printf("%3d %.25f %.025f\n",i,xf,yf);
9
yf/=2.0;
10
}
11
12
xf=0.0,yf=1.0;
13
for(inti=0;i<30;i++){
14
xf+=yf;
15
printf("%3d %.25f %.025f\n",i,xf,yf);
16
yf/=3.33;
17
}
18
19
return0;
20
}
Da sieht man dann, dass sich ab der der sechsten Nachkommastelle nichts
mehr tut:
Oliver S. schrieb:> ist dann doch nicht nachvollziehbar.
Wundert mich schon auch ein wenig. 10 Jahre Compilerentwicklung ergeben
10 fach schnelleren Code. Wenn man das mal extrapoliert...
Lothar M. schrieb:> Irgendwie eine sehr vorteilhafte Wahl, wenn der Rechner sowieso im> Binärsystem arbeitet
Das war ja der Plan. Man kann - so wie du - zeigen, das man sich
Probleme einfangen kann wenn man im Dezimalsystem über die Genauigkeit
einer float Variablen hinaus noch weiter arbeiten will.
Oder das man eine erstaunliche Genauigkeit erreicht, wenn man die
Mantisse im dualen System massiert.
Beides ist richtig, beides muss man wissen.
PS. Die Schleifen wurden nicht rechtzeitig abgebrochen, sondern erst
nachdem der erste Rechenfehler auftrat. So ehrlich bin ich dann doch…
;-)
Rainer W. schrieb:> Richtig, "unüberlegt" und "Integer-Operation" passt nicht wirklich> zusammen, sobald Multiplikationen ins Spiel kommen.
Da muss(te) wohl jeder mal durch, während der Rechenoperation einen
Überlauf, obwohl Eingabe und Ausgabe im zulässigen Bereich liegen.