Forum: Mikrocontroller und Digitale Elektronik ADC-Wert skalieren


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Z.B. Max Z. (oapc)


Lesenswert?

Hi,

ich habe ein eigentlich ganz einfaches Problem, stehe aber gerade massiv 
auf der Leitung.
Folgendes: ich lese Analogdaten von einem ADC ein. Auf Grund der 
externen Beschaltung nutzt der mögliche Eingangsspannungsbereich nicht 
den maximal möglichen ADC-Wertebereich aus. Also würde ich die real 
gemessenen Daten gerne auf den tatsächlichen Wertebereich skalieren.

Es sieht also so aus:

0V Eingangsspannung ergeben real einen Wert von 193

2,5V Eingangsspannung erbenen real einen Wert von 2221

5V Eingangsspannung ergeben real einen Wert von 4072

Das würde ich jetzt gerne so skalieren, dass der komplette bereich von 0 
(0V) bis 4095 (5V) genutzt wird.

Bisher war mein Ansatz, 193 vom DAC-Wert abzuziehen (Offset von 0V) und 
mit 1.051064 zu multiplizieren (Skalierungsfaktor, der sich aus 
4096/(4072-193) ergibt).

Allerdings funktioniert das nicht, da dieser Weg bei 2,5V 
Eingangsspannung nicht 2048 ergibt, sondern 2132. Wo ist mein 
Denkfehler? Wie berechne ich das richtig?

Danke!

: Verschoben durch Moderator
von Sebastian R. (sebastian_r569)


Angehängte Dateien:

Lesenswert?

Praktisch für soetwas ist die map()-Funktion von Arduino:
1
long map(long x, long in_min, long in_max, long out_min, long out_max)
2
{
3
  return (x - in_min) * (out_max - out_min) / (in_max - in_min) + out_min;
4
}
Quelle: https://www.arduino.cc/reference/de/language/functions/math/map/

Ergibt mit deinen Zahlenwerten 2132 als Ergebnis (2132.5, weil kein Long 
bei Excel)

von Yalu X. (yalu) (Moderator)


Lesenswert?

Die drei angegebenen Messpunkte liegen arg nichtlinear.

-> Messfehler oder Ablesefehler oder Fehler im Aufbau oder irgendein 
Bauteil defekt.

: Bearbeitet durch Moderator
von Stefan P. (form)


Lesenswert?

Z.B. Max Z. schrieb:
> Allerdings funktioniert das nicht, da dieser Weg bei 2,5V
> Eingangsspannung nicht 2048 ergibt, sondern 2132. Wo ist mein
> Denkfehler?

Dein ADC arbeitet nicht linear.
Vermutlich hast Du die Eingangsimpedanz des ADCs überschätzt.

von Sebastian R. (sebastian_r569)


Lesenswert?

Z.B. Max Z. schrieb:
> Allerdings funktioniert das nicht, da dieser Weg bei 2,5V
> Eingangsspannung nicht 2048 ergibt, sondern 2132. Wo ist mein
> Denkfehler?

Basierend auf der Annahme, der ADC ist linear genug und deine 
Eingangswerte stimmen, dann kommt man rechnerisch immer auf 2132 bei 
2.5V.

Deine Rechnung ist richtig und dein erwartetes Ergebnis ist falsch.

von Steve van de Grens (roehrmond)


Lesenswert?

Z.B. Max Z. schrieb:
> 0V Eingangsspannung ergeben real einen Wert von 193
> 2,5V Eingangsspannung ergeben real einen Wert von 2221
> 5V Eingangsspannung ergeben real einen Wert von 4072

Bei einer linearen Messung müsste 2,5V den Wert 1940 ergeben. Lass mich 
raten, geht es um einen ESP8266 oder ESP32?

von Klaus K. (Gast)


Lesenswert?

Nach Deinen Berichten ist der AD Aufbau und die Referenzmessung total 
vermurkst, dass kriegste auch nicht mehr per Software nutzbar zurecht 
skaliert.

Du hast einen 12 bit AD-Wandler, dann sollte die Messgenauigkeit der 
Referenzmessung auch in diesem Bereich liegen. Also brauchste nicht die 
Werte bei 0 2,5 und 5 sondern bei 0,000V 2,500 V und 5,000 V.  Bringt 
dein Referenzmessgerät überhaupt diese Anzeigegenauigkeit?

Und dann sollten beim 0.000V aka "Analogeingang mit GND verbunden" 
höchstens das einzeln niederwertigste Bit wackeln, bei dir sind es aber 
gleich die unteren 8 bit.
Das schaut dann schon mal nicht nach einem Offset-fehler sondern nach 
kompletten Murks aus. Das kann vom fehFer beim Auslesen des AD-Wandlers, 
falsche Decodierung und stark verrauschter Versorgungs- resp. 
Ref.-spannung alles sein.
Bring erst die Messungen bei 0.000V und Eingang gegen GND 
schaltungstechnisch sauber auf "000000000000" .

Wie stellst du eigentlich die 0V ein, etwa Analogeingang offen lassen ?

von Z.B. Max Z. (oapc)


Lesenswert?

OK, da hier mal wieder großkotzig von Murks die Rede ist: nein, es ist 
kein Murks.

Der tatsächliche Analogwert liegt weit außerhalb des 
Eingangsspannungsbereiches des ADC, weswegen das mit einem 
Spannungsteiler angepasst wurde.

Tatsächlich sind die Eingangsspannungswerte (Sollwerte):

- Minimum ca. 0,156V
- Mittelwert ca. 1,79V
- Maximum ca 3,28V

Warum nicht 0V und 3,3V? Um Bauteiltoleranzen im Spannungsteiler 
aufzufangen. Entsprechend ergibt sich der relativ hohe Offset beim 
Minimalwert. Das ist also kein Murks, sondern gewollt.

von Klaus K. (Gast)


Lesenswert?

Z.B. Max Z. schrieb:
> OK, da hier mal wieder großkotzig von Murks die Rede ist: nein, es ist
> kein Murks.

Naja Auskotzen kann man nur was man einem in den Mund gelegt wird.

Und in den seltesten Fällen ist der Autor geeignet die Qualität seines 
eigenen Werkes objektiv einzuschätzen. Das "sich selbst auf die Schulter 
klopfen" liegt in der Natur jedes Menschen.

> Der tatsächliche Analogwert liegt weit außerhalb des
> Eingangsspannungsbereiches des ADC, weswegen das mit einem
> Spannungsteiler angepasst wurde.

Ich nehme an, der Spannungsteiler ist aus gewöhnlichen Widerständen mit 
Toleranz 1% aufgebaut? Das kann man machen, bei einen AD-Wandler mit 12 
bit verschenkt man aber reichlich Genauigkeit. Widerstände verändern 
auch bei Erwärmung ihren Widerstandswert, ein Temp.-kompensierte 
Messverstärker resp. Abschwächer wäre hier besser für höchste 
Gebauigkeit.


> Tatsächlich sind die Eingangsspannungswerte (Sollwerte):
>
> - Minimum ca. 0,156V
> - Mittelwert ca. 1,79V
> - Maximum ca 3,28V
>
>  Das ist also kein Murks, sondern gewollt.

Gut gewollt heisst noch nicht gut gemacht.

von Z.B. Max Z. (oapc)


Lesenswert?

Klaus K. schrieb:

> Und in den seltesten Fällen ist der Autor geeignet die Qualität seines
> eigenen Werkes objektiv einzuschätzen.

Noch viel weniger ist jemand dazu geeignet, der nicht bekannte 
technische Details durch übergroßes Ego ersetzt. Also diese armen 
Würstchen, die nur in der Anonymität des Internet glauben, irgendwas zu 
sein oder zu können, dort um so aggressiver und großmäuliger auftreten 
und im wahren Leben absolut nichts auf die Reihe kriegen.

Ende der Diskussion mit dir, bye und ein schönes Leben noch!

von Yalu X. (yalu) (Moderator)


Lesenswert?

Z.B. Max Z. schrieb:
> Tatsächlich sind die Eingangsspannungswerte (Sollwerte):
>
> - Minimum ca. 0,156V
> - Mittelwert ca. 1,79V
> - Maximum ca 3,28V

Ja, dann sind die ADC-Werte plausibel.

Warum schreibst du das nicht gleich?

Z.B. Max Z. schrieb:
> Noch viel weniger ist jemand dazu geeignet, der nicht bekannte
> technische Details durch übergroßes Ego ersetzt.

Die meisten Leser hier gehen optimistischerweise davon aus, dass der
Threadstarter alle für seine Frage relevanten Details offenlegt und
diese auch korrekt sind. Ist dies nicht der Fall, muss er sich eben
kritische Bemerkungen gefallen lassen.

von Klaus K. (Gast)


Lesenswert?

Yalu X. schrieb:

> Die meisten Leser hier gehen optimistischerweise davon aus, dass der
> Threadstarter alle für seine Frage relevanten Details offenlegt und
> diese auch korrekt sind.

Und manche prüfen eben, ob die genannten Werte plausibel sind und das 
sind sie eben nicht. Also meckert man genau das an. Und gibt auch 
Hinweise für die Korrektur (Messschaltung, Genauigkeit Anzeige)


> Ist dies nicht der Fall, muss er sich eben
> kritische Bemerkungen gefallen lassen.

Und unmittelbar nach der kritischen Bewmerkung hat der Threadstarter
den Makel fehlender und grob ungenauer Angaben behoben. Also was gibts 
da zu meckern?

Weiterer Tipp: intern könnte man den eingehenden Messwert zuerst auf die 
Toleranzen der Messstrecke runterskallieren, also grob bei den 12 Bit 
Wandler und 1% Bauteiltoleranzen die unteren 4 bit "wegwerfen". Dann 
kann man die weitere Rechnung auf den Eingengsbereich mit einer kleinen 
LookUp-table erschlagen. Natürlich ist das dann nur ca. 0.05V (1% auf 
5V) genau. Mehr ist aber bei Spannungsteiler aus der Bastelkiste nicht 
drin.

von Z.B. Max Z. (oapc)


Lesenswert?

Yalu X. schrieb:

> Die meisten Leser hier gehen optimistischerweise davon aus, dass der
> Threadstarter alle für seine Frage relevanten Details offenlegt und
> diese auch korrekt sind.

OK, meine Frage war aber nicht "Ist meine Schaltung korrekt" oder 
"funktioniert mein ADC wie er soll", sondern wie berechne ich diese 
Werte korrekt.

Und es besteht auch ein großer Unterschied zwischen "kritischer 
Bemerkung" und unhöflichem, großkotzigen Rumpampen, bei dem man ganz 
deutlich merkt, dass es gar nicht darum geht, eine Antwort zu geben, 
sondern einfach mal darzustellen, wie toll man selber ist und wie dumm 
und Sch*** alle anderen sind. Das ist kein zivilisierter Umgangston, das 
ist einfach nur allerunterste Schiene. Und solche Leute und Ihre 
Pseudo-Antworten können mir persönlich komplett gestohlen bleiben.

von Bernd N. (_bn_)


Lesenswert?

Die Antwort hast du bereits bekommen. Siehe auch...
https://de.wikipedia.org/wiki/Lineare_Regression#:~:text=Die%20lineare%20Regression%20(kurz%3A%20LR,(kurz%3A%20LM)%20angenommen.

