Forum: Mikrocontroller und Digitale Elektronik Arduino-Programm für Tankanzeige. Tankfüllstandsmessung.


von Julian (Gast)


Lesenswert?

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
SSD1306AsciiAvrI2c oled;
5
#define I2C_ADDRESS 0x3C
6
7
int TankValue0;
8
int TankValue1;
9
10
void setup() {
11
 Serial.begin(9600);
12
 oled.begin(&Adafruit128x64, I2C_ADDRESS);
13
 oled.setFont(System5x7);
14
 oled.clear();
15
}
16
17
void loop() {
18
 int sensorTankValue0 = analogRead(A0);
19
 int sensorTankValue1 = 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.

: Bearbeitet durch Moderator
von Stefan B. (blueberlin)


Lesenswert?

Programmier eine Dämpfung....

Ermittel den Widerstand über 1 Minute und daraus den Mittelwert, das ist 
dann dein aktueller Tankinhalt.

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


Lesenswert?

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.

: Bearbeitet durch Moderator
von Udo S. (urschmitt)


Lesenswert?

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.

von Jemand (Gast)


Lesenswert?

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

von Schlaumaier (Gast)


Lesenswert?

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.

von donvido (Gast)


Lesenswert?

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.

von Julian (Gast)


Lesenswert?

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

von donvido (Gast)


Lesenswert?

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
>
> -----------------------------------

von Bernd (Gast)


Lesenswert?

Oder vielleicht ist auch sowas ausreichend:

actValue = actValue * 0,95 + measuredValue * 0,05

von nixundnul (Gast)


Lesenswert?

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.

von Schlaumaier (Gast)


Lesenswert?

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 ;)

von donvido (Gast)


Lesenswert?

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.

von Schlaumaier (Gast)


Lesenswert?

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. ;)

von Einer K. (Gast)


Angehängte Dateien:

Lesenswert?

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.

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


Lesenswert?

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.

: Bearbeitet durch Moderator
von Dymo Fond (Gast)


Lesenswert?

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.

von Einer K. (Gast)


Lesenswert?

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()

von Julian (Gast)


Lesenswert?

Herzlichen Dank.
Ich werds testen und Rückmeldung geben.
Bin dir sehr Dankbar!

von Crazy Harry (crazy_h)


Lesenswert?

Laß mich raten: Motorrad-Tank?

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.