PT1-Filter in C

OP #2757963
Lesenswert?

Nabend an alle Forum nutzer,

ich möchte einen Filter in einem PIC mikrocontroller in C-Programmieren.

Das „Ergebnis“ der AD-Wandler(10-Bit) möchte ich in das PT1-Filter 
schicken(weil bei Temperaturunterschied das „Ergebnis“ sich Automatisch 
verändert) und dann mit einem „Wert(z.B Dez. 550)“ vergleichen. Das 
„Ergebnis“ (bzw. die Spannung am Analogeingang, z.B Dezimal 600) kann 
ich mit einem Poti einstellen! Sobald das „Ergebnis“ unter Dezimal 550 
mit dem Poti eingestellt wurde soll die LED leuchten.
Das Problem ist, wie kann ich so einen PT1-Filter einbauen? Welchen Wert 
kann ich als Vergleichsgröße nehmen? Bei meinem Code habe ich es ohne 
den PT1-Filter, so wie unten deklariert
If(ADCWert <= 550) LED = ON;

Als Periodendauer habe ich Tp=0.004s und Verzögerungszeit Tpt1=60s.
Einige Tipps und auch Code-Beispiele könnten sehr behilflich werden

Mfg
Jesus
#2760682
Lesenswert?

Jesus Nvs schrieb:
> Hallo,
>
> Eine reine mittelwertbildung verlsngsamt doch die ganze sache!

Ist eine reine Frage, wieviele Messwerte du zur Mittelwertbildung 
heranziehst (wie weit in die Vergangenheit der Mittelwert reicht)

> Mit dem
> pt1 filter ist es doch etwas anders zu implementieren? Oder liege ich da
> etwa falsch?

Ist doch im Grunde auch nichts anders. Nur mehr Aufwand (nach dem was 
ich da bis jetzt kurz gegoggelt habe)
Moderator (Firma: Titel) Persönliche Seite #2761770
Lesenswert?

Jesus Nvs schrieb:
>> http://www.lothar-miller.de/s9y/archives/25-Filter-in-C.html
> Ist das nicht nur eine Mittelwertbildung??
Nein.
Eine Mittelwertbildung (im üblichen Sinn: gleitend) könnte ich nur 
machen, wenn ich die 20 letzten Werte speichern und daraus den 
Mittelwert berechnen.

Uhu Uhuhu schrieb:
> Ein gleitender Mittelwert entspricht doch einem PT1-Glied...
Auch nein.

Beim PT1-Glied dürfen aber alle Werte von Anfang an mitspielen Es wird 
nicht nach einer bestimmten Zeit der älteste Wert weggeworfen. Es wird 
nur einfach der neueste Wert mehr gewichtet, und so jeder Einzelne der 
alten Werte mit zunehmendem Alter weniger "wert".
Übertragen in Hardware: die Summe ist der Kondensator.
Das Verhältnis der Gewichtung alt:neu ist der Widerstand...
OP #2761834
Lesenswert?

Lothar Miller schrieb:
> Beim PT1-Glied dürfen aber alle Werte von Anfang an mitspielen Es wird
>
> nicht nach einer bestimmten Zeit der älteste Wert weggeworfen. Es wird
>
> nur einfach der neueste Wert mehr gewichtet, und so jeder Einzelne der
>
> alten Werte mit zunehmendem Alter weniger "wert".
>
> Übertragen in Hardware: die Summe ist der Kondensator.
>
> Das Verhältnis der Gewichtung alt:neu ist der Widerstand...

Könntest du eventuell einen C-Code geben, wo ich es besser verstehen 
könnte? :)

Ich hoffe, dass die PT1-Filter mit den Formeln unten leicht zu 
Implementieren ist!?

Jesus Nvs schrieb:
> Xa/Xe = 1 / (1+ (s*Tpt1)) und
>
>
>
> s = (2*(1-z^-1)) / (Tp*(1+z^-1))
Moderator (Firma: Titel) Persönliche Seite #2762667
Lesenswert?

Hans L. schrieb:
> Umsetzung RC in C ;)
1
filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;
2
output = filter_reg >> FILTER_SHIFT;
Exakt das selbe, was ich mache. Nur einfach in 1 Zeile gepackt und 
explizite Schiebeoperatoren verwendet (was bei den zuvor definierten 
signed-Werten durchaus ins Auge gehen kann)...
1
   avgsum -= avgsum/128;
2
   avgsum += newval;
3
   return avgsum/128;

Uhu Uhuhu schrieb:
>> Es wird nicht nach einer bestimmten Zeit der älteste Wert weggeworfen.
> Das wird in dem Codebeispiel ja auch nicht gemacht...
Richtig, deshalb ist es kein gleitender Mittelwert.
OP #2763324
Lesenswert?

Wie kann ich dieses Code bei meiner Anwendung Implementieren? :)

Also wie gesagt, ohne den Filter habe ich

if(ADCWert <= 550) LED = ON; gehabt!

ich würde zuerst sagen -> filter_input = ADCWert;

wie gehts denn jetzt weiter ???

Lothar Miller schrieb:
> filter_reg = filter_reg - (filter_reg >> FILTER_SHIFT) + filter_input;
>
> output = filter_reg >> FILTER_SHIFT;