Sebastian R. schrieb:
> long map(long x, long in_min, long in_max, long out_min, long out_max)
> {
>   return (x - in_min) * (out_max - out_min) / (in_max - in_min) +
> out_min;
> }
> Quelle: https://www.arduino.cc/reference/de/language/functions/math/map/

Weiteres Beispiel:
Beitrag "ADC und Fixed-Point Arithmetik"

von Udo S. (urschmitt)


Lesenswert?

Z.B. Max Z. schrieb:
> und unhöflichem, großkotzigen Rumpampen

Das kannst du ja mindestens genauso gut wie man sieht.
Und deine Kompetenz kann man durchaus in Frage stellen wenn du hier 
falsche Werte angibst

Z.B. Max Z. schrieb:
> 0V Eingangsspannung ergeben real einen Wert von 193
>
> 2,5V Eingangsspannung erbenen real einen Wert von 2221
>
> 5V Eingangsspannung ergeben real einen Wert von 4072

Z.B. Max Z. schrieb:
> Tatsächlich sind die Eingangsspannungswerte (Sollwerte):
>
> - Minimum ca. 0,156V
> - Mittelwert ca. 1,79V
> - Maximum ca 3,28V

Auf was beziehen sich jetzt eigentlich deine ADC Werte? Das ist immer 
noch nicht klar.

Du schreibst von einem Spannungsteiler. Wie hochohmig ist der.
Auf die Frage von Stefan:

Stefan P. schrieb:
> Vermutlich hast Du die Eingangsimpedanz des ADCs überschätzt.

kam von dir nichts!

Ich kann hier kein besonders konstruktives Bemühen von Deiner Seite 
sehen DEIN Problem zu lösen. Aber ganz schnell Beleidigungen:

Z.B. Max Z. schrieb:
> da hier mal wieder großkotzig von Murks die Rede ist

Z.B. Max Z. schrieb:
> Noch viel weniger ist jemand dazu geeignet, der nicht bekannte
> technische Details durch übergroßes Ego ersetzt. Also diese armen
> Würstchen, die nur in der Anonymität des Internet glauben, irgendwas zu
> sein oder zu können, dort um so aggressiver und großmäuliger auftreten
> und im wahren Leben absolut nichts auf die Reihe kriegen.

Es zeigt sich ziemlich klar hier wieder dass der Spruch
"Wie man in den Wald hineinruft, so schallt es heraus"
zutrifft.

von Martin J. (martiko)


Lesenswert?

2.5 V ist der arithmetische Mittelwert von 0 V und 5 V, aber 2221 ist 
nicht der arithmetische Mittelwert von 193 und 4072, denn dieser ergibt 
sich zu (193 + 4072)/2 = 2132.5. Die Funktion A(U) mit A = ADC-Output 
und U = Eingangsspannung ist also nicht linear. Dafür muss es 
irgendeinen Grund geben, der sich aus Deiner Schaltung ergibt. Diesen 
Grund gilt es zu identifizieren und daraus die entsprechende Mathematik 
abzuleiten, um so zu wissen, welche Art von Nichtlinearität vorliegt. 
Mit dieser Information kannst Du dann darauf...

>sondern wie berechne ich diese Werte korrekt.

...die "richtige" Antwort finden.

von Andreas M. (amesser)


Lesenswert?

Z.B. Max Z. schrieb:
> Und es besteht auch ein großer Unterschied zwischen "kritischer
> Bemerkung" und unhöflichem, großkotzigen Rumpampen,

Unhöflich ist es falsche Angaben zu machen wenn man von anderen Hilfe 
will. Während 2,5V tatsächlich die Hälfte von 5.0V ist, ist (1.79-0.16)V 
weit weg von der Hälfte von (3.28-0.16)V.

von Mi N. (msx)


Lesenswert?

Bernd N. schrieb:
> Weiteres Beispiel:
> Beitrag "ADC und Fixed-Point Arithmetik"

Optimierungswahn? Zurück ins Mittelalter?
Wozu denn einem µC das Dezimalsystem aufzwingen?

Wenn der heutzutage verwendete µC noch keine 'float'-Berechnungen per 
Hardware hat, so ist er doch schnell genug, das per Software 
nachzubilden.

von Dirk F. (dirkf)


Lesenswert?

Mi N. schrieb:
> Wenn der heutzutage verwendete µC noch keine 'float'-Berechnungen

Float nur wenns unbedingt notwendig ist.

von Rainer W. (rawi)


Lesenswert?

Z.B. Max Z. schrieb:
> ich habe ein eigentlich ganz einfaches Problem,

Stimmt, Dreisatz ist Inhalt des Matheunterricht in der sechsten Klasse, 
Geradengleichung der achten Klasse.

> Auf Grund der externen Beschaltung nutzt der mögliche
> Eingangsspannungsbereich nicht den maximal möglichen ADC-Wertebereich
> aus. Also würde ich die real gemessenen Daten gerne auf den
> tatsächlichen Wertebereich skalieren.

Ja und?
Was soll die Rumrechnerei - außer zusätzlichem Rechenaufwand - bringen.
Die Daten werden dadurch nicht besser.

von Martin J. (martiko)


Lesenswert?

Außerdem wäre auch noch zu klären, was genau Du damit meinst:

>Das würde ich jetzt gerne so skalieren, dass der komplette bereich von 0
>(0V) bis 4095 (5V) genutzt wird.

Das finde ich nämlich alles andere als eindeutig. Heißt das, Du suchst 
eine Funktion f mit der Eigenschaft f(192) = 0 und f(2221) = 2048 und 
f(4072) = 4095? Wenn ja: Wozu? Was soll f können, was eine Funktion g 
mit der Eigenschaft g(192) = 0 und g(2221) = 2.5 und g(4072) = 5 nicht 
kann?

von Mi N. (msx)


Lesenswert?

Dirk F. schrieb:
> Float nur wenns unbedingt notwendig ist.

Dann hoffe ich mal, daß Dein Taschenrechner auf nur 'integer' 
einzustellen ist.
Kleine Notiz: 'float/double' und Divisionen nutze ich sogar in ISRs ;-)

Rainer W. schrieb:
> Was soll die Rumrechnerei - außer zusätzlichem Rechenaufwand - bringen.
> Die Daten werden dadurch nicht besser.

Aber die Skalierbarkeit zur Laufzeit. Offsets und Faktoren lassen sich 
anpassen und im EEPROM abspeichern. Aber wer es lieber mag, nimmt eben 
Trimmpotis.

von Sebastian W. (wangnick)


Lesenswert?

Anstelle der umstrittenen Bewertungsfunktion plädiere ich für einen 
intelligenten Filter, der emotional gefärbte Beiträge und grob 
beleidigendes Vokabular ausblendet oder erst gar nicht annimmt.

Wenn man schon beleidigen will, dann doch bitte elegant! Oder ist 
Deutsch derart hinterwäldlerisch?

LG, Sebastian

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Mi N. schrieb:
> Kleine Notiz: 'float/double' und Divisionen nutze ich sogar in ISRs ;-)

Recht so!

Ich glaube das war irgendwann zwischen 1880 und 1905, da hat mal jemand 
postuliert das float Operation schlimmster Teufelskram sind.
Weiter darüber nachgedacht haben danach nur sehr wenige und so werden 
den Kindern am Kaminfeuer noch heute die alten Geschichten erzählt.
Ungeachtet der Tatsache das diese Operationen eher im µs denn im ms 
Bereich angesiedelt sind.

von Benjamin K. (bentschie)


Lesenswert?

Norbert schrieb:

> Ich glaube das war irgendwann zwischen 1880 und 1905, da hat mal jemand
> postuliert das float Operation schlimmster Teufelskram sind.

Hmm, manchmal schon. Ist mir erst heute passiert zwar nicht im µC 
sondern im Excel. Kann einem aber so ähnlich auch im µC auf die Füße 
fallen.
156,22€ Einnahmen, 156,22€ Aussgaben, Differenz ist ungleich Null!?
Hatte extra eine Formel genutzt um auf Nulldiffernz zu prüfen.
Hhmm, Excel Doof?, Ich doof?
Bei 156,20€ statt 156,22 gehts aber? Was ist hier los?

Ein Vergleich von Floats kann auch schief gehen, wenn die Differnz sehr 
sehr klein ist. Hätte nicht gedacht das beim addieren von vielleicht 5 
Beträgen bereits Rundungsfehler im Float auftreten. Ist aber so.

von Dirk F. (dirkf)


Lesenswert?

Norbert schrieb:
> Ungeachtet der Tatsache das diese Operationen eher im µs denn im ms
> Bereich angesiedelt sind

Oh, jetzt bin ich aber überrascht.

Meine maximale Zykluszeit ohne die Double Berechnung:  80 us
Mit 1000 Berechnung Double:  161 us
1
    double a;
2
    volatile double b;
3
    int i;
4
    a = 2.234;
5
    b = 0.0;
6
    for (i=0;i<1000;i++)
7
        {
8
        b = a * a ;
9
        debug[6] = b;
10
        }

Also 80 ns / Double Float Berechnung.

PIC32MZ @ 200 MHz mit FPU.

von Udo S. (urschmitt)


Lesenswert?

Dirk F. schrieb:
> PIC32MZ @ 200 MHz mit FPU.

Und was kostet es auf einer 8 Bit CPU ohne FPU?

Aber inzwischen braucht man wohl schon einen 200MHz Boliden mit 512K Ram 
um in einem Wasserkocher die Temperatur zu messen

ECNR

von Mi N. (msx)


Lesenswert?

Norbert schrieb:
> Ich glaube das war irgendwann zwischen 1880 und 1905

Gestern hier im Forum veröffentlicht:
OCR0A = (262L * delta) >> 9;

Was immer der Autor damit gemeint hat: Es ist wohl eine Art Religion, 
die nur Angehörige der Sekte als heilsbringend betrachten.

Dirk F. schrieb:
> Also 80 ns / Double Float Berechnung.

Das will ich jetzt nicht ausprobieren, aber 'mein' Compiler schmeißt den 
Müll vielleicht komplett weg.

von Rainer W. (rawi)


Lesenswert?

Benjamin K. schrieb:
> Hätte nicht gedacht das beim addieren von vielleicht 5 Beträgen bereits
> Rundungsfehler im Float auftreten. Ist aber so.

Die Rundungsfehler entstehen schon, wenn deine reellen Zahlen aus dem 
Dezimalsystem in Float (aka. Fixkommazahlen mit variabler Kommaposition 
im Binärformat) gewandelt werden.

von Rainer W. (rawi)


Lesenswert?

Dirk F. schrieb:
> Meine maximale Zykluszeit ohne die Double Berechnung:  80 us
> Mit 1000 Berechnung Double:  161 us

Wenn dein Compiler über ein Minimum an Optimierung verfügt, hat er 
erkannt, dass a und b durch die Schleife nicht beeinflusst werden und 
hat die Operation aus der Schleife heraus genommen.
Um wirklich zu wissen, was er rechnet, guckst du besser in den erzeugten 
Assemblercode.

von Norbert (der_norbert)


Lesenswert?

Benjamin K. schrieb:
> 156,22€ Einnahmen, 156,22€ Aussgaben, Differenz ist ungleich Null!?

