außer, sein Arduino hat einen ARM Prozessor (Zero, Due), dann hat int von vornherein die Größe 32-bit. 8-)
außer, sein Arduino hat einen ARM Prozessor (Zero, Due), dann hat int von vornherein die Größe 32-bit. 8-)
Und noch ein Klassiker im Code:
Es ist wohl gemeint:Code:if(i = 255) { i=0; }
Dieser Fehler verursacht, dass i erstmal auf 255 gesetzt wird. Damit ist i ungleich null, somit der Ausdruck in der Klammer wahr, und der Code i=0 wird ausgeführt. i ist also nachher immer null.Code:if(i == 255) ...
Tipp:
Bei 256 Werten ein Byte als Typ benutzen. Wenn der Wert dann 255 ist und um eins erhöht wird, fängts automatisch wieder bei null an.
Erstmal vielen Dank für die Hilfe.
Das ist der fertige Code:
int werte[255];
int i,j = 0;
unsigned long summe;
void setup() {
Serial.begin(9600);
}
void loop() {
werte[i] = analogRead(0);
i++;
if(i == 255) {
i = 0;
}
delay(100);
durchschnitt();
}
void durchschnitt() {
summe = 0;
j = 0;
while(j < 255) {
summe += werte[j];
j++;
}
float schnitt = summe / 255;
Serial.println(schnitt);
}
Klappt alles wie es soll!
Nach 25,5 Sekunden wird dann der korrekte Mittelwert angezeigt.
Danke nochmal
TobiasE
warum delay(100) ? wenn das so sein muss, ok!
aber sonst: analogRead braucht nur ca. 1ms zum auslesen, und dafür wartet es von alleine!
- HaWe
- - - Aktualisiert - - -
ps
ein "gleitender Durchschnitt" geht aber anders ... und schneller.... und ganz ohne Arrays...!
ja, Ringpuffer ist natürlich perfekt und auch perfekt auf die Stichprobengröße angepasst.
Angenähert geht es aber auch mit dem gleitenden Mittelwert per Lowpass-Filter, damit bekommt man bis auf ein paar unerhebliche Nachkommastellen das gleiche Ergebnis:
float ETA=0.95; // ETA anfangs festlegen, ggf. noch justieren, kann auch bei 0.90 oder 0.99 liegen=> rumprobieren!
Mittelwert = ETA*(Messwert) + (1-ETA)*Mittelwert;
Dann spart man sich die extrem langsamen Array-Operationen und den Speicher dafür. Allerdings sind es dann nicht exakt 255 Werte, die gemittelt werden, sondern nur größenordnungsmäßig was in der Art.
Aber:
man kann ja auch die obige Formel benutzen, und dabei bis 255 zählen,
dann den Mittelwert ablesen,
und dann wieder neu starten.
Aber: er gleitet, mit minimalem Aufwand.![]()
Geändert von HaWe (01.03.2016 um 09:50 Uhr) Grund: blödsinnige Tippfehler
Die Frage ist, was man wirklich machen will. Meist geht es darum, ein verrauschtes Signal etwas zu glätten. In HW würde man da einen Tiefpass einsetzen. Irgendwie hat sich aber die Meinung verbreitet, ein gleitender Mittelwert wäre ein Tiefpass. Mir fiel bei einem Thread auf Mikrocontroller.net auf, das jemand den gleitenden Mittelwert als Kerbfilter für 50Hz Störungen einsetzt. Das ist dann sicher kein Tiefpass. An anderer Stelle hat dann der User Yalu X. aus ebendiesem Forum den Frequenzgang eines gleitenden Mittelwertes, nennt man wohl auch FIR Filter, zusammen mit dem Frequenzgang eines Tiefpasses, ein IIR Filter, geplottet. Hier das Bild:
Die rote Kurve ist der aus der Analogtechnik gut bekannte Tiefpass, die grüne der gleitende Mittelwert. Man erkennt dort deutlich das Kerbfilter zusammen mit einem Tiefpass.
Der gleitende Mittelwert hat auf jeden Fall zwei Nachteile: er kostet viel mehr Prozessorresourcesn, Speicher sowie Rechenzeit, und er verursacht, hier nicht dargestellt, Phasensprünge im Signal. Wenn man also das Kerbfilters nicht braucht, und das macht nur Sinn, wenn man die Abtastrate und Buffergröße genau an das Störsignal fester Frequenz anpasst, ist ein einfacher Tiefpass besser.
Die Rechnung eines Tiefpasses ist einfach, hier etwas Pseudocode:
Output = Oldvalue * n + Newvalue * (1 - n) // wobei n < 1
Oldvalue = Output
In Integerrechnung für n = 0,5 gehts noch einfacher
Output = (Oldvalue + Newvalue) / 2 // kann auch ein shift right werden
Oldvalue = Output
n zusammen mit der Abtastrate gibt die Grenzfrequenz des Tiefpasses an. Man muß bei der Integerrechnung nur darauf achten, daß beim Teilen nicht unten zuviele Bits verloren gehen. Man sollte also die Messwerte vorher nach oben im Bereich des Integers verschieben. Diese einfache Rechnung kann man leicht z.B. in der Auslesefunktion des ADC unterbringen.
MfG Klebwax
Strom fließt auch durch krumme Drähte !
Lesezeichen