INFO: Dieses Forum nutzt Cookies...
Cookies sind für den Betrieb des Forums unverzichtbar. Mit der Nutzung des Forums erklärst Du dich damit einverstanden, dass wir Cookies verwenden.

Es wird in jedem Fall ein Cookie gesetzt um diesen Hinweis nicht mehr zu erhalten. Desweiteren setzen wir Google Adsense und Google Analytics ein.

Antwort schreiben 
 
Themabewertung:
  • 0 Bewertungen - 0 im Durchschnitt
  • 1
  • 2
  • 3
  • 4
  • 5
Analogwerte glätten
12.04.2015, 00:48 (Dieser Beitrag wurde zuletzt bearbeitet: 12.04.2015 00:51 von Wampo.)
Beitrag #9
RE: Analogwerte glätten
Dann bin ich ja jetzt froh das ihr euch einigen konntet...Wink

Das FiFo Prinzip von Kurti is soweit ganz gut hab damit kein Flackern mehr drauf, aber knnte man das nicht auch als ein Array schreiben aber so dass nicht nach 10 zählungen das array gelöscht wird sondern auch nach FiFo funktiniert.
Ich meine nur weil so wies jetzt geschrieben ist kann man schlecht mal irgendwann auf 100 messreihen zurückgreifen...

Welcher ansatz wäre da dann der richtige?
Gibt es denn eigentlich auch ne andere Methode um ein LDR Wert von 1-1023 an helligkeitswerte von 0-255 anzupassen ohne diese zu mappen.

Greez Wampo
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 07:55 (Dieser Beitrag wurde zuletzt bearbeitet: 12.04.2015 07:59 von Bitklopfer.)
Beitrag #10
RE: Analogwerte glätten
Moin,
@Wampo, ja das geht auch per Array. Habe das mal mit 20 Werten so gemacht. Ich poste einfach mal meinen Code. Beim auslesen hatte ich da noch Stufen eingefügt...aber die kann man ja weglassen.
Code:
//####################################################################
// Arduino ATtiny85 als Schalter fuer Flugzeug Positionslichter
// und Landescheinwerfer
// Pos.1  alles AUS
// Pos.2  Mittelstellung Positionslampen EIN
// Pos.3  Positionslampen und Landescheinwerfer EIN
// Bitklopfer 17.7.2014    
// V1      
// V2
// V3 mit Spannungsueberwachung
// PWM V1 Landescheinwerfer regelbar
//
//####################################################################


const byte rcpin = 4;         // RC Eingang
unsigned long int impdauer;   // in microsec
byte pwmll;                   // PWM Wert Landelicht
byte llflag = 0 ;                  // Landelichtflag
unsigned int pwmmittel;       // PWM Mittelwertbildung
unsigned int oldmittel;       // letzter Mittelwert
byte pwmarray[21];            // PWM Buffer
byte schreibi = 0;                // Index fuer Array
byte lesei;


const byte positionpin = 10;
const byte landelichtpin = 9;


void setup()
{
  Serial.begin(9600);
  pinMode(positionpin, OUTPUT);             // Configure as output and
  digitalWrite(positionpin, LOW);           // set to LOW
  pinMode(landelichtpin, OUTPUT);           // Configure as output and
  digitalWrite(landelichtpin, HIGH);         // set to LOW
  pinMode(rcpin, INPUT);        // RC Pin input
  digitalWrite(rcpin, HIGH);    // Pull Up einschalten  WIRD durch Pull Down R ersetzt

//######################### VCC Check
//analogReference(INTERNAL2V56);
  
}