Man vergleicht Fließkommazahlen niemals auf Gleichheit. <-PUNKT
(Außer man weiß zu 100% das der Nachkommaanteil aus 1/2^n Komponenten 
zusammen setzbar ist.)
Wobei N besser nicht die gewählte Präzision (Mantisse) sprengt.
Alle anderen vergleichen auf Ähnlichkeit innerhalb einer gegebenen 
Varianz.

von Norbert (der_norbert)


Lesenswert?

Dirk F. schrieb:
> Oh, jetzt bin ich aber überrascht.
>
> Meine maximale Zykluszeit ohne die Double Berechnung:

Hab's früher™ mal mit einem Kinder-AVR™ ausgiebig getestet und meine 
mich zu erinnern das man dort mit maximal ~ 500CPU-Zyklen (zumeist 
deutlich weniger) rechnen musste.
Das kann man dann geschmeidig für die jeweilige CPU-Taktfrequenz 
umrechnen und stellt fest das selbst Kinder-AVRs™ Hunderte bis Tausende 
FLOPS können.

von Norbert (der_norbert)


Lesenswert?

Udo S. schrieb:
> Und was kostet es auf einer 8 Bit CPU ohne FPU?

Sehr wenig!

von Norbert (der_norbert)


Lesenswert?

Hab' gerade mal in den antiken Archiven nachgesehen.
(Nur falls es irgend jemanden interessieren sollte…)

Jeweils 10.000 Messungen mit einem mega128, Ergebnisse aufgeteilt in die 
jeweiligen, sich ergebenden Zeitscheiben bei 16MHz:
1
---[ I  => F ]---
2
         2 µs       5027
3
         3 µs       4433
4
         4 µs        470
5
         5 µs         70
6
7
---[ UI => F ]---
8
         2 µs       5042
9
         3 µs       4401
10
         4 µs        465
11
         5 µs         92
12
13
---[ F  => I ]---
14
         3 µs       5030
15
         4 µs       4024
16
         5 µs        741
17
         6 µs        205
18
19
---[ F  => UI ]---
20
         2 µs       5013
21
         3 µs       3139
22
         4 µs       1420
23
         5 µs        405
24
         6 µs         23
25
26
---[ Add f1+f2 ]---
27
         5 µs       5378
28
         6 µs       1727
29
         7 µs       2026
30
         8 µs        641
31
         9 µs        182
32
        10 µs         24
33
        11 µs         14
34
        12 µs          8
35
36
---[ Sub f1-f2 ]---
37
         5 µs       5251
38
         6 µs       1758
39
         7 µs       2132
40
         8 µs        645
41
         9 µs        166
42
        10 µs         30
43
        11 µs         12
44
        12 µs          5
45
        14 µs          1
46
47
---[ Mul f1*f2 ]---
48
         6 µs          1
49
         8 µs       7900
50
         9 µs       2099
51
52
---[ Div f1/f2 ]---
53
         6 µs          1
54
        28 µs        298
55
        29 µs       5044
56
        30 µs       4452
57
        31 µs        205
58
59
---[ sinf(f1) ]---
60
        64 µs          1
61
        84 µs       1240
62
        88 µs       3754
63
        92 µs          1
64
       104 µs          6
65
       108 µs         58
66
       112 µs        642
67
       116 µs       1833
68
       120 µs       1470
69
       124 µs        863
70
       128 µs        128
71
       132 µs          4
72
73
---[ cosf(f1) ]---
74
        68 µs          2
75
       104 µs          4
76
       108 µs       1056
77
       112 µs       4814
78
       116 µs       1731
79
       120 µs       1431
80
       124 µs        860
81
       128 µs         87
82
       132 µs         11
83
       136 µs          4
84
85
---[ tanf(f1) ]---
86
        80 µs          1
87
        96 µs        910
88
       100 µs       3833
89
       104 µs        282
90
       108 µs          1
91
       112 µs          1
92
       116 µs          8
93
       120 µs        160
94
       124 µs        389
95
       128 µs        638
96
       132 µs        667
97
       136 µs        442
98
       140 µs        157
99
       144 µs         32
100
       148 µs         80
101
       152 µs        350
102
       156 µs        507
103
       160 µs        721
104
       164 µs        500
105
       168 µs        249
106
       172 µs         53
107
       176 µs         18
108
       180 µs          1
109
110
---[ asinf(f1) ]---
111
        64 µs        553
112
        68 µs       1691
113
        72 µs        210
114
        76 µs          1
115
       152 µs       3258
116
       156 µs       3363
117
       160 µs        924
118
119
---[ acosf(f1) ]---
120
       144 µs        672
121
       148 µs       1835
122
       152 µs       3601
123
       156 µs       2499
124
       160 µs        919
125
       164 µs        382
126
       168 µs         91
127
       172 µs          1
128
129
---[ atanf(f1) ]---
130
        96 µs          1
131
       116 µs         65
132
       120 µs       2235
133
       124 µs       2625
134
       128 µs          2
135
       132 µs          1
136
       160 µs          1
137
       172 µs          1
138
       176 µs          5
139
       180 µs         13
140
       184 µs         82
141
       188 µs        211
142
       192 µs        418
143
       196 µs        549
144
       200 µs        562
145
       204 µs       1775
146
       208 µs       1447
147
       212 µs          7
148
149
---[ logf(f1) ]---
150
         0 µs       5036
151
       136 µs        521
152
       140 µs       1894
153
       144 µs        751
154
       148 µs        898
155
       152 µs        554
156
       156 µs        279
157
       160 µs         61
158
       164 µs          2
159
       168 µs          3
160
       172 µs          1
161
162
---[ log10f(f1) ]---
163
         4 µs       5051
164
       144 µs        353
165
       148 µs       1961
166
       152 µs        747
167
       156 µs        905
168
       160 µs        610
169
       164 µs        291
170
       168 µs         72
171
       172 µs          7
172
       176 µs          2
173
       180 µs          1
174
175
---[ powf(f1,f2) ]---
176
         0 µs       2175
177
         4 µs        633
178
        16 µs          2
179
       148 µs        146
180
       152 µs       1280
181
       156 µs       1091
182
       160 µs        846
183
       164 µs        717
184
       168 µs        432
185
       172 µs        155
186
       176 µs         29
187
       180 µs          4
188
       272 µs          2
189
       276 µs         48
190
       280 µs        169
191
       284 µs        271
192
       288 µs        274
193
       292 µs        229
194
       296 µs        170
195
       300 µs         87
196
       304 µs        103
197
       308 µs        196
198
       312 µs        281
199
       316 µs        260
200
       320 µs        179
201
       324 µs        127
202
       328 µs         60
203
       332 µs         27
204
       336 µs          6
205
       340 µs          1
206
207
---[ sqrtf(f1) ]---
208
         2 µs       5003
209
         3 µs          1
210
        29 µs        632
211
        30 µs       3471
212
        31 µs        878
213
        32 µs         15

von Falk B. (falk)


Lesenswert?

Mi N. schrieb:
> Norbert schrieb:
>> Ich glaube das war irgendwann zwischen 1880 und 1905
>
> Gestern hier im Forum veröffentlicht:
> OCR0A = (262L * delta) >> 9;
>
> Was immer der Autor damit gemeint hat: Es ist wohl eine Art Religion,
> die nur Angehörige der Sekte als heilsbringend betrachten.

Tja, wenn man nichts kapiert, muss es dumm sein, gelle.
Wenn man aber zu doof oder zu faul zum Lesen des Kommentars ist, ist 
Hopfen und Malz verloren. Andere Leute haben Festkommaarithmetik 
verstanden und wenden sie erfolgreich an. Du gehörst nicht dazu.

Beitrag "Re: PWM Signal ( 5V, Pulslänge 1-2ms) für Servomotor in 0-10v umsetzen"
1
       // scale 1ms = 500 counts = 100%
2
        // OCR0A = 256 * delta / 500 = (262 * delta ) / 512 = (262 * delta ) >> 9
3
        OCR0A = (262L * delta) >> 9;

von Norbert (der_norbert)


Lesenswert?

Falk B. schrieb:
> Tja, wenn man nichts kapiert, muss es dumm sein, gelle.

Falk, du hast schon in der Vergangenheit in hinreichendem Maße bewiesen, 
das du eine besondere Befähigung hast blöde Kommentare abzugeben. Du 
musst es nicht ständig aufs Neue beweisen.

Es gibt nur selten einen wirklich guten Grund sich mit 
Festkommaarithmetik herum zu schlagen. Ja, es gibt sie manchmal. 
MANCHMAL.

Zumeist sind die Kommentare eine blinde Trotzreaktion ohne die echten 
Fakten zu kennen.

von Falk B. (falk)


Lesenswert?

Norbert schrieb:
> Falk B. schrieb:
>> Tja, wenn man nichts kapiert, muss es dumm sein, gelle.
>
> Falk, du hast schon in der Vergangenheit in hinreichendem Maße bewiesen,
> das du eine besondere Befähigung hast blöde Kommentare abzugeben. Du
> musst es nicht ständig aufs Neue beweisen.

Wie man in den Wald hinein ruft, so schallt es heraus. Und in besonderen 
Wäldern noch viel lauter!

> Es gibt nur selten einen wirklich guten Grund sich mit
> Festkommaarithmetik herum zu schlagen. Ja, es gibt sie manchmal.
> MANCHMAL.

Ich behaupte das Gegenteil! Die meisten Anwendungen kommen problemlos 
damit aus. Eben WEIL der Dynamikbereich von Festkomma NICHT gebraucht 
wird! Solche ADC und andere Sensorgeschichten sind sowas!

> Zumeist sind die Kommentare eine blinde Trotzreaktion ohne die echten
> Fakten zu kennen.

von Mi N. (msx)


Lesenswert?

Falk B. schrieb:
> Andere Leute haben Festkommaarithmetik
> verstanden und wenden sie erfolgreich an. Du gehörst nicht dazu.

Und das ist gut so! Ich schreibe es so:
1
  pw = pw * (PWM_MAX) / (PW_IN_MAX-PW_IN_MIN);  // skalieren
2
  dac_ausgabe(pw);

und mache dabei nicht den Fehler, direkt ins OCRxx-Register zu 
schreiben, sondern die Ausgabe zu invertieren. Bei '0' soll ja auch '0' 
am Ausgang erscheinen ;-)

von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> ---[ I  => F ]---
>          2 µs       5027
>    ...

"Wichtige Regeln - erst lesen, dann posten!"

Was für längeren Quellcode gilt, darfst du auch gerne auf längere 
Zahlenkolonnen übertragen - einfach ein ganz klein wenig Selbständigkeit 
zeigen ...

von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> "Wichtige Regeln - erst lesen, dann posten!"

Wolltest du einfach nur etwas schreiben oder einen wichtigen Beitrag 
leisten und es ist dir nicht gelungen?

von Norbert (der_norbert)


Lesenswert?

Falk B. schrieb:
> Ich behaupte das Gegenteil! Die meisten Anwendungen kommen problemlos
> damit aus.

Ja selbstverständlich Falk.

 Es ist unbedingt darauf zu achten das vom verfügbaren Flashspeicher 
nach Fertigstellung des Programms noch 95% frei bleiben.
Ebenso muss sichergestellt werden, das die CPU mindestens zu 95% im Idle 
herum eiert. Weil man nur dann ein echt sparsamer Profi ist.

von Falk B. (falk)


Lesenswert?

Norbert schrieb:
>> Ich behaupte das Gegenteil! Die meisten Anwendungen kommen problemlos
>> damit aus.
>
> Ja selbstverständlich Falk.

Na immerhin.

>  Es ist unbedingt darauf zu achten das vom verfügbaren Flashspeicher
> nach Fertigstellung des Programms noch 95% frei bleiben.
> Ebenso muss sichergestellt werden, das die CPU mindestens zu 95% im Idle
> herum eiert. Weil man nur dann ein echt sparsamer Profi ist.

Die meisten "Profis" sind faul und verschwenderisch und das was sie am 
besten können ist Jammern über fehlende Resourcen, sei es Speicher oder 
CPU-Leistung.

von Jens G. (jensig)


Lesenswert?

Benjamin K. schrieb:
> 156,22€ Einnahmen, 156,22€ Aussgaben, Differenz ist ungleich Null!?

Kann aber nur passieren, wenn einer von beiden oder beide berechnete 
Werte sind. Also nur äuserlich gleich aussehen, aber in 
FP-Representation doch leicht unterschiedlich sind.

von M. K. (sylaina)


Lesenswert?

Benjamin K. schrieb:
> Ein Vergleich von Floats kann auch schief gehen, wenn die Differnz sehr
> sehr klein ist.

Deshalb prüft man Floats(Doubles) nicht auf Gleichheit ;)

von Peter D. (peda)


Lesenswert?

Z.B. Max Z. schrieb:
> Allerdings funktioniert das nicht, da dieser Weg bei 2,5V
> Eingangsspannung nicht 2048 ergibt, sondern 2132. Wo ist mein
> Denkfehler? Wie berechne ich das richtig?

Wie schon mehrfach bis zu Erbrechen klargestellt wurde, Deine Werte 
bilden eine nichtlineare Funktion, d.h. die Geradengleichung kann darauf 
nicht angewendet werden.
Du solltest also erstmal die Fehlerquelle ermitteln.

Ein gerne gemachter Fehler ist, daß R2R-OPVs eben nicht R2R sind, 
sondern auch einen Totbereich haben. Nur ist der kleiner, als bei 
herkömmlichen OPVs (etwa 50mV >GND bzw. <VCC).
Messungen nahe 0V sind daher stark fehlerbehaftet. Ich speise daher 
einen kleinen Offsetstrom in den Eingang mit ein.

von Joachim B. (jar)


Lesenswert?

Peter D. schrieb:
> Wie schon mehrfach bis zu Erbrechen klargestellt wurde, Deine Werte
> bilden eine nichtlineare Funktion, d.h. die Geradengleichung kann darauf
> nicht angewendet werden.

mit Offsetbetrachtung (b) aber meist ausreichend genau.

Die Geradengleichung heisst ja nicht umsonst y = m * x + b

Also dy/dx für m und dann b ermitteln

Norbert schrieb:
> Hab' gerade mal in den antiken Archiven nachgesehen.
> (Nur falls es irgend jemanden interessieren sollte…)

was hast du an:
"Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang"

nicht verstanden?

: Bearbeitet durch User
von Andreas M. (amesser)


Lesenswert?

Peter D. schrieb:
> Du solltest also erstmal die Fehlerquelle ermitteln.

Seine Fehlerquelle ist, das er nicht rechnen kann. Die Werte aus dem 
Eröffnungsbetrag waren Fantasiezahlen. Etwas Später:

Z.B. Max Z. schrieb:
> - Minimum ca. 0,156V
> - Mittelwert ca. 1,79V
> - Maximum ca 3,28V

Der sogenannte Mittelwert seine Spnnungen liegt gar nicht in der Mitte:
(3,28+0,156) / 2 ~ 1.72.

von Klaus K. (Gast)


Lesenswert?

> Wie schon mehrfach bis zu Erbrechen klargestellt wurde, Deine Werte
> bilden eine nichtlineare Funktion, d.h. die Geradengleichung kann darauf
> nicht angewendet werden.
> Du solltest also erstmal die Fehlerquelle ermitteln.

Das hat er, der TO hat (auf drängende Nachfrage) auch drei (tatsächlich 
ermittelte) Paare Analog|Digital genannt, die auf einer Geraden liegen: 
Beitrag "Re: ADC-Wert skalieren"

* #1  0,156 ->  193
* #2  1,79  -> 2221 (denn nent der TO aber Mittelwert statt Mittenwert)
* #3  3,28  -> 4072

Und das will der TO durch etwas was er "Skalierung" nennt, dahingehend 
verbogen haben, das es "erscheint" wie:

* #1*  0,00  ->    0
* #2*  2,50  -> 2048
* #3*  5,00  -> 4095

Mit dem Vorschlag, das (wie beliebig andere Zuordnungen eingelesener 
Wert -> verarbeiteter Wert) über eine LookUp-Table zu realisieren weiß 
der TO wohl nichts anzufangen. Nicht bekannt ist, wie mit Werten kleiner 
0.156 und größer 3,28 zu verfahren ist.

von Dirk F. (dirkf)


Lesenswert?

M. K. schrieb:
> Deshalb prüft man Floats(Doubles) nicht auf Gleichheit ;)

Frage:  Ist das zulässig ?
1
if (x > 0.0  && x <=1.0)     Funktion1();
2
if (x > 1.0  && x <=2.0)     Funktion2();
3
if (x > 2.0  && x <=3.0)     Funktion3();

Ist dann sichergestellt, dass immer (nur) eine Funktion ausgeführt wird, 
wenn x Werte von 0.0   bis 3.0  annimmt ?

von Kilo S. (kilo_s)


Lesenswert?

Dirk F. schrieb:
> Ist dann sichergestellt, dass immer (nur) eine Funktion ausgeführt wird,

Sollte, wenn einer der operanden 0 ist, ist das Ergebnis 0.

Ist der erste 0, wird der zweite nicht ausgewertet.

von Rolf (rolf22)


Lesenswert?

Norbert schrieb:
> Man vergleicht Fließkommazahlen niemals auf Gleichheit. <-PUNKT

Und auch nicht auf ">", "<", ">=" oder "<=", wenn man nicht genau weiß, 
dass der eventuell dabei entstehende Fehler keine Rolle spielt.

von Steve van de Grens (roehrmond)


Lesenswert?

Dirk F. schrieb:
> Ist dann sichergestellt, dass immer (nur) eine Funktion ausgeführt wird

Ich denke ja, weil ">" das Gegenteil von "<=" ist. Ganz unabhängig 
davon, wie exakt die hart codierten Zahlenwerte als Float/Double 
darstellbar sind.

: Bearbeitet durch User
von Peter D. (peda)


Lesenswert?

Rolf schrieb:
> Norbert schrieb:
>> Man vergleicht Fließkommazahlen niemals auf Gleichheit. <-PUNKT
1
range_t check_in_range_f(float val, float min, float max)
2
{
3
  if (val < min)
4
    return UNDERRANGE;
5
  if (val > max)
6
    return OVERRANGE;
7
  return INRANGE;
8
}
9
10
float set_in_range_f(float val, float min, float max)
11
{
12
  switch (check_in_range_f(val, min, max))
13
  {
14
    case OVERRANGE:
15
      return max;
16
    case UNDERRANGE:
17
      return min;
18
    default:
19
      return val;
20
  }
21
}

von Norbert (der_norbert)


Lesenswert?

Steve van de Grens schrieb:
> Ich denke ja, weil ">" das Gegenteil von "<=" ist. Ganz unabhängig
> davon, wie exakt die hart codierten Zahlenwerte als Float/Double
> darstellbar sind.

Wobei man gerade bei gemischten Operationen float/double auch aufpassen 
muss.
So sind bei float x1 = sqrt(2) und double x2 = sqrt(2) die beiden 
resultierenden Werte NICHT gleich.
Obwohl sie bei einem einfachen printf (ohne Präzisionseinstellungen) als 
gleich dargestellt werden.

von Rainer W. (rawi)


Lesenswert?

Benjamin K. schrieb:
> Ein Vergleich von Floats kann auch schief gehen, wenn die Differnz sehr
> sehr klein ist.

"Sehr, sehr klein" schlägt bereits beim Kontoauszug der Bank zu, wenn 
man versucht, den mit 32-Bit Float aufzuaddieren, jedenfalls wenn der 
Kontostand nicht sehr, sehr klein ist.
Da hat man gerade einmal 23 Bit zur Verfügung.

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Mi N. schrieb:

> Gestern hier im Forum veröffentlicht:
> OCR0A = (262L * delta) >> 9;
>
> Was immer der Autor damit gemeint hat

Das ist doch so offensichtlich, dass man das sogar stinkbesoffen sofort 
lesen kann.

Da steht ganz klar:

OCR0A = 0.51171875 * delta;

Bloß eben so ausgedrückt, dass der strunzdoofe Compiler daraus für die 
behinderte CPU ein sehr viel schnelleres und sehr viel kleineres Stück 
Code produzieren kann.

Im Übrigen könnte man dieselbe Optimierung auch so erreichen, dass sogar 
der Faktor direkt im Quelltext lesbar ist und auch, was die Sache macht:

#define SCALE_BY(fac,val) (((uint32_t)(512.0 * (fac)) * (val)) / 512)

OCR0A = SCALE_BY(0.51171875, delta);

Da sollte bei einem modernen Compiler zumindest in etwa dasselbe 
rauskommen, wie bei der Originalschreibweise. Also etwas, was sehr viel 
schneller und sehr viel kleiner ist als das Machwerk mit float auf 
demselben Target, die eben keine FPU hat.

von Wendels B. (wendelsberg)


Lesenswert?

Z.B. Max Z. schrieb:
> Der tatsächliche Analogwert liegt weit außerhalb des
> Eingangsspannungsbereiches des ADC, weswegen das mit einem
> Spannungsteiler angepasst wurde.

Aus welchen Werten ist der Spannungsteiler zusammengesetzt und in 
welchem Prozessor ist der ADC?

von Klaus K. (Gast)


Lesenswert?

> OK, meine Frage war aber nicht "Ist meine Schaltung korrekt" oder
> "funktioniert mein ADC wie er soll", sondern wie berechne ich diese
> Werte korrekt.
>
> Und es besteht auch ein großer Unterschied zwischen "kritischer
> Bemerkung" und unhöflichem, großkotzigen Rumpampen,

Jajaja, ich bereue zutiefst, das ich versucht habe einen Sinn in Deinen 
fehlerhaften Angaben zu finden und dir mögliche Fehlerquellen genannt zu 
haben. Es kann nach dem GIGO-Prinzip eben keine korrekte Berechnung  aus 
frei erfundenen Zahlen geben. 
https://de.wikipedia.org/wiki/Garbage_In,_Garbage_Out

> Aus welchen Werten ist der Spannungsteiler zusammengesetzt

Wahrscheinlich wie dort vorgekaut: 
Beitrag "+-5V Analogsignal auf 0-3.3V für ADC?"

>und in welchem Prozessor ist der ADC?
Wahrscheinlich in dem selben wie dort: 
Beitrag "STM32F4 - Audioausgabe realisieren?"
 STM32F4 - selbst der kleinste hat genug Speicher für mehrere LUT's

von Wendels B. (wendelsberg)


Lesenswert?

Klaus K. schrieb:
> Wahrscheinlich

Fakten bitte.

Klaus K. schrieb:
> Wahrscheinlich in dem selben

