Forum: Digitale Signalverarbeitung / DSP / Machine Learning PT1-Filter in C


von Jesus N. (piccolado)


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

: Verschoben durch Moderator
von Jesus N. (piccolado)


Lesenswert?

Hallo

Kann mir wirklich keiner helfen :(

MFG

JN

von Michael H. (michael_h45)


Lesenswert?

Sinnvoller für Temperaturmessung und dabei noch leichter zu 
implementieren wäre ein IIR-Filter.
Generelle Literatur zum Thema Digitales Filter: Schüßler: Digitale 
Signalverarbeitung Band 1 (und Band 2).

von Jesus N. (piccolado)


Lesenswert?

Hallo

Danke fur den tipp. Ich werde es mir angucken.

Für weitere tipps bin ich gern noch offen

Mfg

von Jesus N. (piccolado)


Lesenswert?

Hallo,

ich würde es gerne mit dem PT1-Filter Implementieren!

Einige Code-Beispiele könnten mich schon weiterbringen

Mfg

JN

von Michael H. (michael_h45)


Lesenswert?


von Benjamin K. (benjamin92)


Lesenswert?

Warum ist das überhaupt im Off-Topic?

von Jesus N. (piccolado)


Lesenswert?

Michael H. schrieb:
> http://www.lothar-miller.de/s9y/archives/25-Filter-in-C.html

Ist das nicht nur eine Mittelwertbildung??

Ich habe eher an einem PT1-Filter gedacht!

Xa/Xe = 1 / (1+ (s*Tpt1)) und

s = (2*(1-z^-1)) / (Tp*(1+z^-1))

von Uhu U. (uhu)


Lesenswert?

Jesus Nvs schrieb:
> Ist das nicht nur eine Mittelwertbildung??

Ein gleitender Mittelwert entspricht doch einem PT1-Glied...

von Jesus N. (piccolado)


Lesenswert?

Hallo,

Eine reine mittelwertbildung verlsngsamt doch die ganze sache! Mit dem 
pt1 filter ist es doch etwas anders zu implementieren? Oder liege ich da 
etwa falsch?

von Karl H. (kbuchegg)


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)

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von Jesus N. (piccolado)


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))

von Hans L. (hansl)


Angehängte Dateien:

Lesenswert?

Schau dir mal diese Filterbeschreibung an.

Umsetzung RC in C ;)

Hans L

von Uhu U. (uhu)


Lesenswert?

Lothar Miller schrieb:
> Es wird nicht nach einer bestimmten Zeit der älteste Wert weggeworfen.

Das wird in dem Codebeispiel ja auch nicht gemacht...

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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.

von Jesus N. (piccolado)


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;

von Vorn N. (eprofi)


Lesenswert?

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

von Simon K. (simon) Benutzerseite


Lesenswert?

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;

Bring einer lernenden Person nicht so einen Schiet bei!
Oder findest du das besonders cool alles in einer Zeile zu machen?

von Jesus N. (piccolado)


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

von Lothar M. (Firma: Titel) (lkmiller) (Moderator) Benutzerseite


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...

von Jesus N. (piccolado)


Angehängte Dateien:

Lesenswert?

Hallo,

danke Lothar für deine Antwort :)

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?

Gruss

von Klaus2 (Gast)


Lesenswert?

...ehm, du kannst aus der Zeile die notwendigen Schritte in C nicht 
ablesen?

Oha.

von Michael H. (michael_h45)


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...

von Jesus N. (piccolado)


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

von AG (Gast)


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

von Bronco (Gast)


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...)

von Jesus N. (piccolado)


Angehängte Dateien:

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

von weißNix (Gast)


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 ...

von UR-Schmitt (Gast)


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.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.