Einfache digitale
Filter
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