Einfache digitale Filter

Elektronik-Labor   Projekte   AVR 

 

Tiefpass- und Hochpassfilter braucht man immer mal. Um einige kleine Programme in Bascom auszuprobieren verwende ich hier den Arduino zusammen mit dem Bascom-Bootloader.  Das erste Programm erzeugt ein Rechtecksignal an B.5 (= Pin13, LED), das über eine Drahtbrücke an ADC(0) gelegt wird.  In der Sub Filter wird das Signal gemessen, gefiltert und ausgegeben.  

'Arduino/Bascom Filter

$regfile = "m168def.dat"
$hwstack = 32
$swstack = 64
$framesize = 64
$crystal = 16000000
Baud = 19200

Dim Ausgang As Integer
Dim N As Word

'Ports 0...7 = PortD, Ports 9...13 = Port B
'13-LED = PortB.5

Config Portb.5 = Output

Declare Sub Filter()


Config Adc = Single , Prescaler = 32 , Reference = Avcc
Start Adc
Config Timer1 = Pwm , Prescale = 8 , Pwm = 10 , Compare A Pwm = Clear Up , Compare B Pwm = Clear Up
Start Timer1


Do
Portb.5 = 0
For N = 1 To 10
Filter
Waitms 20
Next N

Portb.5 = 1
For N = 1 To 10
Filter
Waitms 20
Next N
Loop


Sub Filter
Ausgang = Ausgang + Getadc(0)
Ausgang = Ausgang / 2
Pwm1a = Ausgang
Print Ausgang
End Sub


End



Die gefilterten Messwerte werden im Terminal sichtbar.  Wenn man genau hinsieht erkennt man bereits das typische Verhalten eines Tiefpassfilters, wie es z.B. mit einem RC-Glied erreicht wird.  Die Rechteckspannung hat die Werte 0 und ca. 1000.  Angenommen, der letzte Ausgangswert war Null, und jetzt schaltet das Eingangssignal um auf 1000. Dann liefert die Zeile
Ausgang = Ausgang + Getadc(0)
einen Wert von 1000.  In der nächsten Zeile wird dann durch 2 geteilt, macht 500. Beim nächsten Aufruf erhält man (500 + 1000) / 2 = 750 und nähert sich damit wieder um die Hälfte dem Endwert. Beim dritten Aufruf sind es (750 + 1000) / 2 = 875 und so weiter. Ungefähr diese Verhalten zeigen die Messwerte im Terminal.  Anders als beim sonst viel verwendeten gleitenden Mittelwert mit einem Ringpuffer müssen hier nicht mehrere alte Werte gespeichert werden, sondern nur einer in der Variablen Ausgang. Dieser enthält die Vorgeschichte des Signals theoretisch seit dem Start des Programms, praktisch und durch die Ganzzahl-Rundung aber effektiv die letzten paar Messungen.




Noch übersichtlicher wird es mit dem Oszilloskop. Das Ausgangssignal wird dazu auf den PWM-Ausgang gegeben und mit einem RC-Flied (1 kOhm, 10 µF)  geglättet. Und tatsächlich, es sieht aus wie am Ausgang einen einfachen RC-Tiefpassfilters.



Ein Hochpassfilter

Schaltet man einen Widerstand und einen Kondensator in Reihe, hat man bereits ein Filter erster Ordnung. Betrachtet man die Spannung am Kondensator, dann ist es ein Tiefpassfilter. Die Spannung am Widerstand zeigt dagegen ein Hochpassverhalten. Praktisch ist das die Differenz zwischen Eingangssignal und Tiefpass-Ausgang.



Dim Eingang As Integer
Dim Ausgang As Integer
Dim Hochpass As Integer
Dim N As Word

Sub Filter
Eingang = Getadc(0)
Ausgang = Ausgang + Eingang
Ausgang = Ausgang / 2
Hochpass = Eingang - Ausgang
Hochpass = Hochpass + 512
Pwm1a = Hochpass
End Sub





Die veränderte Filter-Sub stellt den mittleren Pegel auf 512 ein, damit das Signal in beide Richtungen ausschlagen kann. Das Oszillogramm sieht nicht ganz ideal aus, weil ein Tiefpassfilter am PWM-Ausgang nachgeschaltet ist. Schaut man sich die Daten aber im Terminal an, erkennt man Impulse bis herunter auf fast Null und herauf bis auf fast 1023.






Stärker filtern

Bisher hat jeder neue Messwert sich zu 50% im Endergebnis ausgewirkt, die anderen 50% kamen von allen bisherigen Werten. Will man stärker filtern kann dieses Verhältnis verändert werden. Es dauert dann länger bis der Endwert sich einpendelt, d.h. die Messung wird stärker geglättet. Im Endergebnis entspricht das einem Filter mit geringerer Grenzfrequenz. Das folgende Beispiel verwendet 90% der Vorgeschichte und 10% vom aktuellen Messwert.  Um das Ergebnis deutlich zu sehen wird diesmal jede Phase in 300 Rechendurchläufen ohne Wartezeiten bearbeitet.

Do
Portb.5 = 0
For N = 1 To 300
Filter
'Waitms 20
Next N

Portb.5 = 1
For N = 1 To 300
Filter
'Waitms 20
Next N
Loop


Sub Filter
Ausgang = Ausgang * 9
Ausgang = Ausgang + Getadc(0)
Ausgang = Ausgang / 10
Pwm1a = Ausgang
End Sub


Mehrstufige Filter

Einfache Filter höherer Ordnung können  gebildet werden, indem man das bereits gefilterte Signal der jeweils nächsten Filterstufe zuführt. Das folgende Beispiel filtert so stark, dass aus dem ursprünglichen Rechtecksignal bereits ein fast reines Sinussignal wird.

Do
Portb.5 = 0
For N = 1 To 50
Filter
Next N

Portb.5 = 1
For N = 1 To 50
Filter
Next N
Loop


Sub Filter
Ausgang = Ausgang * 7
Ausgang = Ausgang + Getadc(0)
Ausgang = Ausgang / 8

Ausgang2 = Ausgang2 * 7
Ausgang2 = Ausgang2 + Ausgang
Ausgang2 = Ausgang2 / 8

Ausgang3 = Ausgang3 * 7
Ausgang3 = Ausgang3 + Ausgang2
Ausgang3 = Ausgang3 / 8
Pwm1a = Ausgang3
End Sub




Elektronik-Labor   Projekte   AVR