Erklärung Tiefpassformel

Hallo zusammen!

Ich muss für mein Projekt drei Max6675-Sensoren für Temperaturmessung und drei Potis auslesen und würde gerne die Signale glätten um die Signale etwas stabiler zu bekommen!

Daher habe ich mich durch die Suche gewurstelt und eine interessante Formel ausgegraben die, so glaube ich, für meine Anwendung auch ganz gut in Frage käme!

Allerdings habe ich ein paar Fragen dazu da ich einiges nicht ganz verstehe!

Hier die Formel aus dem älteren Post von Guntherb:

void Filtern(float &FiltVal, int NewVal, int FF){
  FiltVal= ((FiltVal * FF) + NewVal) / (FF +1.0);  
}

Ich denke die Rechenformel habe ich verstanden allerdings beim Code habe ich Probleme!

Wieso ist im Parameterfeld &FiltVal und nicht Filtval?
Wenn der neu gemessene Wert ein float-Wert ist, kann dann in der Formel einfach int NewVal gegen float NewVal ausgetauscht werden?

Hier ist noch ein Beispielcode den ich nicht verstehe:

float Val;
int Eingangswert,j;

void setup() {  
  Serial.begin(115200);
  Serial.print("IN\t"); Serial.print("OUT\t\n"); 
}

void loop() {    
  Serial.print(Eingangswert); Serial.print("\t"); 
  Filtern(Val, Eingangswert, 100);
  Serial.print(Val); Serial.print("\t\n"); 
  if (j++ > 10) Eingangswert=1;  // nach 10 Werten Sprung auf 1  
}


/*************************************************************************************************
** Funktion Filtern()  by GuntherB								**
**************************************************************************************************
** Bildet einen Tiefpassfilter (RC-Glied) nach.							**
** FF = Filterfaktor;  Tau = FF / Aufruffrequenz						**
**  												**
**  												**
**  											   	**
**  Input: FiltVal der gefilterte Wert, NewVal der neue gelesene Wert; FF Filterfaktor		**
**  Output:	FiltVal										**
**  genutzte Globale Variablen: 	keine							**
**************************************************************************************************/
void Filtern(float &FiltVal, int NewVal, int FF){
  FiltVal= ((FiltVal * FF) + NewVal) / (FF +1.0);  
}

Was macht die Zeile int Eingangswert,j; bzw der Beistrich und das j hinter Eingangswert??
Welcher Wert wäre denn in diesem Code der gefilterte Wert den ich später weiterverarbeiten könnte?

Diese Zeile: if (j++ > 10) Eingangswert=1; // nach 10 Werten Sprung auf 1
Welcher Befehl bewirkt denn das hochzählen??
Und wieso soll der Eingangswert auf einmal 1 sein, sollte da nicht immer der aktuell gemessene Wert rein??

Ich hoffe ihr könnt ein wenig Licht ins Dunkel bringen!
Vielen Dank im voraus

& bedeutet dass eine Referenz ist. Du willst die Änderung ja schließlich außerhalb der Funktion mitbekommen

Wenn dir Referenzen fremd sind, du aber als alter C - Hase keine Angst vor Zeigern hast, sähe die Funktion so aus:

void Filtern(float *FiltVal, int NewVal, int FF){
  *FiltVal= ((*FiltVal * FF) + NewVal) / (FF + 1); 
}

…und müsste mit einem float* aufgerufen werden.

Zur andern Frage:
int Eingangswert,j; ist dasselbe wie

int Eingangswert; int j;

Hallo,

mit float **&**FiltVal wird eine Referenz deiner Mittelwert Variablen übergeben. Diese Variable behält den permanenten Mittelwert und wird in der Funktion direkt geändert. Du benötigst keinen Rückgabewert der Funktion und es gibt keine Kopie der Variable. Mit NewVal wird ein neuer Messwert übergeben. FF ist der Faktor wie stark der Filter wirken soll.

j**++** bedeutet j wird mit jeden Durchlauf inkrementiert, um genau eins.

Doc_Arduino:
j**++** bedeutet j wird mit jeden Durchlauf inkrementiert, um genau eins.

@Doc_Arduino: Wichtig: Nach der Verwendung (Postincrement).

@ michael_x: Seine Fragen lassen auf keinen alten C-Hasen schließen.

Gruß Tommy

du aber als alter C - Hase

:grinning: wenns denn so wäre, leider nur unerfahren und kompletter Anfänger

Hallo,

korrekt. :wink: Zur Vollständigkeit für den TO es gibt noch Prekrement **++**j, erst inkrementieren, danach wird es verwendet. Kann manchmal kriegsentscheidend sein.

Zur andern Frage:
int Eingangswert,j; ist dasselbe wie

int Eingangswert; int j;

Das heißt ich übergebe dem Integer gleichzeitig den Namen Eingangswert und j??

Wenn ich das richtig verstanden habe wäre mein gefilterter Wert den ich dann später im Programm aufrufen kann FiltVal!?

Wozu aber wird der Eingangswert in der Funktion nach 10 Werten auf 1 gesetzt??

Weil das nur ein errechneter Wert ist und kein wirklicher Messwert.

Da wird keinem int zugewiesen, sondern es werden die int Eingangswert und j angelegt.

Gruß Tommy

nein.
Du hast (neben anderen) zwei Variable, eine heißt Eingangswert, die andere j .

Beide sind vom Datentyp int.

Tommy56:
Weil das nur ein errechneter Wert ist und kein wirklicher Messwert.

Da wird keinem int zugewiesen, sondern es werden die int Eingangswert und j angelegt.

Gruß Tommy

Dem Eingangswert muss ich doch den ausgelesenen Wert vom Sensor zuweisen oder etwa nicht??
Ich glaube ich bin momentan komplett auf dem Holzweg

Schulz:
Dem Eingangswert muss ich doch den ausgelesenen Wert vom Sensor zuweisen oder etwa nicht??

Richtig.

In dem Beispiel wird aber kein echter Messwert benutzt, sondern einfach eine Zahl immer wieder hoch gezählt und zurückgesetzt.

Gruß Tommy

Schulz:
Dem Eingangswert muss ich doch den ausgelesenen Wert vom Sensor zuweisen oder etwa nicht??
Ich glaube ich bin momentan komplett auf dem Holzweg

Achso, ich dachte der Code sollte nur mit den Messwerten ergänzt werden und der Rest muss so stehen bleiben!

Also neuer Versuch, mal sehen ob ich es jetzt kapiert habe!
Sollte das etwa so passen??

#include "max6675.h"

int thermoDO = 43;
int thermoCS1 = 39;
int thermoCS2 = 40;
int thermoCS3 = 41;
int thermoCLK = 42;

MAX6675 thermocouple1(thermoCLK, thermoCS1, thermoDO);
MAX6675 thermocouple2(thermoCLK, thermoCS2, thermoDO);
MAX6675 thermocouple3(thermoCLK, thermoCS3, thermoDO);

float Eingangswert = 0;
float FiltVal = 0;

void setup() {

Serial.begin(9600);

}

void Filtern(float &FiltVal, float NewVal, float FF){
  FiltVal= ((FiltVal * FF) + NewVal) / (FF +1.0);
}

void loop() {

Eingangswert = thermocouple1.readCelsius();
Filtern(FiltVal, Eingangswert, 0.9);
Serial.println(FiltVal);




}

Das ist Unsinn:

Filtern(FiltVal, Eingangswert, 0.9);

Der letzte Wert ist die Anzahl der Werte, über die gefiltert werden soll. Da ist 0.9 Quatsch.

Gruß Tommy

Hallo,

der Filterfaktor FF ist int, also Ganzzahl, also nix mit 0.9. float macht keinen Sinn. Kleiner 1 macht auch keinen Sinn. Ansonsten klappt da so. Probiere es ab FF 10. Je höher der FF je mehr wird gefiltert aber je mehr "verzögert" die Reaktion.

Edit
mal wieder zeitliche Überschneidung

Tommy56:
Das ist Unsinn:

Filtern(FiltVal, Eingangswert, 0.9);

Der letzte Wert ist die Anzahl der Werte, über die gefiltert werden soll. Da ist 0.9 Quatsch.

Gruß Tommy

In der Beschreibung steht doch dass der letzte Wert der Filterfaktor ist?!!

Ja, über wieviele Werte gefiltert wird.

Gruß Tommy

Jetzt verstehe ich gar nix mehr…

In Post3 dieses Threads wird doch alles in float beschrieben

Hallo,

lies mal in aller Ruhe den gesamten Thread deines Links?
Welcher Anteil von welchen Wert geht in die Formel ein?
Was willst du mit einem Faktor von 0.9 erreichen?
Kleiner 1 kann man zwar filtern nennen, praktisch ist die Wirkung aber nahe 0.
Auf der anderen Seite kannste das jedoch alles selbst ausprobieren und dich nicht verrückt machen (lassen). :slight_smile:

Ich habe jetzt alles des öfteren durchgelesen, habe einiges falsch aufgefasst aber ich glaube es mittlerweile verstanden zu haben!

Habe da noch eine Frage wegen der K-Type Sensoren aber dafür werde ich wohl einen eigenen Thread eröffnen!

Vielen Dank für eure Aufklärung und vor allem eure Geduld!