Hi zusammen,
leider bin Ich nicht so ganz bewandert mit dem Thema Programmieren..
Stell hier einfach mal das Programm ein:
1
#include"SSD1306Ascii.h"
2
#include"SSD1306AsciiAvrI2c.h"
3
4
SSD1306AsciiAvrI2coled;
5
#define I2C_ADDRESS 0x3C
6
7
intTankValue0;
8
intTankValue1;
9
10
voidsetup(){
11
Serial.begin(9600);
12
oled.begin(&Adafruit128x64,I2C_ADDRESS);
13
oled.setFont(System5x7);
14
oled.clear();
15
}
16
17
voidloop(){
18
intsensorTankValue0=analogRead(A0);
19
intsensorTankValue1=analogRead(A1);
20
TankValue0=map(sensorTankValue0,295,785,0,100);
21
TankValue1=map(sensorTankValue1,295,785,0,100);
22
if(TankValue0<0){
23
TankValue0=0;
24
}
25
if(TankValue1<0){
26
TankValue1=0;
27
}
28
if(TankValue0>100){
29
TankValue0=100;
30
}
31
if(TankValue1>100){
32
TankValue1=100;
33
}
34
oled.print("T0=");
35
oled.print(TankValue0);
36
oled.println(" ");
37
oled.print("T1=");
38
oled.print(TankValue1);
39
oled.println(" ");
40
oled.setCursor(0,0);
41
}
Nun mein Problem.
Es handelt sich um eine Tankanzeige. Über einen Sensor (Schwimmkontakt)
der seinen Widerstand von 30...230 Ohm ändert, wird der Füllstand an A0
und A1 gegeben. Wie man sich vorstellen kann, wird der Füllstand immer
schwanken, sobald sich das Wasser bewegt. Ich würde gerne eine Mittelung
einbauen, dass der Wert nicht sekündlich schwankt.. Kann mir wer das
Programm entsprechend anpassen?
Danke schonmal im Vorraus.
Stefan B. schrieb:> Programmier eine Dämpfung....
Besser bekannt als "Tiefpassfilter" oder "Mittelwertfilter":
1. mach 1 Messung pro Sekunde
2. addiere die Messwerte von 100 Messungen
3. teile diese Summe durch 100
So bekommst du alle anderthalb Minuten einen "beruhigten" Wert.
Dieses Vefahren kann man jetzt natürlich noch optimieren, indem die
Messwerte zwischengespeichert werden und immer der älteste Wert durch
den neuen Wert überschrieben wird. Aber für einen Tanksensor dürfte eine
Updatefrequenz von anderthalb Minuten locker ausreichen.
Lothar M. schrieb:> 1. mach 1 Messung pro Sekunde> 2. addiere die Messwerte von 100 Messungen> 3. teile diese Summe durch 100
4. Solange man beim Starten noch keine 100 Messwerte hat:
Summiere die vorhandenden Messwerte und teile durch die Anzahl.
Man will ja nicht fast 2 Minuten warten bis man eine erste Anzeige hat.
Hallo
Lothar M. schrieb:> Dieses Vefahren kann man jetzt natürlich noch optimieren, indem die> Messwerte zwischengespeichert werden und immer der älteste Wert durch> den neuen Wert überschrieben wird. Aber für einen Tanksensor dürfte eine> Updatefrequenz von anderthalb Minuten locker ausreichen.
Auch als stiller Mitleser ein großes Danke für die Idee.
Aber wie geht man erstmal generell an so ein Mittlungsproblem (Glättung,
Beruhigung...)heran und wie dann im jeweiligen Einzelfall?
Was ist wichtig (sicherlich die Messdatenfrequenz, aber wohl auch noch
so einiges mehr)- wie erkenne ich das überhaupt, woher weis ich welche
Mathematik ich anwenden muss?
Wie finde ich heraus wie die Messwerte abhängig von der jeweiligen
Messaufgabe und Messfrequenz optimal gemittelt werden sollten und vor
allem wann eine einfache Mittlung ("Mathe 6 Klasse") nicht ausreicht -
und vor allem welche ergänzenden Mittlungsverfahren man dann nutzen
"muss"?
Die Regelungstechnik und vor allem Mathematik hat wohl auch was damit zu
tun (PID...)?
Trotz 1001 Erklärungen die man so findet und die oft gar nicht so
schlecht sind hat es bei mir immer noch nicht "Klick" gemacht wie man
Mathematisch (Eben kein reines Trail and Error mittels Anleitungen die
"einfach" sagen wenn dies und das bei den entsprechenden Objekt -Teil,
Motor, Multikopter,...- auftritt muss man den P bzw. I bzw. D Anteil in
eine bestimmte Richtung verändern) die Sache zumindest schon mal
theoretisch soweit berechnet das nur noch wenige Anpassungen (trail and
error?) notwendig sind.
Auch fehlt mir "das Bauchgefühl" zu diesen ganzen Gebiet.
Jemand
in Basic
Anzahl = 10
summe = 0
for i = 1 to Anzahl
summe = summe + _gemessenen_wert
next i
Real_wert = summe / Anzahl
-----------------------------------
Das musst du nur noch in Arduino-C umwandeln ;)
Sollte man bei so schwankenden Sensoren eh immer machen. Ich setze so
eine Routine bei Temp-Messungen ein. So wird man auch
Fehlinterpretationen eines Sensors los.
Jemand schrieb:> die Idee
schimpft sich gleitender Mittelwert und ist nichts neues.
Jemand schrieb:> Aber wie geht man erstmal generell an so ein Mittlungsproblem (Glättung,> Beruhigung...)heran und wie dann im jeweiligen Einzelfall?
Bei einer Tiefpassfilterung (Mittelwert, PT1, PTn) sind zunächst einmal
die Abtastrate und die höchsten im Signal auftretenden Frequenzen von
Interesse. Wenn man Aliasing vermeiden möchte, (hohe Frequenzen können
das abgetastete Signal verfälschen und als niedrige Frequenzen
erscheinen) sollte die halbe Abtastrate höher sein, als die höchste
Frequenz im Signal (Nyquist-Theorem).
Die nächste Frage wäre dann, was man mit dem Signal anstellen will und
was für Störsignale rausgefiltert werden müssen. Dementsprechend wählt
man dann einen Filter mit einer entsprechenden Dämpfung.
Jemand schrieb:> Die Regelungstechnik und vor allem Mathematik hat wohl auch was damit zu> tun (PID...)?
Da ein Tiefpassfilter immer (außer bei Zero-phase filtering, was nur
offline angewendet werden kann) mit einer Phasenverschiebung
(Signalverzögerung) einhergeht, hat er auch immer Auswirkung auf ein
geregeltes System (Rückführung) und muss entsprechend berücksichtigt
werden.
Danke schonmal für die Antworten.
Kann mir jemand das Programm anpassen?
Wie gesagt, bin nicht sehr begabt in dem Thema und gerade dabei es zu
lernen..
Wäre euch sehr dankbar!
Gruß Julian
Julian schrieb:> Kann mir jemand das Programm anpassen?
Ich fürchte das wird hier nicht passieren.
Zumal du schon ein ganz gutes Beispiel bekommen hast.
Schlaumaier schrieb:> in Basic>> Anzahl = 10> summe = 0> for i = 1 to Anzahl> summe = summe + _gemessene_werte(i)> next i>> Real_wert = summe / Anzahl>> -----------------------------------
Kommt drauf an, wie feinfühlig der Parameter eingestellt werden soll und
welche Arbeitsgeschwindigkeiten gebraucht werden (scheint hier nicht das
Problem zu sein)
Letztlich ist es eine T1-Verzögerung für den Regeltechniker.
Ein kleiner Controller freut sich eher über das:
xxx = xxx - ( xxx >> 4 ) + messwert;
ergebnis = xxx >> 4;
wobei das 16 Stufen entspricht. Beachte, daß xxx größeren Wertebereich
(mehr Bit) benötigt.
donvido schrieb:> Schlaumaier schrieb:>> in Basic>>>> Anzahl = 10>> summe = 0>> for i = 1 to Anzahl>> summe = summe + _gemessene_werte(i)>> next i>>>> Real_wert = summe / Anzahl>>>> -----------------------------------
Du brauchst nur ein arry wenn du die werte VORHER liest
In meinen Beispiel lese ich DIREKT.
Man kann noch ein DELAY 500 (bis 1000) dazwischen machen.
Einfach gesagt in der Schleife wird der Sensor 10 x abgefragt und die
Ergebnisse zusammen gerechnet. Danach teile ich die summe durch die
Anzahl der Messungen und erhalten den Durchschnittswert.
Das ist Mathematik für Kiddys von 9 Jahren via Software.
Ach und warum in Basic. Ich programmiere die Arduino's nur in Basic
(b4R) deshalb. Mich mach C mit seinen Klammern wahnsinnig ;)
Schlaumaier schrieb:> Du brauchst nur ein arry wenn du die werte VORHER liest>> In meinen Beispiel lese ich DIREKT.
Dann solltest du aber auch klar machen, dass
1
_gemessenen_wert
eine Funktion ist, die den aktuell gemessenen ADC-Wert zurückgibt.
donvido schrieb:> Dann solltest du aber auch klar machen, dass_gemessenen_wert> eine Funktion ist, die den aktuell gemessenen ADC-Wert zurückgibt.
Man kann es als Aufruf einer Funktion oder als Aufruf einer Abfrage
sehen (welche nur intern einen Funktion ist). Etwas mitdenken sollte
man schon vom TO erwarten.
Eigentlich kommt es doch auf den Sensor an. Wenn ich ihn direkt abfragen
kann, durch eine Funktion der Libray wäre gemessener_wert halt dieser
Funktion selbst.
Kann ich es nicht (einige Sensoren brauchen mehr als eine Zeile, bzw
Aufruf) so rufe ich die Funktion auf, und erhalte das Ergebnis.
Um es aber den TO nicht zu kompliziert zu machen habe ich das einfach
als "Ergebnis" betrachtet. Es bleibt also den TO überlassen wie er an
den Wert des Sensors kommt.
ABER. Bei einen Array müsste er die 10 Werte (im Beispiel) vorher messen
und Speichern. Das ist unnötiger Speicherplatzverbrauch und mehr
Aufwand.
Ich lege nur dann Array an, wenn ich dadurch Speicherplatz spare. ;)
Schlaumaier schrieb:> Das musst du nur noch in Arduino-C umwandeln ;)
Oder in C++ ;-)
Julian schrieb:> Danke schonmal für die Antworten.> Kann mir jemand das Programm anpassen?> Wie gesagt, bin nicht sehr begabt in dem Thema und gerade dabei es zu> lernen..
Ausnahmsweise.
Nur weiß ich nicht, ob du dadurch viel lernst....
Denn eigentlich heißt der Spruch ja:
> Wir lernen, indem wir es tun!
PS:
Das Programm ist völlig ungetestet, da mir dieses Display fremd ist.
Zudem, auf Grund der float Geschichte nicht sonderlich
performant/effektiv.
Aber das sollte hier egal sein.
Ich würde ein RC-Glied nachbilden:
http://www.lothar-miller.de/s9y/categories/21-Filter
Das braucht nur ein Summenregister und kann einfach auf einen
Anfangswert gesetzt werden. Udn wenn man es halbwegs schlau macht, dann
braucht man nichtmal eine Fließkommaoperation dafür...
Arduino Fanboy D. schrieb:> Zudem, auf Grund der float Geschichte nicht sonderlich> performant/effektiv.> Aber das sollte hier egal sein.
Wenn man weiß, woher der Rechenzeitverbrauch kommt und dass man es
besser machen könnte...
Aber i.A. sind für mich ".0" auf einem 8-Bit-µC ohne FP-Unit und das
unterbrechende Warten in der Mainloop mit "delay()" eindeutige Signale
dafür, dass da sonst noch irgendwo Fehler im Code sind.
Schlaumaier schrieb:> Man kann noch ein DELAY 500 (bis 1000) dazwischen machen.
Man muss es "irgendwie" schaffen, zwischen die Messwerte den
angesprochenen Sekundenabstand zu bringen. Ein delay() ist gerade mal
gut genug für die erste Bastelei.
Jemand schrieb:> Aber wie geht man erstmal generell an so ein Mittlungsproblem (Glättung,> Beruhigung...)heran und wie dann im jeweiligen Einzelfall?
...
> Die Regelungstechnik und vor allem Mathematik hat wohl auch was damit zu> tun (PID...)?
Was willst du regeln? Bisher ist erst einmal nur die Rede von Messen.
> Trotz 1001 Erklärungen die man so findet und die oft gar nicht so> schlecht sind hat es bei mir immer noch nicht "Klick" gemacht wie man> Mathematisch
Ja, man kann da ein großes mathematisches Fass aufmachen. Angefangen vom
Erfassen der Messwerte = Nicht-ideale Abtastung, (vermutlich
Unterabtastung) und Digitalisierung, über mechanische, analoge und
digitale Filter bis hin zu neuronalen Netzen und KI. Wer mag kann auch
noch die Tankbeschleunigung messen und Wellenbewegungen anhand der
Eigenschaften der Flüssigkeit im Tank vorhersagen. Das Verhalten der
Flüssigkeit beim Betanken ist sicher auch interessant. Vielleicht noch
ein bisschen Fuzzylogik ...
Zum Schluss kommt es auf die Anwendung an. Wenn es reicht einen
laufenden Mittelwert aus x Werten zu bilden ist's auch gut und man
schenkt sich die Mathematik. Gut genug ist gut genug.
Lothar M. schrieb:> Ein delay() ist gerade mal> gut genug für die erste Bastelei.
Wenn Nebenläufigkeiten benötigt werden, steht es etwas im Wege rum.
Aber ein Trost hat man ja....
Es gibt 2 weitere Leben neben delay()
Einmal Interrupts und zum zweiten yield()