void loop()
{
  impdauer = pulseIn(rcpin, HIGH,  30000);
  if (impdauer >= 2500 || impdauer <= 700) impdauer = 1000;
      {
      if (impdauer <= 1100)
           {
           digitalWrite(positionpin,0);
//           digitalWrite(landelichtpin,0);
           llflag = 0;
           }
  
      if (impdauer >= 1200)
           {  
           digitalWrite(positionpin,1);
           }

      if (impdauer < 1450){
           llflag = 0; // Landelicht ausschalten
           }
  
      if (impdauer >= 1520 && impdauer <= 2300)
           {
           digitalWrite(positionpin,1);
           llflag = 1;
           }
          
           if(llflag){
           if(impdauer >= 1950)impdauer = 1950;
           if(impdauer <= 1520)impdauer = 1522;
           pwmll = map(impdauer, 1520,1950,0,255);
           pwmarray[schreibi] = pwmll;
           schreibi++;
           if(schreibi == 20)schreibi = 0;
           pwmmittel = 0;
           for(lesei = 0; lesei != 20; lesei++){
             Serial.print(pwmarray[lesei]);
             Serial.print(" ");
           pwmmittel += pwmarray[lesei];
           }
           Serial.print(" ");
           Serial.print(pwmmittel);
           if(pwmmittel >= oldmittel)oldmittel = pwmmittel;
           if(pwmmittel < oldmittel)oldmittel -= 1;
           if(oldmittel >= 100){
                  if(pwmmittel < (oldmittel - 50))oldmittel -= 50;
                  }
           Serial.print(" ");
           Serial.println(oldmittel);
           pwmll = oldmittel / 20;
           analogWrite(landelichtpin, pwmll);
           }
          
           if(!llflag){
           oldmittel = 0;
           pwmarray[schreibi] = 0;
           schreibi++;
           if(schreibi >= 20)schreibi = 0;
           analogWrite(landelichtpin, 0);
           }
          
          
      }

}
Die Mittelwertbildung ist relativ einfach, das Array wird als Ringpuffer verwaltet und so werden die Werte nacheinander überschrieben. Bei der Mittelwertbildung werden einfach alle 20 Werte ausgelesen und durch 20 geteilt...fedisch.


Zu deiner Frage ohne zu mappen, klar das geht auch. Da der ADC 10Bit liefert und die PWM 8 Bit annimmt einfach durch 4 teilen weil das hier Linear ist. Übrigens der ADC liefert 0 - 1023...Wink
lg
bk

1+1 = 10 Angel ...und ich bin hier nicht der Suchmaschinen-Ersatz Dodgy...nur mal so als genereller Tipp..
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 09:04 (Dieser Beitrag wurde zuletzt bearbeitet: 12.04.2015 09:43 von HaWe.)
Beitrag #11
RE: Analogwerte glätten
wampo,
du WILLST es nicht verstehen, oder?
Dein arithmetischer FIFO-Array-Durchschnitt für 5 oder 10 ist Humbug, verglichen mit dem Tiefpassfilter!
Gerade WEIL er ein konfigurierbares gleitendes Langzeitgedächtnis hat.
Warum bist du so beratungsresistent?
Aber warum fragst du dann dauernd nach was neuem, wenn doch dein arithmetischer array-Durchschnitt angeblich so super funktioniert?
DASS er es aber tatsächlich nicht perfekt tut, wundert mich allerdings nicht!

Ein array als Speicher z.B. für die letzten 100 Werte macht nur dann Sinn, wenn du
a) jederzeit gezielt wissen können willst, wie der 3. oder der 91. oder der 48. Wert war, oder
b) wenn du einen Medianfilter implementieren willst.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 09:42
Beitrag #12
RE: Analogwerte glätten
Hallo zusammen,
habe mir mal so eure Standpunkte zu dem Thema durchgelesen und komme zu dem Schluss das es wohl an der Lage der Dinge liegt welche Vorgehensweise die nun geeignetere ist. Zum einen wird es wohl daurauf ankommen wie hoch die Abweichungen der Messwerte sind. Und wie lange ich mich an das Vergangene klammern will / muß.
Wenn man das mal aus dieser Perspektive betrachtet würde ich sagen das man es einfach mal ausprobieren muß welche Vorgehensweise für das anstehende Problem das geeignetere ist.
Ich für meinen Fall würde das mit dem FIFO wieder wählen weil die Abweichungen relativ gering sind und ich nach 20 Zyklen = 20 x 20mS eben eine neuen sicheren Wert habe.
lg
bk