Fakten bitte.

von Klaus K. (Gast)


Lesenswert?

Wendels B. schrieb:
> Klaus K. schrieb:
>> Wahrscheinlich
>
> Fakten bitte.
>
> Klaus K. schrieb:
>> Wahrscheinlich in dem selben
>
> Fakten bitte.

Die Fakten ergeben sich aus dem Vergleich der account-namen und dem 
vertrauen das hinter den jeweiligen accounts die selbe person steckt.
Und dem kompletten Ignorieren des Bewertungssystems hier, in dem die 
inhaltsbesten beiträge gern mit der negativsten bewertung abgestraft 
werden. Halt wie bei den drei Affen "Nichts hören, nichts sehen, nichts 
..." https://de.wikipedia.org/wiki/Drei_Affen

von Max M. (Gast)


Lesenswert?

Echt?!?
Ich hätte gedacht, damit ist gemeint, wie ich es lese.
Hat >> 9 eine höhere Wertung, also wird VOR der Klammer ausgewertet?!?
Ist das wieder so ein C Ding oder ist das überall so?
Oder wie ist das zu verstehen?
262L bedeutet doch 262 als Long Wert?


Ob S. schrieb:
Mi N. schrieb:

> Gestern hier im Forum veröffentlicht:
> OCR0A = (262L * delta) >> 9;
>
> Was immer der Autor damit gemeint hat

Das ist doch so offensichtlich, dass man das sogar stinkbesoffen sofort
lesen kann.

Da steht ganz klar:

OCR0A = 0.51171875 * delta;

von Steve van de Grens (roehrmond)


Lesenswert?

>> OCR0A = (262L * delta) >> 9;
>> Was immer der Autor damit gemeint hat

Max M. schrieb:
> Das ist doch so offensichtlich, dass man das sogar stinkbesoffen
> sofort lesen kann.

Finde ich nicht. Ein Kommentar dahinter wäre hilfreich. Die Methode an 
sich ist mir allerdings geläufig.

von Steve van de Grens (roehrmond)


Lesenswert?

>> OCR0A = (262L * delta) >> 9;

Max M. schrieb:
> Hat >> 9 eine höhere Wertung, also wird VOR der Klammer ausgewertet?!?
> Ist das wieder so ein C Ding oder ist das überall so?
> Oder wie ist das zu verstehen?

Nein, keine Sorge. Die Klammern funktionieren in C so, wie man es nach 
dem Mathe Unterricht in der Schule erwartet.

> 262L bedeutet doch 262 als Long Wert?

Ja

Das macht er, damit die Multiplikation von 262·delta keinen Überlauf 
ergibt.

Ohne das "L" wären beide Operanden der Multiplikation 16 Bit Integer, 
deswegen würde der Compiler Code generieren, der als Ergebnis 16 Bit 
Integer produziert. Bei einem delta > 125 würde das nicht ausreichen.

: Bearbeitet durch User
von Klaus K. (Gast)


Lesenswert?

Steve van de Grens schrieb:
>>> OCR0A = (262L * delta) >> 9;
>
> Max M. schrieb:
>> Hat >> 9 eine höhere Wertung, also wird VOR der Klammer ausgewertet?!?
>> Ist das wieder so ein C Ding oder ist das überall so?
>> Oder wie ist das zu verstehen?
>
> Nein, keine Sorge. Die Klammern funktionieren in C so, wie man es nach
> dem Mathe Unterricht in der Schule erwartet.

Auch bei der Code Optimierung?

Da ja zwei der drei Faktoren Konstanten sind, wäre es schon Sinnvoll 
beim Kompilieren den Faktor 1/512 (aka ">> 9") in die Klammer zu ziehen, 
statt während der Laufzeit immer das Gleiche zu prozessiren.

von Steve van de Grens (roehrmond)


Lesenswert?

Klaus K. schrieb:
> Auch bei der Code Optimierung?

Selbstverständlich, sonst wäre ein eine Code-Zerstörung.#

> Da ja zwei der drei Faktoren Konstanten sind, wäre es schon Sinnvoll
> beim Kompilieren den Faktor 1/512 (aka ">> 9") in die Klammer zu ziehen

Wäre es nicht, weil 1/512 = 0 ist und dann das Ergebnis auch 0 wäre.

: Bearbeitet durch User
von Klaus K. (Gast)


Lesenswert?

Steve van de Grens schrieb:
> Klaus K. schrieb:
>> Auch bei der Code Optimierung?
>
> Selbstverständlich, sonst wäre ein eine Code-Zerstörung.#

Gerade diese "Code-Zerstörung" resp. -aufweichung ist ja der Zweck einer 
Optimierung.

>> Da ja zwei der drei Faktoren Konstanten sind, wäre es schon Sinnvoll
>> beim Kompilieren den Faktor 1/512 (aka ">> 9") in die Klammer zu ziehen
>
> Wäre es nicht, weil 1/512 = 0 ist und dann das Ergebnis auch 0 wäre.

Nein, der Faktor 1/512 ist nicht Null, genausowenig wie 1+1 gleich 3 
ist.
Aber natürlich stimmt es, das die Zahlenrepresentationen mancher 
elektronischer Rechenknechte und deren Programmiersprachen die Gesetze 
der Mathematik (scheinbar) außer Kraft setzen resp. (unbekümmert) 
ignorieren.

von Falk B. (falk)


Lesenswert?

Klaus K. schrieb:
>> Wäre es nicht, weil 1/512 = 0 ist und dann das Ergebnis auch 0 wäre.
>
> Nein, der Faktor 1/512 ist nicht Null,

Doch, denn es sind Integer, keine Fließkommazahlen.

von Mi N. (msx)


Lesenswert?

Ob S. schrieb:
> Das ist doch so offensichtlich, dass man das sogar stinkbesoffen sofort
> lesen kann.

Anders herum wird ein Schuh draus: man muß stinkbesoffen sein, um 
solchen Code ertragen zu können. Strunzdoof ist nicht der Compiler, 
sondern der Programmierer.

Hört denn dieser Kinderkram mit den vermeintlichen Optimierungen nie 
auf? Zum Schluß wird noch nach einem Verfahren gesucht, damit 10/3 genau 
3 ergibt, um in seiner bescheiden kleinen Welt glücklich zu werden :-(
Aber gut, jeder so wie er kann.

von Norbert (der_norbert)


Lesenswert?

Klaus K. schrieb:
> Gerade diese "Code-Zerstörung" resp. -aufweichung ist ja der Zweck einer
> Optimierung.

Sag mal, liest du auch manchmal was du schreibst?
Und - viel wichtiger - kannst du das ertragen ohne vor Schmerzen zu 
schreien?

von Roland F. (rhf)


Lesenswert?

Hallo,
Mi N. schrieb:
> ...man muß stinkbesoffen sein, um solchen Code ertragen zu können.

Gegenüber vielen hier gezeigten C++-Code-Beispielen ist obiger Code ein 
Musterbeispiel für Klarheit und Effektivität.

Aber vielleicht man schon mal in Maschinensprache programmiert haben um 
die Einfachheit obigen Codes zu erkennen.

rhf

von Udo S. (urschmitt)


Lesenswert?

Mi N. schrieb:
> Zum Schluß wird noch nach einem Verfahren gesucht, damit 10/3 genau
> 3 ergibt

Das Verfahren ist alt, lernt jeder in der zweiten(?) Klasse. Nennt sich 
Ganzzahlendivision mit Rest.
Und ist auf den mir bekannten Prozessoren das was beim normalen DIV 
Befehl rauskommt.

SCNR

: Bearbeitet durch User
von Mi N. (msx)


Lesenswert?

Roland F. schrieb:
> Gegenüber vielen hier gezeigten C++-Code-Beispielen ist obiger Code ein
> Musterbeispiel für Klarheit und Effektivität.

Leider nein und inkonsequent umgesetzt, denn es geht natürlich frei von 
Grundrechenarten.
1
OCR0A = ((delta << 8 | (delta << 1 | delta) << 1)) >> 9;
Gruß nach Dödelhausen.

von Roland F. (rhf)


Lesenswert?

Hallo,
Mi N. schrieb:
> OCR0A = ((delta << 8 | (delta << 1 | delta) << 1)) >> 9;

Auch schön. :-)

rhf

von Dergute W. (derguteweka)


Lesenswert?

Moin,

Klaus K. schrieb:
>>>> OCR0A = (262L * delta) >> 9;

Jaaa - aehh...Also wenn ich schon auf dem Level "optimieren" will, wieso 
dann nicht:
(131L*bla)>>8

So'n 8er shift stell ich mir auf einem 8bit Prozessor bedeutend leichter 
vor als einen 9er.

scnr,
WK

von Uuu B. (hansdampf2)


Lesenswert?

Nach dem also geklärt ist, dass man heute neben Festkomma auch float im 
µC rechnen lassen kann, hier meine Antwort auf die Frage des 
Threadstarters zur BERECHNUNG seines offensichtlich mehr oder weniger 
nichtlinearen Messproblems.
Eine Anpassung an eine Skalierungskurve zweiter Ordnung könnte in diesem 
Fall eher hilfreich sein als ein linearer Dreisatz: Zielwert = k0 + k1 * 
ADC + k2 * ADC*ADC, wobei k0 ,k1 ,k2 aus 3 (einmalig kalibrierten) 
Stützstellen-Wertepaaren ermittelt werden. Z.B. bei 1V, 2,5V und 4V (und 
dazu die jeweiligen ADC-Werte). Dann ließe sich auch die 12 
Bit-Auflösung des ADC trotz des Impedanz-Dilemmas besser nutzen. Es käme 
nur auf eine sorgfältige einmalige Messung an. Die Berechnung der 
Konstanten k0-k2 erfolgt dann bekanntermaßen nach Newton. Hier ein 
Programmierbeispiel für die Berechnung der Konstanten zur Laufzeit aus 
einem bewährten Turbo-Pascal Programm von 2005 (x0/Y0-Wertepaar, a0 
entspricht obigen k0 usw.):
1
procedure newton(x0,y0,x1,y1,x2,y2:real;var a0, a1, a2:real);
2
  var c0,c1,c2:real;
3
  begin
4
      if x0=x1 then begin x1:=x0+(x2-x0)/2;y1:=y0+(y2-y0)/2;end;
5
      if (x0=x2)OR(x1=x2)then begin x2:=x0+(x1-x0)/2;y2:=y0+(y1-y0)/2;end;
6
      c0:=y0;
7
      if ((x1-x0)<>0)then c1:=(y1-c0)/(x1-x0) else c1:=max;
8
      if(((x2-x0)*(x2-x1))<>0)then c2:=((y2-c0)-(c1*(x2-x0)))/((x2-x0)*(x2-x1))
9
        else c2:=0;
10
      a0:=c0-(c1*x0)+(c2*x0*x1);
11
      a1:=c1-(c2*x0)-(c2*x1);
12
      a2:=c2;
13
  end;
Die Konstanten kann man natürlich auch von Hand errechnen und im 
Programm fest hinterlegen. Ist ja nur einmal nötig.

: Bearbeitet durch User
von Udo S. (urschmitt)


Lesenswert?

Uuu B. schrieb:
> hier meine Antwort auf die Frage des
> Threadstarters

