Hi, ich bastel gerade mit einem Arduino Nano am analogen Eingang rum. Ich lese dazu bei jedem Durchlauf den Wert vom Analogpin ein und schreibe diesen in ein 255 Elemente fassendes Array welches ich als "Ringbuffer" organisiere. Wenn ich einen Wert brauche, bilde ich über das komplette Array einen Mittelwert. Jetzt merke ich aber schon, dass es hin und wieder Ausreisser gibt, bin mir aber nicht so wirklich sicher, wie ich an effizientesten damit umgehe. Eine Idee wäre natürlich, z.B. die 20 höchsten und die 20 niedrigsten Werte einfach zu verwerfen. Aber: wie ermittle ich diese am besten? Einfach das Array sortieren und die Mittelwertberechnung dann entsprechend nur für die Elemente 20-235 durchführen? Was, wenn z.B. der Fünftniedrigste Wert 30 mal vorkommt? Dann würde der ja "nur" 16 mal rausfliegen, und weitere 14 mal mit in den Mittelwert einfließen? Könnte da aber evtl. schon die geringere Gewichtung ausreichen? Auch bin ich mir eher unsicher, was mich eine Sortierung an CPU-Zeit kostet. Oder gibt es noch bessere und/oder effizientere Methoden? Wenn gewünscht kann ich natürlich auch mal einen ganzen Schwung an Rohdaten bereitstellen. Mir würde aber evtl. mal so ein bisschen Erfahrung von Euch reichen. VG da_user
Standardabweichung ermitteln, Werte entfernen gemäß (mittelwert - standardabweichung) < x < (mittelwert + standardabweichung) (kann auch doppelte Standardabweichung nehmen) Mittelwert neu berechnen und ausgeben
@Matthias S. (da_user) >ich bastel gerade mit einem Arduino Nano am analogen Eingang rum. >Ich lese dazu bei jedem Durchlauf den Wert vom Analogpin ein und >schreibe diesen in ein 255 Elemente fassendes Array welches ich als >"Ringbuffer" organisiere. Wenn ich einen Wert brauche, bilde ich über >das komplette Array einen Mittelwert. Das kann man mit weniger Rechenaufwand machen, wenn man immer den aktuellen Wert auf einen Akku addiert und den letzten Wert im Ringpuffer subtrahiert. Damit hat man mit minimalem Aufwand einen Mittelwert. >Jetzt merke ich aber schon, dass es hin und wieder Ausreisser gibt, Die man erstmal möglichst an der Quelle bekämpfen sollte. Woher kommt denn dein Meßwert? Wie sieht die elektrische Anbindung aus? Wie groß ist denn der Ausreißer? Ist der zufällig oder systematisch? >Gewichtung ausreichen? Auch bin ich mir eher unsicher, was mich eine >Sortierung an CPU-Zeit kostet. Man sollte nicht als erste Maßnahme zu Würg-Arounds und Schummeleien greifen sondern versuchen, die Ursache des Problems zu finden und abzustellen.
Michael schrieb: > Standardabweichung ermitteln, Werte entfernen gemäß > (mittelwert - standardabweichung) < x < (mittelwert + > standardabweichung) > (kann auch doppelte Standardabweichung nehmen) > Mittelwert neu berechnen und ausgeben Danke! Falk B. schrieb: > Das kann man mit weniger Rechenaufwand machen, wenn man immer den > aktuellen Wert auf einen Akku addiert und den letzten Wert im Ringpuffer > subtrahiert. Damit hat man mit minimalem Aufwand einen Mittelwert. Und den Akku teile ich durch die Anzahl der Werte? Ich spare mir im Programmablauf somit also das aufsummieren der Werte? Wäre eine Idee... Falk B. schrieb: > Die man erstmal möglichst an der Quelle bekämpfen sollte. Woher kommt > denn dein Meßwert? Wie sieht die elektrische Anbindung aus? Als "Sensorersatz" ist da im Moment ein einfacher Spannungsteiler dran. Der Sensor hat einen Widerstand von 10-184 Ohm gegen Masse, dazu noch ein 120 Ohm Pull-Up. Das ganze geht dann über einen analogen Optokoppler (HCNR-201 mit der günstigeren Beispielbeschaltung) an den Analogpin. Falk B. schrieb: > Wie groß ist denn der Ausreißer? Ist der zufällig oder systematisch? Gute Frage, dazu müsste ich wohl auch erstmal einen ganzen Schwung Werte nehmen. Da bastel ich mir mal was rein, was mir das ganze evtl. gleich in ner Art csv ausspuckt... Was mir aber auf jeden Fall auffällt, ist dass der Mittelwert mit jedem Reset und auch nach ~10.000 Durchläufen im Bereich von +/- 10 um meinen gedanklichen Mittelwert wandert. Beispiel: Ich habe für den Wert von 150 Ohm nach jeweils ~10.000 Durchläufen bei 5 Resets folgende Mittelwerte: 511; 500; 498, 511; 507. Für den Wert von 10 Ohm habe ich jetzt 3 Resets: 117; 161; 142. Auch ändert sich der Mittelwert zwischen zwei Resets kaum, bzw nicht so krass. Die Schaltung mit dem Optokoppler wird beim Reset weder Primär- noch Sekundärseitig von der Spannung getrennt. Zum Wert selbst: letzten Endes wird sich der wohl relativ flott ändern und soll eigentlich nur visualisiert werden. Dass der 100% richtig ist, ist weniger wichtig. Wichtiger wäre, dass ich eine Tendenz ablesen kann. Zur Erklärung: es handelt sich dann letzten Endes um den Öldruck im Auto der angezeigt werden soll.
:
Bearbeitet durch User
@Matthias S. (da_user) >Und den Akku teile ich durch die Anzahl der Werte? Ich spare mir im >Programmablauf somit also das aufsummieren der Werte? Wäre eine Idee... Ja. >Als "Sensorersatz" ist da im Moment ein einfacher Spannungsteiler dran. >Der Sensor hat einen Widerstand von 10-184 Ohm gegen Masse, dazu noch >ein 120 Ohm Pull-Up. Das ganze geht dann über einen analogen Optokoppler >(HCNR-201 mit der günstigeren Beispielbeschaltung) an den Analogpin. Das ist Müll, denn so ein einfacher Optokoppler hat KEINE stabile Kennlinie, wenn man nix weiter macht. Du mißt damit eher die Temperatur als einen konstanten Wert. >> Wie groß ist denn der Ausreißer? Ist der zufällig oder systematisch? >Was mir aber auf jeden Fall auffällt, ist dass der Mittelwert mit jedem >Reset und auch nach ~10.000 Durchläufen im Bereich von +/- 10 um meinen >gedanklichen Mittelwert wandert. Hmm. Ist deine Versorgungsspannung STABIL? Oder ein 08/15 Chinanetzteil? Auch die USB-Spannung ist nicht sonderlich stabil. Erstmal mußt du sicherstellen, daß dein Meßaufbau paßt. >Ich habe für den Wert von 150 Ohm nach jeweils ~10.000 Durchläufen bei 5 >Resets folgende Mittelwerte: 511; 500; 498, 511; 507. Klingt nach zuviel Schwankungsbreite. >Für den Wert von 10 Ohm habe ich jetzt 3 Resets: 117; 161; 142. Ebenso. >Zur Erklärung: es handelt sich dann letzten Endes um den Öldruck im Auto >der angezeigt werden soll. Bau dir erstmal einen gescheiten Sensorersatz. 10k Poti + 100nF am ADC-Pin. Saubere Versorgung aus einem Linearregler bzw. Labornetzteil. Dann reden wir weiter.
Falk B. schrieb: > Das ist Müll, denn so ein einfacher Optokoppler hat KEINE stabile > Kennlinie, wenn man nix weiter macht. Du mißt damit eher die Temperatur > als einen konstanten Wert. Das ist kein einfacher Optokoppler. Der HCNR-201 ist für die Übertragung von analogen Werten. Falk B. schrieb: > Hmm. Ist deine Versorgungsspannung STABIL? Oder ein 08/15 Chinanetzteil? > Auch die USB-Spannung ist nicht sonderlich stabil. Der Optokoppler wird Sensorseitig über einen 5V-Linearregler versorgt, Controllerseitig vom Arduino Nano, bei dem ich jetzt natürlich nicht sagen kann, ob der jetzt über die externe Stromversorgung (und damit über den aufgelöteten Linearregler) oder über die USB-Versorgung läuft. Davor hängt zwar schon jeweils ein günstiges China-Schaltreglerboard, aber das dürften doch die Linearregler gut ausgleichen? Aber Obacht: dieser Text: Falk B. schrieb: >>Was mir aber auf jeden Fall auffällt, ist dass der Mittelwert mit jedem >>Reset und auch nach ~10.000 Durchläufen im Bereich von +/- 10 um meinen >>gedanklichen Mittelwert wandert. und die von mir geposteten Werte die du mit "zuviel Schwankungsbreite" kommentiert hast, gehören zusammen! Der Mittelwert bleibt im Verlauf stabil, erst nach einem Reset ändert dieser sich um die +/-10. Dazu: was ist gemeint mit "zuviel Schwankungsbreite"? Falk B. schrieb: > Bau dir erstmal einen gescheiten Sensorersatz. 10k Poti + 100nF am > ADC-Pin. Beim Sensorersatz will ich natürlich bei den Werten bleiben, die der Sensor auch wirklich hat. 10k Poti scheidet somit aus. Ich habe mir auf einer Lochrasterplatine ein paar Widerstände und eine Stiftleiste zusammengelötet. Mit einem Jumper kann ich dann die verschiedenen Widerstände für die verschiedenen Drücke auswählen und aufschalten. Das sollte schon relativ vernünftig herhalten. Der HCN-201 ist auch nicht mehr auf einem Streckbrett zusammengefummelt, sondern auf einer ordentlichen geätzten Platine. Was ich hier noch ändern müsste, sind die passenden Transistoren. Die Beispielapplikation will 2N3906 und 2N3904, die hatte ich aber nicht und bin deswegen auf BC557 und BC547 ausgewichen. Die haben andere Verstärkungsfaktoren. Die 2N360X sind mittlerweile da, werde ich entsprechend neu zusammenlöten. Und der 100nF Keramik kommt natürlich auch noch rein.
Matthias S. schrieb: > Falk B. schrieb: >>>Was mir aber auf jeden Fall auffällt, ist dass der Mittelwert mit jedem >>>Reset und auch nach ~10.000 Durchläufen im Bereich von +/- 10 um meinen >>>gedanklichen Mittelwert wandert. > > und die von mir geposteten Werte die du mit "zuviel Schwankungsbreite" > kommentiert hast, gehören zusammen! > Der Mittelwert bleibt im Verlauf stabil, erst nach einem Reset ändert > dieser sich um die +/-10. da ist was faul, warum sollten sich nach einem Reset des Arduino andere Werte ergeben!? Hast du mal die Messwerte roh ausgegeben? Nicht das an deinem Ringpuffer schon was faul ist. Was hast du als ARef verwendet? > Dazu: was ist gemeint mit "zuviel Schwankungsbreite"? Mit einem festen Spannungsteiler am Eingang sollte der Messwert nicht mehr als +/-1 schwanken. Sascha
Falk B. schrieb: > Man sollte nicht als erste Maßnahme zu Würg-Arounds und Schummeleien > greifen ... Willst du damit eine statistische Größe wie den Median als Schummelei bezeichnen? Die Berechnung vom Mittelwert ist ganz grob gesprochen nur sinnvoll, solange die Werte normalverteilt sind und die Verteilung durch die Stichprobe vernünftig repräsentiert wird. In allen anderen Fällen, wo irgendwelche Ausreißer auftreten, die eben in dies Normalverteilung nicht vernünftig reinpassen, ist genau der Median oft nicht der schlechteste Kennwert für die Stichprobe. Im Falle eines Sensor gebe ich dir natürlich Recht, dass man erstmal auf vernünftige Signalkonditionierung setzen sollte, bevor man mit statistischen Methoden drauf los geht.
Matthias S. schrieb: > Oder gibt es noch bessere und/oder effizientere Methoden? Ja, gibt es: 3-Sigma-Korrektur, ist üblich und wissenschaftlich abgesichert. Man berechnet die Standardabweichung. Folgen die Werte der Gauss'schen Normalverteilung, sind Werte, die sich um mehr als 3 x diese Standardabweichung vom Mittelwert unterscheiden so selten, dass sie in einer normalen Messserie nicht auftreten können. Daher eliminiert man diese als Messfehler. Das geht auch mehrfach: man hat danach ja eine neue Menge Messwerte, also kann man die 3-Sigma-Korrektur ein weiteres mal durch führen, und das solange bis keine Werte mehr herausfallen. Für Arduino-Basteleien ist das aber wohl totaler Overkill, so etwas macht man bei Messreihen in wissenschaftlichen Laboren. Georg
georg schrieb: > Für Arduino-Basteleien ist das aber wohl totaler Overkill, so etwas > macht man bei Messreihen in wissenschaftlichen Laboren. Wobei es dafür ne lib gibt: https://playground.arduino.cc/main/statistics In der tat sollte ein ADC aber nicht solche Schwankungen haben.
:
Bearbeitet durch User
Sascha W. schrieb: > da ist was faul, warum sollten sich nach einem Reset des Arduino andere > Werte ergeben!? > Hast du mal die Messwerte roh ausgegeben? Nicht das an deinem Ringpuffer > schon was faul ist. Was hast du als ARef verwendet? Das ist eine gute Frage. Ich habe jetzt mal den Sensordummy ohne den Optokoppler an den Arduino gehängt, als quasi 10 Ohm gegen GND + 120Ohm PullUp und damit zwei Läufe gemacht. Den Reset habe ich auch per Software durchgeführt (serielle Schnittstelle neu verbunden), damit ich ja nicht irgendwas verdrücke oder so. 1. Lauf: MAX 90, MIN 78, AVG 86 2. Lauf: MAX 106, MIN 97, AVG 102 Das Problem habe ich eigentlich auch irgendwie seit Anfang an. Noch bevor mein Ringbuffer drinnen war. Der Analoge Eingang verwende ich "Arduino-Standardmässig": ich mache im Code keine Einstellungen bezgl. der Refernzspannung und AREF bleibt auch offen: https://www.arduino.cc/en/Tutorial/AnalogReadSerial Wobei ich mich erinnere, dass wenn ich einen AVR verlötet habe, AREF auf VCC gelegt habe. Könnte das sogar schon die Lösung sein? Darf ich AREF auf VCC legen? Habe da immer im Hinterkopf, dass man da nicht allzuviel rumspielen sollte, da der AVR da gerne mal in die Binsen geht? Alex G. schrieb: > Wobei es dafür ne lib gibt: > https://playground.arduino.cc/main/statistics Die habe ich auch heute entdeckt. Interessant an der ist, dass die wohl kaum Werte speichert. Wäre somit deutlich RAM-sparender als mein "Ringbuffer", arbeitet dafür aber wohl durchgängig mit float, also eher CPU intensiv... Habe ich aber für morgen auf den Schirm die Lib mal anzutesten!
Matthias S. schrieb: > Wobei ich mich erinnere, dass wenn ich einen AVR verlötet habe, AREF auf > VCC gelegt habe. An ARef kommt ein Kondensator und sonst nichts. Alles andere steuerst du über die internen Register und Schalter - jedenfalls bei den ATmegas (siehe Datenblatt)
Bin da bis jetzt beim löten immer so vorgegangen: https://openhomeautomation.net/cdn/storage/Images/Zd9ZHBMtyKQuP7BDm/original/Zd9ZHBMtyKQuP7BDm.jpg Am Streckbrett bis jetzt immer offen gelassen, wie auch im Arduino Tutorial (weiter oben verlinkt) Wolfgang schrieb: > An ARef kommt ein Kondensator und sonst nichts. Wie groß? 100nF gegen VCC?
Wolfgang schrieb: > Falk B. schrieb: >> Man sollte nicht als erste Maßnahme zu Würg-Arounds >> und Schummeleien greifen ... > > Willst du damit eine statistische Größe wie den Median > als Schummelei bezeichnen? Natürlich -- denn in vorsichtig geschätzt 100% der Fälle, in denen hier nach Abhilfe für "Rauschen" gefragt wird, liegen determinierte Störungen vor, die zu systematischen Fehlern führen. Es handelt sich also gar nicht um Rauschen. Man ist hierbei wesentlich besser beraten, die Störungen zu beseitigen, statt die gestörten Ergebnisse schönzurechnen, da hat Falk schon Recht.
Matthias S. schrieb: > Wie groß? 100nF gegen VCC? Willst du dir jeden Spike, der auf VCC rumtanzt in die ADC-Referenz rüber holen? Die Größe passt, aber der gehört natürlich gegen Gnd. Das ist das Bezugspotential für deine Analogsignale.
@Matthias S. (da_user) >> Das ist Müll, denn so ein einfacher Optokoppler hat KEINE stabile >> Kennlinie, wenn man nix weiter macht. Du mißt damit eher die Temperatur >> als einen konstanten Wert. >Das ist kein einfacher Optokoppler. Der HCNR-201 ist für die Übertragung >von analogen Werten. Dann sollte man das auch dazu schreiben . . . >Davor hängt zwar schon jeweils ein günstiges China-Schaltreglerboard, >aber das dürften doch die Linearregler gut ausgleichen? Kann sein, muß nicht. >Der Mittelwert bleibt im Verlauf stabil, erst nach einem Reset ändert >dieser sich um die +/-10. Auch das ist komisch und darf nicht sein. Möglicherweise ist es aber ein Rechenfehler in deinem Programm, das einige Variablen nicht sauber initialisiert. >Dazu: was ist gemeint mit "zuviel Schwankungsbreite"? Wie schon von anderen geschrieben darf so ein ADC-Wert bei konstanter Eingangsspannung nur um +/-1 LSB wackeln. >Beim Sensorersatz will ich natürlich bei den Werten bleiben, die der >Sensor auch wirklich hat. 10k Poti scheidet somit aus. Nö, das kommt später. Du mußt erstmal herausfinden, wo das Wackeln herkommt. Dazu muß man eine systematische Fehlersuche betreiben und die Signalkette erstmal rigoros kürzen. Wenn es dann ohne Schwankungen läuft, kann man schrittweise wieder dazubauen. > Ich habe mir auf >einer Lochrasterplatine ein paar Widerstände und eine Stiftleiste >zusammengelötet. Mit einem Jumper kann ich dann die verschiedenen >Widerstände für die verschiedenen Drücke auswählen und aufschalten. Das >sollte schon relativ vernünftig herhalten. Sollte. > Der HCN-201 ist auch nicht >mehr auf einem Streckbrett zusammengefummelt, sondern auf einer >ordentlichen geätzten Platine. Was ich hier noch ändern müsste, sind die >passenden Transistoren. Die Beispielapplikation will 2N3906 und 2N3904, >die hatte ich aber nicht und bin deswegen auf BC557 und BC547 >ausgewichen. Die haben andere Verstärkungsfaktoren. Nebensächlich. >Und der 100nF Keramik kommt natürlich auch noch rein. VORSICHT! Wenn du einen aktiven Optokoppler hast, kann der NICHT einfach so 100nF am Ausgang treiben, da hast du gute Chancen, den zum Schwingen zu bringen. Da bracht es einen Entkopplungswidersand von vielleicht 1k oder so.
@Wolfgang (Gast) >> Man sollte nicht als erste Maßnahme zu Würg-Arounds und Schummeleien >> greifen ... >Willst du damit eine statistische Größe wie den Median als Schummelei >bezeichnen? Weil unter den genannten Laborbedingungen der ADC praktisch konstante Werte ohne nennenswerte Schwankung ausspucken muss. Eine Mittelwert-und Medianberechnung würde hier nur die Fehler und Störungen des Meßaufbaus betrachten, nicht die des Signals. >Im Falle eines Sensor gebe ich dir natürlich Recht, dass man erstmal auf >vernünftige Signalkonditionierung setzen sollte, bevor man mit >statistischen Methoden drauf los geht. Meine Rede.
@ Matthias S. (da_user) >Das ist eine gute Frage. Ich habe jetzt mal den Sensordummy ohne den >Optokoppler an den Arduino gehängt, als quasi 10 Ohm gegen GND + 120Ohm >PullUp und damit zwei Läufe gemacht. Den Reset habe ich auch per >Software durchgeführt (serielle Schnittstelle neu verbunden), damit ich >ja nicht irgendwas verdrücke oder so. >1. Lauf: MAX 90, MIN 78, AVG 86 >2. Lauf: MAX 106, MIN 97, AVG 102 Viel zuviel! >Der Analoge Eingang verwende ich "Arduino-Standardmässig": ich mache im >Code keine Einstellungen bezgl. der Refernzspannung und AREF bleibt auch >offen: https://www.arduino.cc/en/Tutorial/AnalogReadSerial Das darf nicht sein! Außerdem ist an AREF ein Kondensator dran. https://www.arduino.cc/en/uploads/Main/Arduino_Nano-Rev3.2-SCH.pdf >Wobei ich mich erinnere, dass wenn ich einen AVR verlötet habe, AREF auf >VCC gelegt habe. Könnte das sogar schon die Lösung sein? NEIN! > Darf ich AREF >auf VCC legen? NEIN!
@Matthias S. (da_user) >> An ARef kommt ein Kondensator und sonst nichts. >Wie groß? 100nF Ja. >gegen VCC? Nein, GND. Ist beim Nano aber schon vorhanden.
Falk B. schrieb: >>> Das ist Müll, denn so ein einfacher Optokoppler hat KEINE stabile >>> Kennlinie, wenn man nix weiter macht. Du mißt damit eher die Temperatur >>> als einen konstanten Wert. > >>Das ist kein einfacher Optokoppler. Der HCNR-201 ist für die Übertragung >>von analogen Werten. > > Dann sollte man das auch dazu schreiben . . . => Matthias S. schrieb: > Das ganze geht dann über einen analogen Optokoppler > (HCNR-201 mit der günstigeren Beispielbeschaltung) an den Analogpin. Falk B. schrieb: > Nö, das kommt später. Du mußt erstmal herausfinden, wo das Wackeln > herkommt. Dazu muß man eine systematische Fehlersuche betreiben und > die Signalkette erstmal rigoros kürzen. Wenn es dann ohne Schwankungen > läuft, kann man schrittweise wieder dazubauen. Stimmt. Dann werde ich mal sowohl meine Signalkette, wie auch mein Programm erstmal auf das Minimum runterkürzen. Falk B. schrieb: > VORSICHT! Wenn du einen aktiven Optokoppler hast, kann der NICHT einfach > so 100nF am Ausgang treiben, da hast du gute Chancen, den zum Schwingen > zu bringen. Da bracht es einen Entkopplungswidersand von vielleicht 1k > oder so. Wo muss dieser Entkopplungswiderstand hin? In Serie? PullUp/Down? Wobei ja hier schon gut was verbaut wäre: https://www.researchgate.net/profile/Constantinos_Kontogiannis/publication/287340190/figure/fig9/AS:325556680839176@1454630169818/HCNR200-basic-topology-for-voltage-optoisolation-The-voltage-signal-is-prior-limited-to.png
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.