Go Down

Topic: Gastank mit Schwimmer (Read 1 time) previous topic - next topic

KAmin

Hallo Forum,

ich habe folgendes:
Gastank mit Schwimmer, 1 Anzeige (Direkt am Tank) wie voll dieser noch ist, eine die Digital umgerechnet wird, und Widerstände für Voll-Mittel-Lehr.

Z.Z. gibt die Anzeige (Digital) 4 LED´s an. Heißt, wenn alle 4 LED´s an sind ist der Tank voll, 2 ist die häflte, und keine ist logischerweise Lehr :)
Da mir diese Anzeige zu ungenau ist, habe ich mir eine Anzeige gebaut (Arduino) die den Widerstand abgreift und auswertet in % und Balken.
Nur dieser Tank bewegt sich, so das es zu Schwankungen in der Prozentzahl sowie auch in den Balken gibt :( .
Die Zeit hab ich schon verändert aber das bringt mich nicht wirklich weiter.
Erst zeigt die Anzeige  z.B. 75 % an und nach 5 sec 34% und wieder 5sec. später 85% usw. .
Also dieses Schwanken geht mir auf den Keks. DAs einzige was ruhig bleibt ist der Analoge Zeiger vom Tank direkt. KA warum diese nicht schwank :(
Gibt es vllt. irgendeine Idee/Lösung die mir da aushelfen kann? Z.B. ein Algoritmus der innerhalb von z.B. 5 min. die Bewegungen aufzeichnet und davon z.B. die 3. höchste Zahl (von allen aufgezeichneteten) annimmt, die aber nicht über die alte Zahl die vor 5 min angezeigt wurde drüber hinaus kommt ? Hoffentlich konnte ich mich richtig ausdrücken.

Ich schaff das einfach nicht zu realisieren. so gut bin ich da nicht :(

Danke für Eure Mühe! :)

sth77

Ich würde annehmen, dass die Anzeige immer um den richtigen Mittelwert herumschwankt. Also musst du mehrere Messungen machen und eine Mittelwertbildung vornehmen. Man könnte bspw. ein Array in gewissen Zeitabständen befüllen und wenn ein neuer Messwert anliegt den ältesten Messwert rauskicken (FIFO-Prinzip).
Alternativ spricht auch nichts dagegen, das Signal vorab mit einem RC-Glied zu glätten - das spart zumindest Speicher im Arduino.
Mein Arduino-Blog: http://www.sth77.de/ - letzte Einträge: Teensy 3.0 - Teensyduino unter Window 7 - Teensyduino unter Windows 8

volvodani

Wie wäre es mit einem Integrator?
hier wäre einer
So ungefähr und das nur nach prüfung ob der neue Wert < Altwert ist,
Die Wert Variabelen müssen datatype long sein

Code: [Select]

Wertaktuell=analogRead(A0);       // Aktuellwert Einlesen
X=Wertneu*10;                         // Neuerwert nur 10% Einfluss auf den alten Diesen Einfluss dann
Y=Wertalt*90;                         // Wert aus dem Vorherigien Zyklus auf 90% diesen auch zusammen müssen 100% ereben
Wertneu=X+Y/100;                 // Beide Werte addieren und Neuen Wert Bilden
Wertalt=Wertneu;                 // Für den nächsten Zyklus ist der neue (aktueller gesmoother Wert)


Somit hat pro Lesezyklus der neue Wert nur 10% Einfluss dass heisst würde der neue Gelesene Wert 0 haben so hat der nur 10% Einfluss und würde den Wert in einem Zyklus um 10% nach unten korrigieren.
Damit kannst du eine schöne Smoothesfekt machen das heisst aussreise des Schwanken beeinflussen den Wert nur gering. Und du hängst auch nicht in einer for-Schleife im einem Programm fest. Wenn dein neu eingelesener Wert noch weniger einfluss haben soll dann die Multipiktoren auf 5/95 setzten soll der neue Wert mehr einfluss haben dann z.B. auf 20/80 setzten.

Gruß
Der Dani
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

KAmin

Hier mal mein jetziger Code mit Balkenanzeige und Prozentanzeige ;)
Wie binde ich das da jetz ein? weil soweit bin ich echt noch nicht um euch da voll folgen zu können. :(


Code: [Select]
    #include <LiquidCrystal.h>
    #include <LcdBarGraph.h>
     
    byte lcdNumCols = 16; // -- Anzahl der vollen Balken im LCD
    byte sensorPin = 1; // -- Analogeingang
     
    LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // -- Aufbau der LCD Verbindung
    LcdBarGraph lbg(&lcd, lcdNumCols);  // -- Aufbau der Balken
     
/////////////////////////////////////////////////////////////////////////////////////////////////   
   
    void setup(){

      analogReference (INTERNAL);   //  Interne Spannung 1,1 V DC am AREF Ausgang
      lcd.begin(2, lcdNumCols);   // -- Initialisierung des LCD
      lcd.clear();
      delay(1000);
    }
     
     
//////////////////////////////////////////////////////////////////////////////////////////////////     
    void loop()
    {

      lbg.drawValue( analogRead(sensorPin), 1024);   // -- Setzt den Wert vom Analogen Eingang
      delay(300);
         
         
int poti = analogRead(sensorPin);                  // Poti-Wert auslesen, max. Wert 1024
int potiVal = ((poti/4) * 100)/251;                // Potiwert in Prozent umrechnen
lcd.setCursor(0,1);                                // 0 = Zeile  ;  1 = Spalte
lcd.print("Tankinhalt");
lcd.setCursor(14,1);
lcd.print("%");
lcd.setCursor(11,1);
lcd.print(potiVal);
  if( potiVal < 100 )                               // Ist potiVal kleiner als 100 setze ein leerzeichen
  lcd.print( " " );
  if( potiVal < 10 )                                // Ist potiVal kleiner als 10 setze ein leerzeichen
  lcd.print( " " );

delay(300);
    }

mkl0815

Ungfähr so:
Code: [Select]

    #include <LiquidCrystal.h>
    #include <LcdBarGraph.h>
     
    byte lcdNumCols = 16; // -- Anzahl der vollen Balken im LCD
    byte sensorPin = 1; // -- Analogeingang

    long data = 0;

    LiquidCrystal lcd(8, 9, 4, 5, 6, 7); // -- Aufbau der LCD Verbindung
    LcdBarGraph lbg(&lcd, lcdNumCols);  // -- Aufbau der Balken
     
/////////////////////////////////////////////////////////////////////////////////////////////////   
   
    void setup(){

      analogReference (INTERNAL);   //  Interne Spannung 1,1 V DC am AREF Ausgang
      lcd.begin(2, lcdNumCols);   // -- Initialisierung des LCD
      lcd.clear();
      delay(1000);

      //einmal initialen Wert setzen, damit nicht bei "0" angefangen wird
      data = analogRead(sensorPin);
    }
     
     

//////////////////////////////////////////////////////////////////////////////////////////////////     
    void loop()
    {
      data = ((data * 90 ) + ( analogRead(sensorPin) * 10)) / 100;
     
      lbg.drawValue( data, 1024);   // -- Setzt den Wert vom Analogen Eingang
      delay(300);
         
      int potiVal = ((data/4) * 100)/251;                // Potiwert in Prozent umrechnen
lcd.setCursor(0,1);                                // 0 = Zeile  ;  1 = Spalte
lcd.print("Tankinhalt");
lcd.setCursor(14,1);
lcd.print("%");
lcd.setCursor(11,1);
lcd.print(potiVal);
  if( potiVal < 100 )                               // Ist potiVal kleiner als 100 setze ein leerzeichen
  lcd.print( " " );
  if( potiVal < 10 )                                // Ist potiVal kleiner als 10 setze ein leerzeichen
  lcd.print( " " );

delay(300);
    }


Ich habe zwei Dinge geändert. Zum Einen wird das Wert nur einmal je loop() eingelesen und dann immer nur der gelesene Wert verarbeitet. Das sollte man grundsätzlich so machen, damit man an allen Stellen mit dem gleichen Wert rechnet. Vor allem aber, wenn die gemessenen Werte stark schwanken. Als Zweites habe ich die Formel von volvodani eingebaut, allerdings etwas mehr zusammengefasst, um Variablen zu sparen.
Der Trick dieser Formel ist, das Du den neuen Wert nicht ausschliesslich aus dem gemessenen Wert nimmst, sondern den vorherigen Messwert auch mit verwendest.
Das macht die Formel:
Quote

data = ((data * 90 ) + ( analogRead(sensorPin) * 10)) / 100;

Ein Beispiel.

Angenommen "data" hat den Wert von 730 und mittels analogRead() werden aktuell 840 gemessen und im nächsten Durchlauf wieder nur 590 und dann wieder 710, dann hättest Du die stark schwankende Anzeige die Du jetzt hast.
Setzen wir nun mal die Wert in die Formel ein.

1. Wert:  730 (initiale Messung im setup())
2. Wert:  ((730 * 90) + (840 * 10)) / 100 = 741  ~ 72%
3. Wert:  ((741 * 90) + (590 * 10)) / 100 = 726  ~ 71%
4. Wert:  ((726 * 90) + (710 * 10)) / 100 = 724  ~ 71%

Nun das Ganze nochmal mit 95/5

1. Wert:  730 (initiale Messung im setup())
2. Wert:  ((730 * 95) + (840 * 5)) / 100 = 735  ~ 72%
3. Wert:  ((735 * 95) + (590 * 5)) / 100 = 728  ~ 71%
4. Wert:  ((728 * 95) + (710 * 5)) / 100 = 727  ~ 71%

Man sieht, die Werte schwanken noch weniger. Das Ganze klappt natürlich nur, wenn der eigentliche Messwert ohne Fehler sich nur sehr langsam ändert. Ich hoffe jetzt ist es etwas klarer.
Mario.

Go Up