Der hat zum gleichen Thema zwei Threads aufgemacht und weil keiner das 
gesagt hat was er gerne hören wollte sich um beide nicht mehr gekümmert.

von Mi N. (msx)


Lesenswert?

Dergute W. schrieb:
> Jaaa - aehh...Also wenn ich schon auf dem Level "optimieren" will, wieso
> dann nicht:
> (131L*bla)>>8
>
> So'n 8er shift stell ich mir auf einem 8bit Prozessor bedeutend leichter
> vor als einen 9er.

Endlich mal was Konstruktives.
Machen wir es also so und reduzieren die Erderwärmung:
1
OCR0A = (delta << 7 | (delta << 1 | delta)) >> 8;

Und wenn der Faktor mal 27931 sein sollte, gibt es sicherlich die 
optimale Lösung auch dafür ;-)

: Bearbeitet durch User
von Andreas M. (amesser)


Lesenswert?

Mi N. schrieb:
> Leider nein und inkonsequent umgesetzt, denn es geht natürlich frei von
> Grundrechenarten.
>
1
OCR0A = ((delta << 8 | (delta << 1 | delta) << 1)) >> 9;

Leider falsch. Das Ergebnis Deiner falschen Shift-Orgie ist nämlich ein 
uint16_t.
um 9 Bit nach rechts geschiftet bleiben nur 7 Bit übrig. Daneben müssen 
die Teilergebnisse addiert und nicht verordert werden.

Mi N. schrieb:
> Endlich mal was Konstruktives.
>
1
OCR0A = (delta << 7 | (delta << 1 | delta)) >> 8;

Immer noch falsch, du musst addieren statt verodern.

Am Ende des Tages ist der Compiler genauso schlau, wie du meinst zu 
sein. Nur halt von Anfang an richtig statt das er zig Versuche dazu 
braucht.

https://godbolt.org/z/zbvb1fazM

> Gruß nach Dödelhausen.

Gruß zurück.

: Bearbeitet durch User
von Mi N. (msx)


Lesenswert?

Andreas M. schrieb:
> Leider falsch. Das Ergebnis Deiner falschen Shift-Orgie ist nämlich ein
> uint16_t.

delta ist doch uint32_t.
Aber schön, daß Du diese Programmierweise als fehlerträchtig entlarfst.

von Andreas M. (amesser)


Lesenswert?

Mi N. schrieb:
> delta ist doch uint32_t.

Nö, da wo die Zeile herkommt ist delta uint16_t.

von Mi N. (msx)


Lesenswert?

Andreas M. schrieb:
>> delta ist doch uint32_t.
>
> Nö, da wo die Zeile herkommt ist delta uint16_t.

Na geht's noch?
Das würde ja bedeuten, dem Compiler eine temporäre Typanpassung 
zuzumuten.
Gans schlecht programmiert - besser gegessen.
Wie gesagt: Kinderkram.

von Norbert (der_norbert)


Lesenswert?

Mi N. schrieb:
> Gans schlecht programmiert - besser gegessen.

Und dabei haben wir noch nicht einmal darüber geredet das anstelle einer 
vernünftigen Rundung einfach ein floor implementiert wurde.

Abba dafür iss alles schön in Integer… ;-)

von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> So sind bei float x1 = sqrt(2) und double x2 = sqrt(2) die beiden
> resultierenden Werte NICHT gleich.

Was für eine Überraschung.
Wenn du von einer unendlich langen Zahl willkürlich unterschiedlich 
viele Stelle abschneidest, kannst du nicht erwarten, dass der 
Unterschied zwischen deinen beiden Abschnitten zufällig vollständig aus 
Nullen besteht, kann manchmal klappen, aber bei 29 Bit ist das doch eher 
unwahrscheinlich, wenn es sich nicht um binär glatte Zahlen handelt.

von Axel R. (axlr)


Lesenswert?

Kann man bitte mal nen Schaltplanauszug bekommen, dass man weis, wo da 
welcher Spannungsteiler wie verschaltet wurde. Wird ja hinzubekommen 
sein, sich dem Wusch des TO wenigstens ansatzweise nähern zu können. Ist 
ja keine Raketenwissenschaft, sondern Irgendwas mit "Kirchoff und Ohm" 
und wer da noch so seine Finger mit im Spiel hatte, damals(tm).
Vielleicht reicht es ja schon, das Impedanzniveau der Gesamtschaltung um 
den Faktor zehn zu verringern.

von Rainer W. (rawi)


Lesenswert?

Axel R. schrieb:
> Vielleicht reicht es ja schon, das Impedanzniveau der Gesamtschaltung um
> den Faktor zehn zu verringern.

... oder ein Kondensator am betreffenden Multplexereingang.

von Max M. (Gast)


Lesenswert?

Ist ja nicht teil der Frage.
Er fragt ja nach einer Softwarelösung der IST Situation
Das er an der HArdware was ändern könnte, wusste er bzw weiß er,ja jetzt 
auch.
Völlig unabhängig davon finde ich aber eine Lösung für so ein Problem 
wie es gegeben ist auch interessanter, was den Lerneffekt angeht.
Spricht Mehrpunktkalibration, oder mit Tabelle Arbeiten etc pp
Es ist ja ok, den Themenstarter auf etwas hinzuweisen, aber seine Frage 
lautet ja anders und nicht was ist an der HArdware falsch und sollte 
geändert werden.
Kenne ich leider von meinen Themen auch, dass es dann so verläuft...


Axel R. schrieb:
> Kann man bitte mal nen Schaltplanauszug bekommen, dass man weis,
> wo da
> welcher Spannungsteiler wie verschaltet wurde. Wird ja hinzubekommen
> sein, sich dem Wusch des TO wenigstens ansatzweise nähern zu können. Ist
> ja keine Raketenwissenschaft, sondern Irgendwas mit "Kirchoff und Ohm"
> und wer da noch so seine Finger mit im Spiel hatte, damals(tm).
> Vielleicht reicht es ja schon, das Impedanzniveau der Gesamtschaltung um
> den Faktor zehn zu verringern.

von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> Was für eine Überraschung.

Wenn du den Rest gelesen und verstanden hättest, dann nicht.
Ich schrieb - EXPLIZIT - das ein casual printf zwei gleiche Werte 
anzeigt obwohl ein Vergleich der Werte kein True ergibt.

Aber danke für deinen Beitrag.

von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> Ich schrieb - EXPLIZIT - das ein casual printf zwei gleiche Werte
> anzeigt obwohl ein Vergleich der Werte kein True ergibt.

Wenn du über printf vergleichen willst (gleiche Ausgabe), musst du 
sicher stellen, dass dein casual printf mehr Stellen darstellt, als 
deine Zahl benutzt und nicht gar noch eine implizite Typumwandlung mit 
Stellenverlust dazwischen schalten.

von A. F. (chefdesigner)


Lesenswert?

Max M. schrieb:
> Kenne ich leider von meinen Themen auch, dass es dann so verläuft...

jaja, aber das liegt auch immer an denen, die alles (T)OT machen, indem 
sie z.B. über SW diskutieren :-)

Und hier lohnt schon auch ein Hinweis an den TO, dass man das hätte 
googeln können. Wie man Widerstände und deren Abweichungen wegbekommt, 
ist ja easy.

In der Messtechnik nennt sich das Fehlerrechnung.

von Steve van de Grens (roehrmond)


Lesenswert?

Klaus K. schrieb:
> der Faktor 1/512 ist nicht Null

In C ist er das, sofern (wie hier) beide Operanden Integer sind.

von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> Wenn du über printf vergleichen willst (gleiche Ausgabe), musst du
> sicher stellen, dass dein casual printf mehr Stellen darstellt, als
> deine Zahl benutzt und nicht gar noch eine implizite Typumwandlung mit
> Stellenverlust dazwischen schalten.

Ernsthaft? Ich meine, ERNSTHAFT?

All das habe ich bereits früher ausführlich geschrieben.
Aber wir können's ja gerne immer wieder falsch und/oder unvollständig 
zitiert wiederholen.

Nebenbei sind das alles Informationen für Anfänger, wie in der 
Threaderöffnung unschwer zu sehen ist.
Ich glaube nicht das jemand der eine 32bit Folge mit dem Stift auf dem 
Papier in einen Float Wert gemäß IEEE754 umwandeln kann in diese Fallen 
stolpert.

von Klaus K. (Gast)


Lesenswert?

Falk B. schrieb:
> Klaus K. schrieb:
>>> Wäre es nicht, weil 1/512 = 0 ist und dann das Ergebnis auch 0 wäre.
>>
>> Nein, der Faktor 1/512 ist nicht Null,
>
> Doch, denn es sind Integer, keine Fließkommazahlen.

Wenn es ein Integer ist, dann ist es auch für Fixpoint tauglich.
Ist denn das Wissen um Fixpoint völlig in Vergessenheit geraten?

https://en.wikipedia.org/wiki/Fixed-point_arithmetic#Applications
Beitrag "ADC und Fixed-Point Arithmetik"
Beitrag "FixedPoint in C und C++"

Genaugenommen ist der "nackte" (32 bit) Integer ein fixpoint mit 0 
Nachkommastellen also 32b.0b . Es ist ein Leichtes, die 12 bit des ADC 
hier so auf die 32 bit zu "skalieren" das man damit bespielsweise 
16b.16b oder 22b.10b Fixpoint ausführen kann.

Und in solchen Fixpoint-darstellung ist die Zahl "1/512"  eben nicht 
gleich 0. Man kann auch in manchen Programmiersprachen Operatoren wie 
'+' überladen, das auf den ersten Blick kein Unterschied zwischen der 
Darstellung  32b.0b und 22b.10b Rechnung erkennbar ist. Manche nennen 
diese triviale Grunderkenntniss aus der Numerik nicht Fixpoint, manche 
sprechen lediglich "von der richtigen Skalierung an der richtigen Stelle 
und Rundungsfehler durch unterschlagenen Nachkommastellen zu vermeiden".
Braucht bei arithmetischer Mittelung, Filterung und Statistik 
allenthalben.

****

Norbert schrieb:
> Klaus K. schrieb:
>> Gerade diese "Code-Zerstörung" resp. -aufweichung ist ja der Zweck einer
>> Optimierung.
>
> Sag mal, liest du auch manchmal was du schreibst?
> Und - viel wichtiger - kannst du das ertragen ohne vor Schmerzen zu
> schreien?

Eher ist es die Frage, ob Du nicht fähig oder nicht willens bist, die 
Posts die Andere verfasst haben zu verstehen!

Natürlich verändert eine Optimierung wie "Dead Code Elimination" den 
Code, insbesonders wenn sie wegen einem vergessen "volatile" unerwartet 
aktiv ist. Ebenso wirft die Optimierung "Loop unrooling" Code-teile wie 
den Loop-Header und pointer-Rechnung aus den Programm. Optimierende 
register-Allokierung wandelt langsames Speicher-lesen/schreiben in 
schnelles Register-umladen um, ...

https://en.wikipedia.org/wiki/Dead-code_elimination
https://de.wikipedia.org/wiki/Loop_unrolling
https://de.wikipedia.org/wiki/Volatile_(Informatik)
https://en.wikipedia.org/wiki/Register_(keyword)

***

Max M. schrieb:

> Es ist ja ok, den Themenstarter auf etwas hinzuweisen, aber seine Frage
> lautet ja anders und nicht was ist an der HArdware falsch und sollte
> geändert werden.