1+1 = 10 Angel ...und ich bin hier nicht der Suchmaschinen-Ersatz Dodgy...nur mal so als genereller Tipp..
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 09:50 (Dieser Beitrag wurde zuletzt bearbeitet: 12.04.2015 10:09 von HaWe.)
Beitrag #13
RE: Analogwerte glätten
das ist völlig korrekt, man muss es testen.
Allerdings gibt es aus Sicht der Messtheorie so etwas wie einen "sicheren neuen Wert" nicht, sondern nur mehr oder weniger wahrscheinliche oder mehr oder weniger unsichere, daher muss JEDER Wert auf seine sog. "Reliablität" untersucht werden.
Vor allem muss man immer unwahrscheinliche Ausreißer eliminieren.
Je nach Stärke der Verrauschung (max. Streuung, Standardabweichung) muss man zu verschiedenen Methoden greifen.

Ich hatte bereits hier so einen Fall konstruiert:

http://www.arduinoforum.de/arduino-Threa...6#pid15446

Spiel das mal mit dem arithm Array-Mittel durch, und dann mit verschieden getuneten Tiefpassfiltern - und dann mit dem Medianfilter.

Ich wage die Prognose:
beim arithm Mittel wird der Ausreißer sehr lange den "wahrscheinlich echten" Wert völlig verfälschen (entspr. der Array-Länge).
beim Medianfilter wird der Ausreißer NIE in Erscheinung treten.
beim entspr. getuneten Tiefpassfilter wird er kurz das Ergebnis verzerren, dann aber zunehmend immer weniger und schließlich verblassen.

noch ein Beispiel:

stell dir vor, du misst einen Teppichboden für dein Zimmer aus.
Du misst 4x mit einem Zollstock deine Zimmerlänge,
3x exakt 6,00 meter
und 1x 5,00 Meter

Kaufst du dann den arithm Durchschnitt 5,75 oder 6meter ?

(hier hilft zum Besipiel nur ein Median)
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 21:16
Beitrag #14
RE: Analogwerte glätten
(12.04.2015 09:50)HaWe schrieb:  beim arithm Mittel wird der Ausreißer sehr lange den "wahrscheinlich echten" Wert völlig verfälschen (entspr. der Array-Länge).
beim Medianfilter wird der Ausreißer NIE in Erscheinung treten.
beim entspr. getuneten Tiefpassfilter wird er kurz das Ergebnis verzerren, dann aber zunehmend immer weniger und schließlich verblassen.
Hi,
meine Meinung dazu: Wenn man Restriktionen von wegen Speicherplatz und Geschwindigkeit hat, dann nimmt man die exponentielle Glättung ("Tiefpassfilter"). Ansonsten finde ich folgenden Algorithmus für die meisten Anwendungen am besten:

Merke Dir immer die letzten 10 Messwerte (oder auch 20, 100, ...).
Schmeiß die kleinsten und die größten 2 raus (oder auch 3, 4, 20,...).
Vom Rest nimm das arithmetische Mittel.

Damit haben Ausreißer gar keine Chance, das ganze passt sich an Änderungen meistens schnell genug an und es ist auch noch einfach zu verstehen.
(Ich weiß, dass das alles etwas einfach dargestellt ist. Die Statistik-Vorlesungen sind halt doch schon 25 Jahre her...)

Gruß,
Thorsten

Falls ich mit einer Antwort helfen konnte, wuerde ich mich freuen, ein paar Fotos oder auch ein kleines Filmchen des zugehoerigen Projekts zu sehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 21:28 (Dieser Beitrag wurde zuletzt bearbeitet: 12.04.2015 21:42 von HaWe.)
Beitrag #15
RE: Analogwerte glätten
klar, dann vereinst du damit den Medianfilter mit dem arithmetischen Mittel eines FIFO Arrays für die grenzwertbereinigten inneren Array.
Nennen wir sie Stufe (4).
Du darfst dann nur nicht vergessen, die Grenzen deiner Extreme richtig zu ziehen, z.B. bei +/- 2*sigma, von wo an du eliminierst.
(aber +/- 2*sigma von was? vom arithmetischen Mittel oder von Median? - da geht's schon wieder los...)
Das ist natürlich das Maximum des arithmetischen und statistischen Aufwandes.

Vom Aufwand her gehen dann da nur noch stochastische Filter drüber,
wie Stufe 5: der Kalman Filter (KF)
und Stufe 6: sequentielle Monte Carlo Methoden (SMC).

Von deiner Stufe (4) 1 Schritt zurück:
Stufe 3: der reine Median (von 3 oder 5).
Noch einmal ein Schritt zurück auf Stufe 2: der Tiefpass.
Noch eine zurück auf die am wenigsten reliable Stufe 1: das reine arithmetische Mittel.

Wir waren aber bereits bei Sufe 2 oder 3. Beide sind für Arduinos absolut adäquat (Im Gegensatz zum Extrem, der SMC, und mit Abstrichen, dem KF).

Und Stufe 2 ist einfacher, schneller, weniger aufwändig und weniger verzerrt als 1.
Also warum mit extrem wenig zufrieden geben, wenn man mit weit weniger Aufwand deutlich mehr haben kann?

8-)

Lassen wir's dabei.
Wer 's jetzt noch nicht verstanden hat, wird es nie verstehen.
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
12.04.2015, 21:36 (Dieser Beitrag wurde zuletzt bearbeitet: 12.04.2015 21:39 von Bitklopfer.)
Beitrag #16
RE: Analogwerte glätten
Hi Kurti,
mein Kompliment, du schiebst wirklich die Daten im FIFO nach hinten....da mußte ich erst 3 mal draufkucken um das zu kapieren (und das nach nem großen Wodka*) was du da treibst....WEIL ich hab mir das Daten shiften erspart und einfach den Index vom Array erhöht was im Endeffekt aufs gleiche rauskommt. ABER, dein Code funzt...läuft hier auf meinem Azu-Duino PERFEKT. Habe da noch ne Serielle Ausgabe dazugemacht um die Werte zu visualisieren...
Wer es nachkucken will, hier mein ergänzter Code:
Code:
//Arduino FIFO
const int FIFO_Anzahl = 10;  // Anzahl der FIFO-Speicherplätze
int FIFO[FIFO_Anzahl];       // Array definieren
int Analogwert = 0;          // gemittelteter Analogwert


void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);

}

void loop() {

  // FIFO-Puffer Inhalte weiterruecken
  for (int i = FIFO_Anzahl-1; i > 0; i = i - 1) {
    FIFO[i] = FIFO[i - 1];
  }
  FIFO[0] = analogRead(A3);    // Analogwert an erste Stelle des FIFO schreiben
  Analogwert = 0;              // gemittelten Analogwert auf 0 setzen

  // FIFO-Puffer Inhalte addieren
  for (int i = 0; i < FIFO_Anzahl; i = i + 1) {
   Serial.print(FIFO[i]);
   Serial.print(" ");
    Analogwert = Analogwert + FIFO[i];
  }
  Analogwert = Analogwert / FIFO_Anzahl; // gemittelten Analogwert errechnen
   Serial.print("   ");
   Serial.print(Analogwert);
Serial.println();
delay(2000);
}
P.S. bei A3 hängt bei mir eine Fotodiode dran mit der ich leicht sich ändernde ADC Werte generieren kann.

* = ich bin kein heimlicher Alki...ich trinke öffentlich...TongueTongueTongue

lg
bk

(12.04.2015 21:16)Thorsten Pferdekämper schrieb:  .....
(Ich weiß, dass das alles etwas einfach dargestellt ist. Die Statistik-Vorlesungen sind halt doch schon 25 Jahre her...)

Gruß,
Thorsten

...drum traue keiner Statistik die du nicht selber gefälscht hast...Big Grin alte Weisheit...lach
lg
bk

1+1 = 10 Angel ...und ich bin hier nicht der Suchmaschinen-Ersatz Dodgy...nur mal so als genereller Tipp..
Alle Beiträge dieses Benutzers finden
Diese Nachricht in einer Antwort zitieren
Antwort schreiben 


Möglicherweise verwandte Themen...
Thema: Verfasser Antworten: Ansichten: Letzter Beitrag
  Analogwerte einlesen kendrick 10 2.550 03.01.2015 20:27
Letzter Beitrag: Bitklopfer
  PWM glätten Cray-1 0 725 07.12.2014 19:07
Letzter Beitrag: Cray-1

Gehe zu:


Benutzer, die gerade dieses Thema anschauen: 1 Gast/Gäste