www.mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Algorithmus für Tankanzeige mit Schwimmer


Autor: Loisl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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)

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Beitrag "Gleitender Mittelwert"

(auch wenn es dort eigentlich um einen exponentiellen Mittelwert geht 
und ich ziemlichen Unfug geschrieben habe, woher der Begriff 'gleitend' 
kommt)

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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!)
int main()
{
  float Average;
  float c = 1.0;

  Average = TankValue();

  while( 1 ) {

    Average anzeigen

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

    if( c > 0.06 )
      c = c - 0.05;

    _delay_ms( 100 );
  }

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)

Autor: Skua C:\> (skua)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Plausibilitätstest einbauen.
Wenn Zündung aus dann wird der Tank nur Voller (Tanken).
Wenn an dann nur langsam Leerer.

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Skua C:\> schrieb:
> Wenn Zündung aus dann wird der Tank nur Voller (Tanken).

nur wenn Du ein Tankschloß hast oder es nicht gerade nachts ist.

Gruß Anja

Autor: Andreas K. (derandi)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
...oder kein Loch im Tank ist. :-)

Schließe mich an: Am Anfang einmal Messen für aktuellen Inhalt und dann 
über eine längere Zeit Mitteln damit die Anzeige nicht pendelt wenn der 
Inhalt herumschwappt.

Früher hat man sowas mit nem Poti und einer Analoganzeige gemacht...

Autor: Anja (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Andreas K. schrieb:
> Früher hat man sowas mit nem Poti und einer Analoganzeige gemacht...

war aber ein Hitzdrahtinstrument das war seehr träge. Außerdem hattest 
Du immer einen anderen Tankinhalt je nachdem ob du das Licht 
eingeschaltet hattest oder die Heckscheibenheizung.

Gruß Anja

Autor: Karl Heinz (kbuchegg) (Moderator)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Läubi .. (laeubi) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Skua C:\> (skua)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
@Karl Heinz Buchegger
Das war nur als Zusatz gedacht um eben Ausreißer zu erkennen, und 
gegebenenfalls zu kompensieren.

Autor: Loisl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.
int main()
{
  float Average;
  float c = 1.0;

  Average = TankValue();

  while( 1 ) {

    Average anzeigen

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

    if( c > 0.06 )
      c = c - 0.05;

    _delay_ms( 100 );
  }
}

Autor: Loisl (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Zusatz:

Vielen Dank auch für den Hinweis und die Links zum Thema "gleitender 
Mittelwert", ich habe sehr viel dazugelernt.

Autor: G a s t (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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.

Autor: Loisl (Gast)
Datum:

Bewertung
0 lesenswert
nicht 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

Autor: asdfghjklöä# (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
nur so als idee - wie wärs mit einem beschleunigungs- und 
neigungs-sensor um die durchschnittsbildung zu beeinflussen?

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.