Es ist nicht "nur" ok, es ist notwendig den Threadstarter 
unmissverständlich daraufhinzuweisen das er  offensichtlich grob falsche 
Messwerte bearbeitet. Andernfalls setz man sich dem Vorwurf aus, ihn 
"sehendes Auge ins Messer laufen zu lassen".

Man kann einen defekten AD-Wandler, also einer mit massiven 
Grundrauschen, Offset-Fehler und Nichtlinearitäten nicht "gesund" 
programmieren. Das der AD-Wandler eigentlich ganz passable arbeitet, 
aber die "Messwerte" wie "bei 0 Volt Digitalwert '000011000001' " vom TO 
'erlogen' wurden, das es so ausschaut als wäre der ADC defekt, ist dann 
eine ganz andere Geschichte ...

von Falk B. (falk)


Lesenswert?

Klaus K. schrieb:
> Wenn es ein Integer ist, dann ist es auch für Fixpoint tauglich.
> Ist denn das Wissen um Fixpoint völlig in Vergessenheit geraten?

Jaja, deine Weiheit hat uns gerade noch gefehlt!

von Klaus K. (Gast)


Lesenswert?

> Jaja, deine Weiheit hat uns gerade noch gefehlt!

Offennichtlich ;-)

von Norbert (der_norbert)


Lesenswert?

Klaus K. schrieb:
> Eher ist es die Frage, ob Du nicht fähig oder nicht willens bist, die
> Posts die Andere verfasst haben zu verstehen!

Oh vertrau mir, ich habe deinen Text gelesen. Deshalb war ich ja so - 
nennen wir es mal abmildernd - verblüfft.

Du hattest geschrieben:

Klaus K. schrieb:
> Gerade diese "Code-Zerstörung" resp. -aufweichung ist ja der Zweck einer
> Optimierung.

Der Code wird ganz sicher nicht zerstört und auch nicht aufgeweicht - 
was auch immer diese hochgradig seltsamen Beschreibungen auch aussagen 
sollen.

Bei einer Code Optimierung wird in einer Art und Weise Maschinencode 
generiert, das der ursprüngliche Zweck und die ursprüngliche Funktion zu 
100% erhalten bleiben. Wäre das nicht der Fall sein - und man beachte 
bitte den Konjunktiv - dann wäre es »Code-Zerstörung« und der Compiler 
somit reparaturbedürftig.

Nicht beachtet wird jedoch die Geschwindigkeit oder Größe des erzeugten 
Code. Darüber wird keinerlei Aussage getroffen oder Annahme gemacht, 
bzw. das ist abhängig von den Optimierungseinstellungen.

von Klaus K. (Gast)


Lesenswert?

> Klaus K. schrieb:
>> Gerade diese "Code-Zerstörung" resp. -aufweichung ist ja der Zweck einer
>> Optimierung.
>
> Der Code wird ganz sicher nicht zerstört und auch nicht aufgeweicht -
> was auch immer diese hochgradig seltsamen Beschreibungen auch aussagen
> sollen.
>
> Bei einer Code Optimierung wird in einer Art und Weise Maschinencode
> generiert, das der ursprüngliche Zweck und die ursprüngliche Funktion zu
> 100% erhalten bleiben. Wäre das nicht der Fall sein - und man beachte
> bitte den Konjunktiv - dann wäre es »Code-Zerstörung« und der Compiler
> somit reparaturbedürftig.

Mglw. meinen wir das Gleiche, wobei der eine drastische Wortwahl 
benutzt. Auch macht es den Disput nicht einfacher, wenn ohne 
Unterscheidung von "Code" gesprochen wird unabhängig davon ob damit 
Opimierungs-Imput (bspw. Hochsprachen-Code) oder Optimierungs-Output 
(Kompilat, Maschinencode) gemeint ist.


Optimierung heisst eben Aufwandsverminderung, also beispielsweise 
weniger Zeit aufwenden, weniger Speicher benutzen. Und das schliesst 
eben auch den Fall ein, das der eigentliche Zweck "umformuliert" wird. 
Wie bei der Codeoptimierung, bei der eben eine Zählschleife als (dummer) 
Delay-ersatz rausfliegt, weil eben der gezählte Wert nie benutzt wird.

Oder beim loop-unrolling fällt bspw das incrementweg, der for () Teil 
exestiert schlicht nicht, kann auch bei Reverse compilieren im 
Instruction code nicht aufgefunden werden. Das wäre dann m.M.n. 
"zerstörter Code". Das kann dann beim debugging für verwunderung sorgen, 
wenn man beispielsweise auf das increment eines registerwertes wartet.

Und natürlich kann auch etwas "kaputt optimiert" werden, das sehe ich 
nicht vorrangig als Compilerfehler, sondern eher Fehler des 
Compiler-nutzers. Dann hat er eben ein Stück Code vom Compiler 
automatisch optimieren lassen, das nicht "verändert" werden darf. Also 
eine Form von "zu Tode gespart" resp. "an falschen Ende gespart".

Bei sicherheitsrelevanter Software (Luftfahrt) wird auch gern gefordert, 
die hohen Optimierungsstufen nicht zu benutzen:
Beitrag "Wann Compiler-Optimierung in Embedded ausschalten"

von Sebastian W. (wangnick)


Lesenswert?

Klaus K. schrieb:
> Und natürlich kann auch etwas "kaputt optimiert" werden, das sehe ich
> nicht vorrangig als Compilerfehler, sondern eher Fehler des
> Compiler-nutzers

Klaus, ich finde du hast eine enorm erfrischende Art, jegliche 
Produktfehler als durch den Kunden verursacht anzusehen!

LG, Sebastian

: Bearbeitet durch User
von Klaus K. (Gast)


Lesenswert?

>  ich finde du hast eine enorm erfrischende Art, jegliche
> Produktfehler als durch den Kunden verursacht anzusehen!

Ich empfehle ein Wochenende der Kontemplation über "Errare humanum est"
verbunden mit intensiven Digital-Detox. 
https://images.pling.com/img/00/00/08/05/63/1059069/66550-1.jpg

von A. F. (chefdesigner)


Lesenswert?

Norbert schrieb:
> Bei einer Code Optimierung wird in einer Art und Weise Maschinencode
> generiert,

Widerspruch! Die Compiler zerpflücken heute in der Regel in einer 
Vorphase der Übersetzung des Codes selbigen so, dass er 
compiler-kompatibel wird, zur Aufgabe passt und die Vorgaben des 
Entwicklers berücksichtig, oftmals auch die des Herstellers.

- Bei Funktionsaufrufen wird z.B. die Stacktiefe mitprotokolliert, die 
erzeugt wird um sicherzustellen, dass die Resourcen die eingestellt und 
verfügbar sind, auch reichen.

- Beim Inlinnig wird geprüft, ob die zeitlichen Randbedingungen noch 
passen, wenn z.B. eine LIB als Datei ausgelagert ist, deren 
Funktionsteile nachgeladen werden müssen und gegengerechnet, ob der 
Mehr-Code, der durch Einkopieren erzeugt wird, noch in das spätere Flash 
passt - früher wurde sogar noch geprüft, ob der Compiler wegen der 
RAM-Beschränkungen die eine oder andere Stategie fahren darf - um nichts 
überlaufen zu lassen (ist heute natürlich weg)

- Funktionsaufrufe aus lib-spezifischen API-calls werden dahingehend 
erweitert oder gestripped, daß die herstellereigenen Implementierungen 
direkt verwendet werden können, damit nicht ausgedehnter Code erzeugt 
und übersetzt werden muss, sondern bereits linkerfähiger Code in einer 
von mehreren vorbereiteten Übersetzungen verwendet werden kann - um a ) 
schneller zu werden,  b) Knowhow zu schützen, weil so kein lesbarer 
C-Code vorliegen muss

- weiters wegen Funktionsaufrufe so gestaltet, dass die MPS-fähig 
werden, also Zugriff auf Resourcen erlangen können, die mehrfach genutzt 
werden, bzw die in den LIBs vorbereiteten Funktionen dafür werden 
aktiviert - oder auch weggelassen, wenn es ein Single Core System ist.

Da gibt es noch hundert andere Sachen

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

Z.B. Max Z. schrieb:
> Wie berechne ich das richtig?
Wenn du das unbedingt willst, dann über 2 einzelne Geraden so wie im von 
dir irrtümlich neu angetriggerten 
Beitrag "Wertebereich skalieren und Offset ausgleichen" recht weit unten.

Kurz: dein Problem hat nichts mit dem Compiler zu tun, auch wenn du dort 
den Schuldigen suchst.

Du solltest einfach mal deine Kennlinie aufzeichnen. Hilfreich wäre dann 
auch, ein paar mehr Stützpunkte der Kennlinie zu haben, wenn du schon 
erkennst, dass sie nicht linear ist.

Sebastian W. schrieb:
> Klaus K. schrieb:
>> Und natürlich kann auch etwas "kaputt optimiert" werden, das sehe ich
>> nicht vorrangig als Compilerfehler, sondern eher Fehler des
>> Compiler-nutzers
> Klaus, ich finde du hast eine enorm erfrischende Art, jegliche
> Produktfehler als durch den Kunden verursacht anzusehen!
Es ist eher so, dass sich der Anwender aus Faulheit oder seinem "Gefühl 
heraus" implizit auf etwas verlässt, was nirgends so dokumentiert ist. 
Derjenige, der die Doku zur Sprache gelesen hat, weil er dafür einen 
Compiler schreiben musste, nimmt auf solche faulen Kameraden und 
irgendwelche Gefühle natürlich keine Rücksicht.

: Bearbeitet durch Moderator
von Klaus K. (Gast)


Lesenswert?

>> Klaus K. schrieb:
>>> Und natürlich kann auch etwas "kaputt optimiert" werden, das sehe ich
>>> nicht vorrangig als Compilerfehler, sondern eher Fehler des
>>> Compiler-nutzers
>> Klaus, ich finde du hast eine enorm erfrischende Art, jegliche
>> Produktfehler als durch den Kunden verursacht anzusehen!
> Es ist eher so, dass sich der Anwender aus Faulheit oder seinem "Gefühl
> heraus" implizit auf etwas verlässt, was nirgends so dokumentiert ist.
> Derjenige, der die Doku zur Sprache gelesen hat, weil er dafür einen
> Compiler schreiben musste, nimmt auf solche faulen Kameraden und
> irgendwelche Gefühle natürlich keine Rücksicht.

Wenn halt jemand das richtige Werkzeug an der falschen Stelle/zum 
falschen Zweck verwendet, dann liegt das Problem eben nicht beim 
"Werkzeugmacher". Oder wie der Engländer kalauert: "a fool with a tool 
is still a fool"

Außerdem ist es meiner Erfahrung nach produktiver und führt schneller zu 
Erfolg wenn man die Verbesserungs/Lösungsmöglichkeiten wie bspw. Auswahl 
des passenden tools oder Produktes selbst in der Hand hat, als das man 
versucht den Hersteller zur Änderung an seinem Produkt zu bewegen.

von Norbert (der_norbert)


Lesenswert?

Auf dem PC ein passendes Polynom berechnen:
1
#!/usr/bin/python3
2
import numpy as np
3
4
def pc_berechnung():
5
    adc = [193, 2221, 4072]