Lothar Miller schrieb:
> avgsum -= avgsum/128;
>
>    avgsum += newval;
>
>    return avgsum/128;
OP #2774681
Lesenswert?

Hallo Leute,

Sorry das ich erst jetzt ragieren konnte. War leider die letzten Tage 
etwas angeschlagen!

static unsigned long avgsum = 0;
avgsum -= avgsum/128;
avgsum += newval;
return avgsum/128;

Vorn Nachn schrieb:
> #define FILTER 5  //Filterstärke 1 .. 6 bei 10-Bit-ADC
> if((avgsum+=adc-(avgsum>>FILTER)) < (550<<FILTER))LED=ON else LED=OFF;

Was ich nicht verstanden habe ist, wieso FILTER als die Zahl 5 genommen 
wird?? Hats das etwas mit dem 128 zu tun??

Mfg
Moderator (Firma: Titel) Persönliche Seite #2776942
Lesenswert?

Jesus Nvs schrieb:
> Was ich nicht verstanden habe ist, wieso FILTER als die Zahl 5 genommen
> wird?? Hats das etwas mit dem 128 zu tun??
Ja.  2^5 sind 32
Es wäre also das selbe, wie wenn da statt 128 überall 32 stehen würde:
1
static unsigned long avgsum = 0;
2
avgsum -= avgsum/32;
3
avgsum += newval;
4
return avgsum/32;

Aber richtigerweise sollte (wegen des signed) da stehen:
1
if((avgsum+=adc-(avgsum/32)) < (550<<FILTER))LED=ON else LED=OFF;
Oder einfach avgsum als unsigned nehmen. Dann passts immer, ob mit 
Shift oder mit Division...
#2777164
Lesenswert?

Michael H. schrieb:
> Sinnvoller für Temperaturmessung und dabei noch leichter zu
> implementieren wäre ein IIR-Filter.

Jesus Nvs schrieb:
> ich würde es gerne mit dem PT1-Filter Implementieren!

...

Jesus Nvs schrieb:
> Ich bin zufälligerweise auf die Seite von Cypress gestoßen da wird für
> das Software Filtern z.B der IIR-Filter empfohlen(siehe Anhang S.41)


Verstehst du eigentlich überhaupt irgendetwas von dem, was du machen 
willst??
Ich nehme mal an, du bist Student? Studier was anderes...
OP #2777263
Lesenswert?

Hallo,

ich muss ehrlich zugeben, dass ich mich nicht so oft damit beschäftigt 
habe. Aus diesem Grund kommt es mal vor, dass ich mehrere Fragen habe 
die beantwortet werden sollte. Deshalb stelle ich soviele Fragen wie 
möglich damit ich jede Arten von Fragezeichen beseitigen kann :)

Ich hoffe um Verständnis :)

Gruss
Gast #2778375
Lesenswert?

> Ich hoffe um Verständnis :)

Da biste im falschen Forum gelandet, also weg hau ab verschwinde!
(-; (-; (-;

> damit ich jede Arten von Fragezeichen beseitigen kann

Also ich kenn nur diese Art: ?

;-)


SCNR
Gast #2778587
Lesenswert?

Jesus Nvs schrieb:
> Ich bin zufälligerweise auf die Seite von Cypress gestoßen da wird für
> das Software Filtern z.B der IIR-Filter empfohlen(siehe Anhang S.41)
>
> Die gleichung sieht so aus : Y(i) = 1/k x [X(i) + (k-1) x Y(i-1)]
>
> Wie könnte ich diesen in C Implementieren?

z.B. so:
1
Y[i] = 1.0/k * (X[i] + (k-1.0) * Y[i-1]);

(ich warte nur, bis das nächste Bitfile fertig ist...)
OP #2796659
Lesenswert?

Ich habe das Folgende Code(Anhang) Implementiert. Jedoch Funktioniert es 
nicht ! Ich wüsste nicht wo ich einen Fehler gemacht haben könnte!?

Ich bilde 2 Mittelwerte; Das eine bestehht aus 16Werten wo ich eine 
Änderung des ADCWertes erkennen kann.
Das zweite ist eine Langzeit Mittelwert wo sich das neue Schwellwert 
berechnen lässt.

Für weitere Hilfen schonmal besten Dank

Gruss

JN
Angehängte Dateien:
Gast #2796681
Lesenswert?

PT1 als IIR-"Sparfilter" in C:

gefilterterWert += ((input - gefilterterWert) * filterfaktor);

filterfaktor 0..1 -> 0 keine/langsame Filterkonstante, 1 
ungefiltert/schnell

Das dann für signed Werte. Bei unsigned kann man vorher eine 
Fallunterscheidung auf input >= gefilterterWert machen. Der Filterfaktor 
kann natürlich auch durch >> 8 oder >> 16 auf 8Bit oder 16Bit skaliert 
werden. Die genaue Grenzfrequenz lässt sich mit der Taskzeit in der der 
Filter gerechnet wird bestimmen.

Hoffe es hilft ...
Gast #2796688
Lesenswert?

Warum hat eigentlich niemand bis jetzt Jesus gesagt daß:
- programmieren etwas anderes als code aus dem Netz zusammenklauben ist.
- man auf seine Weise NICHT programmieren lernt
- Er ein C Buch braucht, das er auch lesen muss.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren