Go Down

Topic: Poti-Werte nicht konstant (Read 2 times) previous topic - next topic

mazell

Hallo :) Ich habe jetzt einen Poti an meinen AnalogIn angeklemt und lese die Werte auf einem LCD aus. Mir ist aufgefallen dass die Werte permanent schwanken +-2. Wenn ich den Poti komplett runter drehe komme ich auf 0,1,2. Beim maximalen aufdrehen immer auf 1022,1023. Gibt es eine möglichkeit dies zu verhindern ?

LG

Robdeflop

Hi

Mir ist bis jetzt auch noch keine 100prozentige Lösung gekommen. Aber wenn du solch große Werte nicht unbedingt brauchst, kannst du diese auch auf niedrigere mappen. z.B.: "neuval = map(altval, 0, 1023, 0, 10);"
So wird dann in die variable neuval der wert von 0 bis 1023 auf 0 bis 10 "gemappt".
Oder versuch´s damit, den Durchschnittwert zu "errechnen". Also mehrmals den Wert auslesen, zusammenaddieren, und durch die anzahl wie oft du die werte genommen hast ;)

MFG, Robdeflop®

MaFu

Routine zum Glätten der Eingabe:
Code: [Select]
const int SMOOTH_FACTOR = 3;
...
wert = (wert - (wert >> SMOOTH_FACTOR)) + (analogRead(0) >> SMOOTH_FACTOR);
_______
Manfred

mazell

Perfekt! danke :) hier wird einem immer richtig gut geholfen!

LG
Pete

volvodani

Ich glätte immer mit
Code: [Select]

  Wertact=analogRead(A0);                     // Einlesen des Lambdaistwertes
  WertX=Wertact*100*0.2;                        // Filter neuer Lesewert mit 20% pro Zyklus
  WertY=Wertlast*100*0.8;
  Wertdis=(WertX+WertY)/100;
  Wertlast=Wertdis;
  return Wertdis;


Damit werden auch Ausreißer nicht so doll bewertet.


@MaFu
kannst du mir mal den Code erlautern ich komme mit dem Bitshift nicht klar. Bin interessiert meinen Code zu verbessern bzw genau zu verstehen
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

uwefed

Diese "Ungenauigkeit" ist fisiologisch.
Ich würde aber nicht den vorgeschlagenen Allogaritmus verwenden ( neuer Wert mit weniger Gewicht als die Alten) da so Änderungen des Sollwertes nicht sofort übernommen werden sondern sich der Wert erst langsam angleicht. Ich bevorzuge mehrere werte nacheinander zu lesen und dann den Mittelwert zu machen. Der vorteil ist daß eine Positionsännderung sofort wirksam wird. Die Werte können auch alle nacheinander gelesen werden. 5 bis 10 Werte genügen.

Viele Grüße Uwe

volvodani

#6
Feb 28, 2011, 07:13 pm Last Edit: Feb 28, 2011, 07:15 pm by volvodani Reason: 1
Hallo Uwe,
man überlege das dies Pro Zyklus passiert und das ist bei den Atmegas (vorausgesetzt du arbeitest ohne delays) bei einer Bewertung von 30% im Grunde eine Sofortige Auswirkung hat ohne das der einzelne Wert irgendwas kaputt macht. Bei 30% Einfluss ist eine 100%ige Änderung des Eingangsignals innerhalb 20 Zyklen erreicht bei einer Zykluszeit von 3-4ms ist diese in 60ms übernommen!
Dies ist eine gerne benutzter Algorithmus aus der SPS Technik. Da man unabhängig ist und wenn man eine schnellere Integration braucht ändern man den Einfluss des neuen Wertes :-)
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

uwefed

hallo volvodani
Es kommt darauf an, wie man den Wert mißt; kontinuierlich oder nur bei Bedarf.
Ich lese zB jede Minute einen analogen Wert und da ist ein Mittelwert von 10 aufeinander folgenden Messungen meiner Ansicht besser.
Wenn ich den Wert in einer Schleife kontinuierlich messe bringt mir den andere Alogaritmus Vorteile.
Grüße Uwe

mazell

So, ich habe jetzt alles aus diesem Thread ausprobiert und das Problem war immer noch da. Bei dem Beispiel von Volvodani hatte ich zwischendruch negative Werte etc.

Ich habe jetzt ein bisschen gepfuscht aber es funktioniert.
Code: [Select]

int ergebnis;
void lcdout(){
  lcd.setCursor(0,0);
  lcd.print("Sensor1:        "); //Kein Clear da das Display filimmert
  lcd.setCursor(0,0);
  lcd.print("Sensor1: ");
  lcd.print(ergebnis); 
}

void loop() {
  ergebnis = 0;
  for (int i = 0; i<5; i++){
    ergebnis = ergebnis + analogRead(A0);
  }
  ergebnis = (ergebnis*0.3+ergebnis*0.7)/50;   
  if (ergebnis ==101 || ergebnis == 102){
    ergebnis = 100;
  }     
  lcdout();
  delay(10);
}   


Ich habe jetzt konstante Werte zwischen 0 und 100.

MaFu

Quote
@MaFu
kannst du mir mal den Code erlautern ich komme mit dem Bitshift nicht klar. Bin interessiert meinen Code zu verbessern bzw genau zu verstehen


Bitshift eine Position nach rechts entspricht einer Division durch 2.
Bitshift eine Position nach links entspricht einer Multiplikation mit 2.

Gehen wir mal davon aus, "wert" wäre 40 und analogRead() liest 36.
wert = (wert - (wert >> SMOOTH_FACTOR)) + (analogRead(0) >> SMOOTH_FACTOR);
ist also
wert = (40 - (40 >> 3)) + (36 >> 3);
40 ist binär 00101000, >>3 schiebt 3 Positionen nach rechts: 00000101 = 5
36 ist binär 00100100, >>3 schiebt 3 Positionen nach rechts: 00000100 = 4
somit ergibt sich:
wert = (40 - (5)) + (4);
neuer Wert ist 39
_______
Manfred

volvodani

Echt ein schöner Integrations-Logarithmus vor allem so kompakt! Danke für deine Erläuterung im Grunde nichts anderes als mein Code nur in einer Zeile halt.
So ist das Leben:
Manchmal bis du das Denkmal, manchmal die Taube!

Udo Klein

Alternativ kann man auch das Rauschen absenken in dem man während der Messung den Prozessor schlafen legt. Im Datenblatt steht wie es geht. Ist aber deutlich aufwendiger als ein paar Mittelwerte zu bilden.
Check out my experiments http://blog.blinkenlight.net

Udo Klein

@Mafu: ich würde Dein Verfahren etwas anders implementieren:

Code: [Select]

const int SMOOTH_POWER = 3;
...
value = ((value << SMOOTH_POWER)  + (analog_read(0) - value))>> SMOOTH_POWER;


1) "POWER" statt "FACTOR" weil das ein Exponent und kein Faktor ist
2) Die niedrig signifikanten Bits werden nicht ignoriert sondern ebenfalls gemittelt.

Udo
Check out my experiments http://blog.blinkenlight.net

MaFu

@Udo

Wo Du recht hast, hast Du recht.
_______
Manfred

Udo Klein

Hehe, einmal in der Numerik Vorlesung nicht geschlafen und sich dann auch noch an "Auslöschung" erinnert ;)
Check out my experiments http://blog.blinkenlight.net

Go Up