6
    voltage = [0.0, 2.5, 5.0]
7
    a, b, c = np.polyfit(adc, voltage, 2)
8
    print(f'a, b, c = {a}, {b}, {c}')
9
10
pc_berechnung()

Ergebnis:
a, b, c = 3.038919010942562e-08, 0.0011593821124328478, 
-0.22489271464192534

Auf dem Microcontroller (hier mit Micropython):
1
#!/usr/bin/python3
2
def µC_poly(a,b,c):
3
    def f(x):
4
        return a * x**2 + b * x + c
5
    return f
6
7
def µC_test():
8
    a, b, c = 3.038919010942562e-08, 0.0011593821124328478, -0.22489271464192534
9
    func = µC_poly(a, b, c)
10
    for adc_inp in range(193, 4072+1):
11
        print(f'{adc_inp:4d}  {func(adc_inp):5.3f} V')

Ein Aufruf von func(adc_inp) dauert ~48µs.

Lässt sich dann aber auch sehr bequem zB. in Assembler/Forth/INTERCAL 
formulieren.

: Bearbeitet durch User
von Uuu B. (hansdampf2)


Lesenswert?

Norbert schrieb:
> a, b, c = np.polyfit(adc, voltage, 2)

Hinweis: die neuere Form ist "polynominal"...
"This forms part of the old polynomial API. Since version 1.4, the new 
polynomial API defined in numpy.polynomial is preferred. A summary of 
the differences can be found in the transition guide"
[https://numpy.org/doc/stable/reference/generated/numpy.polyfit.html]

von Norbert (der_norbert)


Lesenswert?

Uuu B. schrieb:
> Hinweis: die neuere Form ist "polynominal"...

Korrekt. War aber zugegebenermaßen gerade einfach zu bequem...
1
#!/usr/bin/python3
2
from numpy.polynomial import Polynomial
3
4
a, b, c = Polynomial.fit(adc, voltage, 2)

: Bearbeitet durch User
von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> a, b, c = 3.038919010942562e-08, 0.0011593821124328478,
> -0.22489271464192534

Kannst du die Werte nicht mit noch etwas mehr gewürfelten 
Nachkommastellen angeben? ;-)

Guck dir dazu vielleicht die Fehlerfortpflanzung basierend auf einem 
Fehler der Eingangswerte von bis zu 0.49 bzw. 0.049V an.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> Kannst du die Werte nicht mit noch etwas mehr gewürfelten
> Nachkommastellen angeben? ;-)

Hätte ich gekonnt, hatte aber bequemerweise einfach die Ausgabe des 
Programmes wenige Zeilen darüber genommen. Hat auch gar nicht weh getan. 
Vor allem ändert es absolut gar nichts an der 
Ausführungsgeschwindigkeit.

Zunächst überflüssig erscheinende Genauigkeit wird im Bedarfsfall 
automagisch verworfen.

Man könnte also die Ausgabe sowohl für ›float‹ als auch für ›double‹ 
verwenden.

Interessanter Nebeneffekt: Man kann Micropython sowohl mit ›float‹ als 
auch mit ›double‹ Genauigkeit kompilieren.

Gerüchteweise soll es auch in anderen Programmiersprachen funktionieren.

Wollt's nur mal angesprochen haben. ;-)

von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> Zunächst überflüssig erscheinende Genauigkeit wird im Bedarfsfall
> automagisch verworfen.

Das, was du da präsentierst, ist keine Genauigkeit, sondern weitgehend 
sinnloser Zahlensalat.

Die Eingangsdaten haben, so wie der TO es schreibt, gerade einmal eine 
Genauigkeit von bestenfalls zwei gültigen Stellen. Damit kann das 
Ergebnis bei gerade einmal drei Messpunkten nicht plötzlich wesentlich 
besser werden.

: Bearbeitet durch User
von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> …Dinge…

Bitte beschreibe den entstandenen Schaden wenn man die Werte aus der 
vorangegangenen Rechnung einfach übernimmt…

Danke!

von Rainer W. (rawi)


Lesenswert?

Norbert schrieb:
> Rainer W. schrieb:
>> …Dinge…
>
> Bitte beschreibe den entstandenen Schaden wenn man die Werte aus der
> vorangegangenen Rechnung einfach übernimmt…

Füllen von Papier/Bildschirm mit sinnfreiem und eine nicht vorhandene 
Genauigkeit vorgaukelnden Zahlensalat, den vielleicht auch noch Leute 
lesen und fälschlicherweise für bare Münze nehmen.

> Danke!

Gerne

von Norbert (der_norbert)


Lesenswert?

Rainer W. schrieb:
> …erneut…

Ach weißt du Rainer, nun habe ich für dich kompetenten Erbsenzähler nur 
noch ein ursprünglich an den Meister Röhricht Gerichtetes:

Ja, Ja

: Bearbeitet durch User
von Joachim B. (jar)


Lesenswert?

Rainer W. schrieb:
> Füllen von Papier/Bildschirm mit sinnfreiem und eine nicht vorhandene
> Genauigkeit vorgaukelnden Zahlensalat

stört doch nicht!

Rainer W. schrieb:
> Zahlensalat, den vielleicht auch noch Leute
> lesen und fälschlicherweise für bare Münze nehmen.

das ist doch deren Problem, wer es nicht lernen will!

Ich nehme auch gerne Rechenergebnisse C & P wird eh vom Preprozessor 
ausgerechnet, sind also nur ein paar Byte im Quellcode, da muss man hier 
nicht die Riesenkeule schwingen.

von Yalu X. (yalu) (Moderator)


Lesenswert?

Rainer W. schrieb:
> Das, was du da präsentierst, ist keine Genauigkeit, sondern weitgehend
> sinnloser Zahlensalat.

Die drei Zahlenwerte sind genau in dem Sinne, dass sie bei der
Verrechnung mit den (relativ ungenauen) Messwerten keine weitere
Ungenauigkeit hinzufügen.

> Die Eingangsdaten haben, so wie der TO es schreibt, gerade einmal eine
> Genauigkeit von bestenfalls zwei gültigen Stellen.

Wenn der Fehler der Eingangsdaten bei 1% liegt und die Koeffizienten
durch die von dir vorgeschlagene Rundung ebenfalls mit einem Fehler von
1% beaufschlagt werden, wächst der Fehler des Ergebnisses unnötigerweise
von 1% auf 2%. Das will man natürlich nicht.

Es ist deswegen generell ratsam, bei einer Berechnung sämtliche
Operanden mit der jeweils maximal verfügbaren Genauigkeit einzusetzen.
Die Rundung auf eine vernünftige Stellenzahl sollte immer erst beim
Endergebnis vorgenommen werden. Da ist sie aus den von dir genannten
Gründen auch sinnvoll.

von Joachim B. (jar)


Lesenswert?

Yalu X. schrieb:
> Die drei Zahlenwerte sind genau in dem Sinne, dass sie bei der
> Verrechnung mit den (relativ ungenauen) Messwerten keine weitere
> Ungenauigkeit hinzufügen.

so kann man es auch ausdrücken, man nimmt was man hat.

von Rainer W. (rawi)


Lesenswert?

Yalu X. schrieb:
> Die drei Zahlenwerte sind genau in dem Sinne, dass sie bei der
> Verrechnung mit den (relativ ungenauen) Messwerten keine weitere
> Ungenauigkeit hinzufügen.

Dafür hätte auch die Angabe der Werte mit um 10 Stellen reduzierter 
Auflösung mehr als gereicht.
"keine weitere" ist genauso unsinnig wie "bestmöglich" und relativ in 
Bezug auf die Qualität der Ausgangsdaten.

: Bearbeitet durch User
Beitrag #7551000 wurde von einem Moderator gelöscht.
von Rainer W. (rawi)


Lesenswert?

Ich wundere mich immer mehr, mit welcher Borniertheit hier dieser 
bedeutungslose Zahlensalat verteidigt wird, der jeglicher Grundlage 
entbehrt.
Gedankenlos werden Ziffern nachgeplappert, die ein Algorithmus unter 
Annahme eines durch nichts begründeten Modellansatzes ausspuckt.

Und wenn die nächste Sprache/Compiler Zahlenformate mit noch höherer 
Auflösung unterstützt, kommen eben noch 20 Ziffern dazu und werden als 
goldene Wahrheit verkauft ...

: Bearbeitet durch User
von M. K. (sylaina)


Lesenswert?

Rainer W. schrieb:
> Ich wundere mich immer mehr, mit welcher Borniertheit hier dieser
> bedeutungslose Zahlensalat verteidigt wird, der jeglicher Grundlage
> entbehrt.

Naja, ich wundere mich mit welcher Borniertheit hier gegen diese Lösung 
vorgegangen wird.
Wäre es nicht zielführender gewesen, wenn es dich schon so sehr stört, 
wenn du eine alternative Lösung angeboten hättest statt raus zu plärren 
"Bäh, das ist aber Scheiße.". Immerhin ist der "Zahlensalat" 
nachvollziehbar wo er her kommt (und deshalb auch verständlich dass er 
verteidigt wird), dass dir das aber egal ist macht die Sache nicht 
besser.
Was ich im Grunde sagen will: Wer so viel Gegenwind erfährt wie du 
sollte sich fragen ob er nicht doch auf dem falschen Kurs ist. ;)

von Rainer W. (rawi)


Lesenswert?

M. K. schrieb:
> Immerhin ist der "Zahlensalat" nachvollziehbar wo er her kommt

In der Technik gibt man zu Messwerten gewöhnlich einen Fehler an, der 
sich über weitere Berechnungen fortpflanzt.
Woher weiß der Polynomfitter, dass der Zusammenhang polynomisch mit 2ter 
Ordnung ist. Könnte nicht genauso gut bei einem ansonsten linearen 
Zusammenhang beim oberen Wert ein Sättigungsverhalten in Erscheinung 
treten, dass den unteren Bereich überhaupt nicht betrifft.

Wenigstens ein paar mehr Messwerte sollte man hinzuziehen.

von M. K. (sylaina)


Lesenswert?

Rainer W. schrieb:
> Wenigstens ein paar mehr Messwerte sollte man hinzuziehen.

Dem bin ich ja grundsätzlich nicht abgeneigt, ich kann deinen Standpunkt 
durchaus nachvollziehen. Die Frage ist aber halt auch wie der Standpunkt 
vorgetragen wird ;)

Die jetzige Lösung bezieht sich auf drei Messpunkte und das nur deshalb 
weil der TE bisher nur drei Messpunkt angegeben hat. Sprich: Genauer 
kann es zum jetzigen Standpunkt nicht werden. Und wenn ich sehe wie sich 
der TE bisher verhalten hat wird es, denke ich mir, auch nicht mehr 
Messpunkte geben.
Norbert hat seine Lösung incl. Lösungsweg präsentiert. Jetzt liegt es am 
TE ob er diese Lösung verwendet, die er ja auch mit beliebig mehr 
Messpunkten füttern kann um die Genauigkeit zu vergrößern ;)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


Lesenswert?

M. K. schrieb:
> weil der TE bisher nur drei Messpunkt angegeben hat
... und ihn das Thema seit 2 Wochen sowieso absolut nicht mehr 
interessiert.

Weder hier noch im doppelten 
Beitrag "Wertebereich skalieren und Offset ausgleichen"

: Bearbeitet durch Moderator
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.