Algorithmus für Tankanzeige mit Schwimmer

Gast #2089290
Lesenswert?

Hallo,

ich brauche Hilfe bei der mathematischen Auswertung eines Gebersignals.

Und zwar soll der Füllstand eines Fahrzeugtanks auf einem Display 
angezeigt werden. Der eingebaute Tanksensor ist ein Hebelarmgeber (Poti) 
mit Schwimmer, das muss leider auch so bleiben.

Ich versuche nun schon seit einigen Stunden das Gebersignal über die 
Zeit zu mitteln, kam aber bisher zu keinem befriedigenden Ergebnis. Der 
Wert der Tankanzeige reagiert entweder zu ruckartig oder verhält sich 
anders unangebracht. Z.B. braucht die Anzeige anfangs zu lang um einen 
Wert anzuzeigen oder ähnliches.

Bisher basierten meine Versuche in etwa auf folgendem Schema:

Bei Timer-Interrupt nach 1000ms
{
  zähler = zähler + 1
  pegelsumme = pegelsumme + aktuellGemessenerPegelwert
  Wenn Zähler = 30{
  {
     anzuzeigenderPegelwert = pegelsumme / 30
     zähler = 0
     pegelsumme = 0
  }
}

Hat jemand Erfahrung aus der Praxis mit so etwas oder vielleicht einen 
Tipp wie man das vernünftig löst?

Wie machen das die Profis?

Danke im voraus,
Loisl
#2089308
Lesenswert?

Loisl schrieb:

> anders unangebracht. Z.B. braucht die Anzeige anfangs zu lang um einen
> Wert anzuzeigen oder ähnliches.


kein Wunder.
Dein erstes Ergebnis kriegst du nach 30 Messperioden von denen jede 1 
Sekunde lang ist.

> Hat jemand Erfahrung aus der Praxis mit so etwas oder vielleicht einen
> Tipp wie man das vernünftig löst?

gleitenden Mittelwert
(danach kann man googlen)
Gast #2089429
Lesenswert?

Loisl schrieb:
> Wie machen das die Profis?

Ein paar Ideen hätte ich da schon:

- Kleine Filterzeitkonstante (wenige Messwerte alle 100ms mitteln) wenn 
das Fahrzeug Steht. (also Zündung an und der Motor läuft noch nicht).

- Einfrieren des Wertes bei starker Beschleunigung (viel Gas), bei 
Bremsleuchte an oder bei großem Lenkwinkeleinschlag (Lenkwinkelsensor).

- Ansonsten große Filterzeitkonstante.

Gruß Anja
#2089442
Lesenswert?

Filterzeitkonstante nach dem Anlegen derVersorgungsspannung sukzessive 
anwachsen lassen.
Nach dem 'Zündung ein' steht ja das Fahrzeug normalerweise, d.h. da ist 
noch nicht mit großen Schwankungen durch Beschleunigungen zu rechnen. In 
den Sekunden bis zum wegfahren, wird die Filterzeitkonstante sukzessive 
erhöht: Unmittelbar nach dem Einschalten geht die Anzeige schnell auf 
den aktuellen Tankwert und wird dann in den nächsten Sekunden immer 
träger.

Damit würde ich mal mein Glück versuchen.


Ohne Rücksicht auf Verluste (Achtung: Floating Point!)
1
int main()
2
{
3
  float Average;
4
  float c = 1.0;
5

6
  Average = TankValue();
7

8
  while( 1 ) {
9

10
    Average anzeigen
11

12
    Avrage = ( 1.0 - c ) * Average + c * TankValue();
13

14
    if( c > 0.06 )
15
      c = c - 0.05;
16

17
    _delay_ms( 100 );
18
  }

Wie sinnvoll die Zahlenwerte sind, müsste man ausprobieren. Ich hab 
einfach mal aus dem Bauch heraus ein paar Werte angenommen.
(TankValue ist eine hypothetische Funktion, die den ADC ausliest)
#2089492
Lesenswert?

Skua C:\> schrieb:
> Plausibilitätstest einbauen.
> Wenn Zündung aus dann wird der Tank nur Voller (Tanken).
> Wenn an dann nur langsam Leerer.

Keine gute Idee

Fährt man bergab (bergauf, je nach Geber) dann zeigt die Anzeige zu 
wenig an. Mit deiner Heuristik verhinderst du, dass sich die Anzeige 
danach auf ebener Strecke wieder auf den korrekten Wert einstellt.
Persönliche Seite #2089660
Lesenswert?

Ich habe das mal über einen gewichteten Mittelwert (in Assembler) 
gemacht.

Man nimmt sich ein Array aus z.B. 5 Werten.

1) Messwert aufnehmen
2) array[4] = array[3] / 2
3) array[3] = array[2] / 2
4) array[2] = array[1] / 2
5) array[1] = array[0] / 2
6) array[0] = Meßwert
7) Anzuzeigender Wert = summe(array[0..4]) / 5

Funktionierte ganz gut, und da der Messwert meist eh als byte vorliegt 
ist die Division ein einfacher shift nach rechts.

Durch die Zeitliche Komponente hat man dann auch eine ganz gute 
Dämpfung, trotzdem passt sich das Signal recht schnell an Änderungen an.
Gast #2090481
Lesenswert?

Vielen Dank für die Tipps!

Ich habe den auf den ersten Blick simpel erscheinenden unten stehenden 
Code von Karl-Heinz Buchegger in Excel mit ein paar simulierten Daten 
durchgespielt und muss sagen: Es ist eine effiziente und geniale Lösung 
für mein anfangs beschriebenes Problem!

Bin mal gespannt was die Tests unter realen Bedingungen ergeben.
1
int main()
2
{
3
  float Average;
4
  float c = 1.0;
5

6
  Average = TankValue();
7

8
  while( 1 ) {
9

10
    Average anzeigen
11

12
    Average = ( 1.0 - c ) * Average + c * TankValue();
13

14
    if( c > 0.06 )
15
      c = c - 0.05;
16

17
    _delay_ms( 100 );
18
  }
19
}
Gast #2090490
Lesenswert?

Wie wäre es mit einer Verwendung des Medianwertes aus einer Serie von 
Messungen? Der reagieren nicht auf Ausreißer. Die Länge der Messserie 
muß dann nur etwas länger als die "Schwapp"-Zeit sein.
Gast #2098529
Lesenswert?

Soooo, nun hab ich Karl-Heinz Bucheggers Codevorschlag mal am Fahrzeug 
getestet.

Es funktioniert super, wie erwartet. Damit die Tankanzeige noch etwas 
träger auf "Schwappvorgänge" reagiert, habe ich die Konstante noch von 
5% auf 1% heruntergesetzt. Die Anzeige reagiert zwar immernoch auf lange 
Kurven, aber das könnte man auch noch mit Feintuning der Parameter (z.B. 
Zeitfaktor vergrößern, Konstante auf 0,5%) in den Griff bekommen.

Wünsche euch allen ein schönes Wochenende.
Liebe Grüße, Loisl

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren