Sign in to follow this  
Followers 0
ABV

Digital Filters

7 posts in this topic

#1 ·  Posted (edited)

Hi All

This is my first posting, and I have done so because you don't see that many worked exampled of DSP this maybe because there is not much interest or because it is a bit tricky.

Either way, here is some code for digital filters; It will need integrating into your application. If there is interest I will post more examples.

Local $rGain
    Local $rFc
    Local $rOrder
    Local $rMy_Output
    Local $bFirstRun = True
    
    Local $rM_Input
    Local $rM_Gain
    Local $rM_Freq
    Local $rM_Order
    Local $rM_LPF_Output
    Local $Temp = 0
    
    Local $rb0 = 0
    Local $rb1 = 0
    Local $rb2 = 0
    Local $rb3 = 0
    Local $ra1 = 0
    Local $ra2 = 0
    Local $ra3 = 0

    Local $rn = 0
    Local $rn_1 = 0
    Local $rn_2 = 0
    Local $rn_3 = 0
    Local $rn_4 = 0
    Local $ry = 0
    Local $ry_1 = 0
    Local $ry_2 = 0
    Local $ry_3 = 0
    Local $rMy_Output = 0
    Local $rOld_Order = 0
    
    Do
        
        $rGain  = 1
        $rFc    = 1000
        $rOrder = 2
            
        ;Wc = 2*pi*Fc
        ;K = Wc/TAN(pi*FC/Fs)
        $rWc = (2*$rPi*$rFc)
        $rK = ($rWc)/Tan(($rPi*$rFc)/$rFs)
            
        Select
            Case $rOrder = 1
                $FilterType = "1LP"
            Case $rOrder = 2
                $FilterType = "2LP"
            Case $rOrder = 3
                $FilterType = "3LP"
            Case Else   
                $FilterType = "1LP"
        EndSelect
                        
        If $bFirstRun = True Then
            $rOld_Order = $rOrder
        Else
            IF $rOld_Order <> $rOrder Then
                Local $rb0 = 0
                Local $rb1 = 0
                Local $rb2 = 0
                Local $rb3 = 0
                Local $ra1 = 0
                Local $ra2 = 0
                Local $ra3 = 0
            EndIf
        EndIf
            
        Select
            Case $FilterType = "1LP"
            ;First Order Low PASS Cpeficents
            ;b0 = Wc/(K+Wc)
            ;b1 = Wc/(K+Wc)
            ;a1 = (Wc-k)/(K+Wc)
            $rb0 = $rWc/($rK + $rWc)
            $rb1 = $rWc/($rK + $rWc)
            $ra1 = ($rWc - $rK)/($rK + $rWc)
    
        Case $FilterType = "1HP"
            ;First Order High PASS Cpeficents
            ;b0 = k/(K+Wc)
            ;b1 = -k/(K+Wc)
            ;a1 = (Wc-k)/(K+Wc)
            $rb0 = $rK /($rK + $rWc)
            $rb1 = -$rK /($rK + $rWc)
            $ra1 = ($rWc - $rK)/($rK + $rWc)
        
        Case $FilterType = "2LP"
            ;Second Order Low PASS Cpeficents
            ;b0 = Wc^2/Wc2+k2+Sqrt(2)*Wc*K
            ;b1 = (2*Wc^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;b2 = Wc^2/Wc2+k2+Sqrt(2)*Wc*K
            ;a1 = (2WC^2-2K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;a2 = (Wc2+k2-Sqrt(2)*Wc*K)/(Wc2+k2+Sqrt(2)*Wc*K)
            $rb0 = ($rWc^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb1 = (2*$rWc^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb2 = ($rWc^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra1 = ((2*$rWc^2) -(2*$rK^2)) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra2 = (($rWc^2)+($rK^2)-(Sqrt(2)*$rWc*$rK))/(($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
        
        Case $FilterType = "2HP"
            ;Second Order High PASS Cpeficents
            ;b0 = K^2/Wc2+k2+Sqrt(2)*Wc*K
            ;b1 = -(2*K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;b2 = K^2/Wc2+k2+Sqrt(2)*Wc*K
            ;a1 = (2WC^2-2K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;a2 = (Wc2+k2-Sqrt(2)*Wc*K)/(Wc2+k2+Sqrt(2)*Wc*K)
            $rb0 = ($rK^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb1 = (-2*$rK^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb2 = ($rK^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra1 = ((2*$rWc^2) -(2*$rK^2)) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra2 = (($rWc^2)+($rK^2)-(Sqrt(2)*$rWc*$rK))/(($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
        
        Case $FilterType = "3LP"
            ;Third Order Low PASS Cpeficents
            ;b0 = Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b1 = 3Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b2 = 3Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b3 = Wc3/Wc3+k3+2Wc2k+2Wck2
            ;a1 = 3Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a2 = 3Wc3+3k3-2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a3 = Wc3-2KWc2+2K2WC-K3/Wc3+k3+2Wc2k+2Wck2
            $rb0 = ($rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb1 = (3*$rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb2 = (3*$rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb3 = ($rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra1 = ((3*$rWc^3)-(3*$rK^3)+(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra2 = ((3*$rWc^3)+(3*$rK^3)-(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra3 = (($rWc^3)-(2*$rK*$rWc^2)+(2*$rK^2*$rWc)-($rK^3))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
        
        Case $FilterType = "3HP"
            ;Third Order High PASS Cpeficents
            ;b0 = K3/Wc3+k3+2Wc2k+2Wck2
            ;b1 = -3K3/Wc3+k3+2Wc2k+2Wck2
            ;b2 = 3K3/Wc3+k3+2Wc2k+2Wck2
            ;b3 = -K3/Wc3+k3+2Wc2k+2Wck2
            ;a1 = 3Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a2 = 3Wc3+3k3-2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a3 = Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            $rb0 = ($rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb1 = (-3*$rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb2 = (3*$rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb3 = (-$rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra1 = ((3*$rWc^3)-(3*$rK^3)+(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra2 = ((3*$rWc^3)+(3*$rK^3)-(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra3 = (($rWc^3)-(2*$rK*$rWc^2)+(2*$rK^2*$rWc)-($rK^3))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
    
        Case Else
            MsgBox(0, "", "No case was true")
    EndSelect
           
           
           $rn = $rM_Input
                        
            $rMy_Output = ($rb0*$rn)+($rb1*$rn_1)+($rb2*$rn_2)+($rb3*$rn_3)
            $rMy_Output = $rMy_Output - ($ra1*$ry_1)
            $rMy_Output = $rMy_Output - ($ra2*$ry_2)
            $rMy_Output = $rMy_Output - ($ra3*$ry_3)
                        
            $rn_3 = $rn_2
            $rn_2 = $rn_1
            $rn_1 = $rn
                        
            $ry_3 = $ry_2
            $ry_2 = $ry_1
            $ry_1 = $rMy_Output
                    
            $rMy_Output = $rMy_Output * $rGain
Edited by ABV

Share this post


Link to post
Share on other sites



Hi and Welcome to the forums!

Can you give us some example on what to use this for? (and how?)

:)

That was quick!

They are low and high pass filters calculations

If you have a data from and analogue to digital device, you might want to pass it through a filter to remove all frequency components above or below a cut-off frequency.

For example, if you have graphic equalisers on a stereo you can isolate frequency bands. Say 20-40Hz 0-20Khz.

This file contains the calculations in order to do so.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Hi,

I would like to know how to use your code.

But it looks very broken the way it is atm.

Your Do loop has no Until to complete doing a loop.

$rPi has no value and is not declared in any way but is called in calculations twice.

Your idea is good but your code needs to be tidied to be usable and examples of basic use need to be provided for anyone to make use of your posting.

EG: Type of data and the length of data your filters expect.

Cheers

Edited by smashly

Share this post


Link to post
Share on other sites

Hi,

I would like to know how to use your code.

But it looks very broken the way it is atm.

Your Do loop has no Until to complete doing a loop.

$rPi has no value and is not declared in any way but is called in calculations twice.

Your idea is good but your code needs to be tidied to be usable and examples of basic use need to be provided for anyone to make use of your posting.

EG: Type of data and the length of data your filters expect.

Cheers

Here is a worked example,

I use $r for real, $i for Integer and $s for String, $rPi is pi = 3.141...

This example uses a square wave input and you will see that the output responds slower, the high frequency edge has been filtered.

As you can tell GUI’s are not my strong point. I would like to be able to stop the execution when cancel is pressed. I am sure this is easy for most of you.

I am working on a Generic algorithm that I am thinking of posting. But like the filter it is pretty boring unless you have a reasonable GUI….

#include-once
#include <Array.au3>
#include <GUIConstantsEx.au3>


Opt("GUIOnEventMode", 1)

    Local $rGain = 1
    Local $rFc = 10
    Local $FilterType = "1LP"
    Local $rMy_Output
    Local $bFirstRun = True
    
    Local $rM_Input
    Local $rM_Gain
    Local $rAngle = 0
    
    Local $rb0 = 0
    Local $rb1 = 0
    Local $rb2 = 0
    Local $rb3 = 0
    Local $ra1 = 0
    Local $ra2 = 0
    Local $ra3 = 0

    Local $rn = 0
    Local $rn_1 = 0
    Local $rn_2 = 0
    Local $rn_3 = 0
    Local $rn_4 = 0
    Local $ry = 0
    Local $ry_1 = 0
    Local $ry_2 = 0
    Local $ry_3 = 0
    
    Local $rPi = 3.1415926535897932384626433832795
    

$Form1_1 = GUICreate("Filter Test", 350, 80)
GUISetOnEvent($GUI_EVENT_CLOSE, "SpecialEvents")


$iLabel1 = GUICtrlCreateLabel ("Input", 10, 22, 50, 20)
$iLabel1 = GUICtrlCreateLabel ("Output", 10, 47, 150, 20)


GuiCtrlCreateGroup("Filter Test Data", 5, 5, 220, 70)
$sAUI1  = GUICtrlCreateInput("G133", 55, 20, 150, 20)
$sAUI2  = GUICtrlCreateInput("G100", 55, 45, 150, 20)




;******************************************************************************
;******************************************************************************
;******************************************************************************
;******************************************************************************


;Create an "OK" button
$OK_Btn = GUICtrlCreateButton("Go", 260, 10, 70, 25)
GUICtrlSetOnEvent($OK_Btn, "OKPressed")
;Create a "CANCEL" button
$Cancel_Btn = GUICtrlCreateButton("Cancel", 260, 50, 70, 25)
GUICtrlSetOnEvent($Cancel_Btn, "CancelPressed")

GUISetState(@SW_SHOW)

While (1)
    Sleep(10)
Wend

Func SpecialEvents()
    ;Destroy the GUI including the controls
    GUIDelete()
    ;Exit the script
    Exit
EndFunc 

Func CancelPressed()
    ;Destroy the GUI including the controls

    GUIDelete()
    ;Exit the script
    Exit
EndFunc   ;==>CancelPressed

Func OKPressed()
    
    $rAngle = 0
    
    Do
        sleep(20)
        
        $rGain  = 1         ;system gain
        $rFc    = 0.1       ;Cut off Frequnecy Hz
        $FilterType = "1LP"
        $rFs        = 10    ; Sample Rate Hz 1/samples per second.
        
        ;this is a test input signal, think of it as a stream from a codec. I have craeted a square wave as an example
        $rM_Input = Sin($rAngle * ($rPi / 180)) 
        
        IF $rM_Input > 0 Then 
            $rM_Input = 10
        ElseIF $rM_Input < 0 Then 
            $rM_Input = -10
        Else
            $rM_Input = 0
        EndIf
        $rAngle += 1
        ;Test input End
        
        GUICtrlSetData($sAUI1,$rM_Input)
            
        ;Wc = 2*pi*Fc
        ;K = Wc/TAN(pi*FC/Fs)
        $rWc = (2*$rPi*$rFc)
        $rK = ($rWc)/Tan(($rPi*$rFc)/$rFs)
            
        If $bFirstRun = True Then
            Local $rb0 = 0
            Local $rb1 = 0
            Local $rb2 = 0
            Local $rb3 = 0
            Local $ra1 = 0
            Local $ra2 = 0
            Local $ra3 = 0
            $bFirstRun = False
        EndIf
            
        Select
            Case $FilterType = "1LP"
            ;First Order Low PASS Cpeficents
            ;b0 = Wc/(K+Wc)
            ;b1 = Wc/(K+Wc)
            ;a1 = (Wc-k)/(K+Wc)
            $rb0 = $rWc/($rK + $rWc)
            $rb1 = $rWc/($rK + $rWc)
            $ra1 = ($rWc - $rK)/($rK + $rWc)
    
        Case $FilterType = "1HP"
            ;First Order High PASS Cpeficents
            ;b0 = k/(K+Wc)
            ;b1 = -k/(K+Wc)
            ;a1 = (Wc-k)/(K+Wc)
            $rb0 = $rK /($rK + $rWc)
            $rb1 = -$rK /($rK + $rWc)
            $ra1 = ($rWc - $rK)/($rK + $rWc)
        
        Case $FilterType = "2LP"
            ;Second Order Low PASS Cpeficents
            ;b0 = Wc^2/Wc2+k2+Sqrt(2)*Wc*K
            ;b1 = (2*Wc^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;b2 = Wc^2/Wc2+k2+Sqrt(2)*Wc*K
            ;a1 = (2WC^2-2K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;a2 = (Wc2+k2-Sqrt(2)*Wc*K)/(Wc2+k2+Sqrt(2)*Wc*K)
            $rb0 = ($rWc^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb1 = (2*$rWc^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb2 = ($rWc^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra1 = ((2*$rWc^2) -(2*$rK^2)) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra2 = (($rWc^2)+($rK^2)-(Sqrt(2)*$rWc*$rK))/(($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
        
        Case $FilterType = "2HP"
            ;Second Order High PASS Cpeficents
            ;b0 = K^2/Wc2+k2+Sqrt(2)*Wc*K
            ;b1 = -(2*K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;b2 = K^2/Wc2+k2+Sqrt(2)*Wc*K
            ;a1 = (2WC^2-2K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;a2 = (Wc2+k2-Sqrt(2)*Wc*K)/(Wc2+k2+Sqrt(2)*Wc*K)
            $rb0 = ($rK^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb1 = (-2*$rK^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $rb2 = ($rK^2) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra1 = ((2*$rWc^2) -(2*$rK^2)) / (($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
            $ra2 = (($rWc^2)+($rK^2)-(Sqrt(2)*$rWc*$rK))/(($rWc^2)+($rK^2)+(Sqrt(2)*$rWc*$rK))
        
        Case $FilterType = "3LP"
            ;Third Order Low PASS Cpeficents
            ;b0 = Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b1 = 3Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b2 = 3Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b3 = Wc3/Wc3+k3+2Wc2k+2Wck2
            ;a1 = 3Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a2 = 3Wc3+3k3-2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a3 = Wc3-2KWc2+2K2WC-K3/Wc3+k3+2Wc2k+2Wck2
            $rb0 = ($rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb1 = (3*$rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb2 = (3*$rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb3 = ($rWc^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra1 = ((3*$rWc^3)-(3*$rK^3)+(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra2 = ((3*$rWc^3)+(3*$rK^3)-(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra3 = (($rWc^3)-(2*$rK*$rWc^2)+(2*$rK^2*$rWc)-($rK^3))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
        
        Case $FilterType = "3HP"
            ;Third Order High PASS Cpeficents
            ;b0 = K3/Wc3+k3+2Wc2k+2Wck2
            ;b1 = -3K3/Wc3+k3+2Wc2k+2Wck2
            ;b2 = 3K3/Wc3+k3+2Wc2k+2Wck2
            ;b3 = -K3/Wc3+k3+2Wc2k+2Wck2
            ;a1 = 3Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a2 = 3Wc3+3k3-2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a3 = Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            $rb0 = ($rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb1 = (-3*$rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb2 = (3*$rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $rb3 = (-$rK^3) / (($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra1 = ((3*$rWc^3)-(3*$rK^3)+(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra2 = ((3*$rWc^3)+(3*$rK^3)-(2*$rWc^2*$rK)-(2*$rWc*$rK^2))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
            $ra3 = (($rWc^3)-(2*$rK*$rWc^2)+(2*$rK^2*$rWc)-($rK^3))/(($rWc^3)+($rK^3)+(2*$rWc^2*$rK)+(2*$rWc*$rK^2))
    
        Case Else
            MsgBox(0, "", "No case was true")
    EndSelect
           
            $rn = $rM_Input
                        
            $rMy_Output = ($rb0*$rn)+($rb1*$rn_1)+($rb2*$rn_2)+($rb3*$rn_3)
            $rMy_Output = $rMy_Output - ($ra1*$ry_1)
            $rMy_Output = $rMy_Output - ($ra2*$ry_2)
            $rMy_Output = $rMy_Output - ($ra3*$ry_3)
                        
            $rn_3 = $rn_2
            $rn_2 = $rn_1
            $rn_1 = $rn
                        
            $ry_3 = $ry_2
            $ry_2 = $ry_1
            $ry_1 = $rMy_Output
                    
            $rMy_Output = $rMy_Output * $rGain
            
            GUICtrlSetData($sAUI2,$rMy_Output)
            
    Until $rAngle = (360 * 3)
    
EndFunc   ;==>OKPressed

Share this post


Link to post
Share on other sites

I hooked this into Taietel's

#AutoIt3Wrapper_AU3Check_Parameters=-q -d -w 1 -w 2 -w 3 -w 4 -w 5 -w 6 -w 7

#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <StaticConstants.au3>
#include <Array.au3>

Global $bFirstRun = True
Global Const $rPi = 3.1415926535897932384626433832795
Global $rM_Input, $rMy_Output
Global $rAngle = 0
Global $rGain = 1
Global $rFs, $rWc, $rK, $rn, $rn_1 = 0, $rn_2 = 0, $rn_3 = 0, $ra1 = 0, $ra2 = 0, $ra3 = 0
Global $ry_1 = 0, $ry_2 = 0, $ry_3 = 0, $rb0 = 0, $rb1 = 0, $rb2 = 0, $rb3 = 0
Global $rFc = 10
Global $FilterType = "1LP"

; sample control to monitor something (v2.0)
; by Mihai Iancu (aka taietel at yahoo dot com)
; modify to fit your needs

Global Const $hGui = GUICreate("A Whatever Monitor", 550, 120)

GUISetState(@SW_SHOWNORMAL)

Global $points[1]
Global $aControl[8]

AdlibRegister("_Timer", 500) ; register the timer

While 1
    Sleep(10)

    Switch GUIGetMsg()
        Case $GUI_EVENT_CLOSE
            Exit
    EndSwitch
WEnd

Func _Timer()
    Local $Val = OkPressed() ; Replace this with your value to monitor

    _MControl_DrawGraph($Val)
    GUICtrlSetData($aControl[1], "Digital Filter: " & $Val)
EndFunc   ;==>_Timer

Func _MControl_Create($iX = 10, $iY = 10, $iW = 540, $iH = 80, $GridSpace = 10, $GridColor = 0x008800, $iBkColor = 0x000000)
    If $iX = -1 Then $iX = 10
    If $iY = -1 Then $iY = 10
    If $iW < 180 Then $iW = 180
    If $iH < 80 Then $iH = 80

    Local $hGrafic = GUICtrlCreateGraphic($iX, $iY, $iW, $iH)
    GUICtrlSetColor(-1, $GridColor)
    GUICtrlSetBkColor(-1, $iBkColor)
    GUICtrlSetCursor(-1, 0)

    Local $hValMon = GUICtrlCreateLabel("", $iX, $iY + $iH, $iW, 12, BitOR($SS_LEFT, $SS_CENTERIMAGE))
    GUICtrlSetFont(-1, 6, 400, 0, "Terminal")
    GUICtrlSetColor(-1, 0x00CC00)
    GUICtrlSetBkColor(-1, 0x000000)

    ; store the data
    _ArrayInsert($aControl, 0, $hGrafic)
    _ArrayInsert($aControl, 1, $hValMon)
    _ArrayInsert($aControl, 2, $iX)
    _ArrayInsert($aControl, 3, $iY)
    _ArrayInsert($aControl, 4, $iW)
    _ArrayInsert($aControl, 5, $iH)
    _ArrayInsert($aControl, 6, $GridColor)
    _ArrayInsert($aControl, 7, $GridSpace)

    Return $aControl
EndFunc   ;==>_MControl_Create

Func _MControl_DrawGraph($iValue)
    Local $MaxValue = 100
    Local $MinValue = 0
    Local $maxSteps
    Local $fromPoint
    Local $toPoint
    Local $Step = 3

    If $iValue < $MinValue Or $iValue > $MaxValue Then
        Return False
    Else
        $maxSteps = $aControl[4] / $Step

        If UBound($points) >= $maxSteps Then
            For $i = 1 To UBound($points) - 1
                _ArraySwap($points[$i - 1], $points[$i])
                _ArrayDelete($points, $i)
                Return False
            Next
        EndIf

        _ArrayInsert($points, UBound($points), $iValue)

        GUICtrlDelete($aControl[0])

        _MControl_Create()

        For $i = $aControl[5] To 0 Step -$aControl[7]
            GUICtrlSetGraphic($aControl[0], $GUI_GR_COLOR, $aControl[6])
            GUICtrlSetGraphic($aControl[0], $GUI_GR_MOVE, 0, $i)
            GUICtrlSetGraphic($aControl[0], $GUI_GR_LINE, $aControl[4], $i)
        Next

        For $i = $aControl[7] - 1 To $aControl[4] Step $aControl[7]
            GUICtrlSetGraphic($aControl[0], $GUI_GR_MOVE, $i, 0)
            GUICtrlSetGraphic($aControl[0], $GUI_GR_LINE, $i, $aControl[5])
        Next

        If UBound($points) > 0 Then
            For $i = 1 To UBound($points) - 1
                $fromPoint = $aControl[5] / ($MaxValue - $MinValue) * ($points[$i - 1] - $MinValue)
                $toPoint = $aControl[5] / ($MaxValue - $MinValue) * ($points[$i] - $MinValue)
                GUICtrlSetGraphic($aControl[0], $GUI_GR_COLOR, 0xFFFF00)
                GUICtrlSetGraphic($aControl[0], $GUI_GR_MOVE, $aControl[4] - (UBound($points) - $i + 1) * $Step, $aControl[5] - $fromPoint)
                GUICtrlSetGraphic($aControl[0], $GUI_GR_LINE, $aControl[4] - (UBound($points) - $i) * $Step, $aControl[5] - $toPoint)
            Next
            GUICtrlSetGraphic($aControl[0], $GUI_GR_REFRESH)
        EndIf

        Return True
    EndIf
EndFunc   ;==>_MControl_DrawGraph

Func OKPressed()
    $rGain = 1 ;system gain
    $rFc = 0.1 ;Cut off Frequnecy Hz
    $FilterType = "1LP"
    $rFs = 10 ; Sample Rate Hz 1/samples per second.

    ;this is a test input signal, think of it as a stream from a codec. I have craeted a square wave as an example
    $rM_Input = Sin($rAngle * ($rPi / 180))

    If $rM_Input > 0 Then
        $rM_Input = 10
    ElseIf $rM_Input < 0 Then
        $rM_Input = -10
    Else
        $rM_Input = 0
    EndIf
    $rAngle += 1
    ;Test input End

    ;Wc = 2*pi*Fc
    ;K = Wc/TAN(pi*FC/Fs)
    $rWc = (2 * $rPi * $rFc)
    $rK = ($rWc) / Tan(($rPi * $rFc) / $rFs)

    If $bFirstRun = True Then
        $rb0 = 0
        $rb1 = 0
        $rb2 = 0
        $rb3 = 0
        $ra1 = 0
        $ra2 = 0
        $ra3 = 0
        $bFirstRun = False
    EndIf

    Select
        Case $FilterType = "1LP"
            ;First Order Low PASS Cpeficents
            ;b0 = Wc/(K+Wc)
            ;b1 = Wc/(K+Wc)
            ;a1 = (Wc-k)/(K+Wc)
            $rb0 = $rWc / ($rK + $rWc)
            $rb1 = $rWc / ($rK + $rWc)
            $ra1 = ($rWc - $rK) / ($rK + $rWc)

        Case $FilterType = "1HP"
            ;First Order High PASS Cpeficents
            ;b0 = k/(K+Wc)
            ;b1 = -k/(K+Wc)
            ;a1 = (Wc-k)/(K+Wc)
            $rb0 = $rK / ($rK + $rWc)
            $rb1 = -$rK / ($rK + $rWc)
            $ra1 = ($rWc - $rK) / ($rK + $rWc)

        Case $FilterType = "2LP"
            ;Second Order Low PASS Cpeficents
            ;b0 = Wc^2/Wc2+k2+Sqrt(2)*Wc*K
            ;b1 = (2*Wc^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;b2 = Wc^2/Wc2+k2+Sqrt(2)*Wc*K
            ;a1 = (2WC^2-2K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;a2 = (Wc2+k2-Sqrt(2)*Wc*K)/(Wc2+k2+Sqrt(2)*Wc*K)
            $rb0 = ($rWc ^ 2) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $rb1 = (2 * $rWc ^ 2) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $rb2 = ($rWc ^ 2) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $ra1 = ((2 * $rWc ^ 2) - (2 * $rK ^ 2)) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $ra2 = (($rWc ^ 2) + ($rK ^ 2) - (Sqrt(2) * $rWc * $rK)) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))

        Case $FilterType = "2HP"
            ;Second Order High PASS Cpeficents
            ;b0 = K^2/Wc2+k2+Sqrt(2)*Wc*K
            ;b1 = -(2*K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;b2 = K^2/Wc2+k2+Sqrt(2)*Wc*K
            ;a1 = (2WC^2-2K^2)/Wc2+k2+Sqrt(2)*Wc*K
            ;a2 = (Wc2+k2-Sqrt(2)*Wc*K)/(Wc2+k2+Sqrt(2)*Wc*K)
            $rb0 = ($rK ^ 2) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $rb1 = (-2 * $rK ^ 2) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $rb2 = ($rK ^ 2) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $ra1 = ((2 * $rWc ^ 2) - (2 * $rK ^ 2)) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))
            $ra2 = (($rWc ^ 2) + ($rK ^ 2) - (Sqrt(2) * $rWc * $rK)) / (($rWc ^ 2) + ($rK ^ 2) + (Sqrt(2) * $rWc * $rK))

        Case $FilterType = "3LP"
            ;Third Order Low PASS Cpeficents
            ;b0 = Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b1 = 3Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b2 = 3Wc3/Wc3+k3+2Wc2k+2Wck2
            ;b3 = Wc3/Wc3+k3+2Wc2k+2Wck2
            ;a1 = 3Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a2 = 3Wc3+3k3-2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a3 = Wc3-2KWc2+2K2WC-K3/Wc3+k3+2Wc2k+2Wck2
            $rb0 = ($rWc ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $rb1 = (3 * $rWc ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $rb2 = (3 * $rWc ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $rb3 = ($rWc ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $ra1 = ((3 * $rWc ^ 3) - (3 * $rK ^ 3) + (2 * $rWc ^ 2 * $rK) - (2 * $rWc * $rK ^ 2)) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $ra2 = ((3 * $rWc ^ 3) + (3 * $rK ^ 3) - (2 * $rWc ^ 2 * $rK) - (2 * $rWc * $rK ^ 2)) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $ra3 = (($rWc ^ 3) - (2 * $rK * $rWc ^ 2) + (2 * $rK ^ 2 * $rWc) - ($rK ^ 3)) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))

        Case $FilterType = "3HP"
            ;Third Order High PASS Cpeficents
            ;b0 = K3/Wc3+k3+2Wc2k+2Wck2
            ;b1 = -3K3/Wc3+k3+2Wc2k+2Wck2
            ;b2 = 3K3/Wc3+k3+2Wc2k+2Wck2
            ;b3 = -K3/Wc3+k3+2Wc2k+2Wck2
            ;a1 = 3Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a2 = 3Wc3+3k3-2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            ;a3 = Wc3-3k3+2Wc2k-2WcK2/Wc3+k3+2Wc2k+2Wck2
            $rb0 = ($rK ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $rb1 = (-3 * $rK ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $rb2 = (3 * $rK ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $rb3 = (-$rK ^ 3) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $ra1 = ((3 * $rWc ^ 3) - (3 * $rK ^ 3) + (2 * $rWc ^ 2 * $rK) - (2 * $rWc * $rK ^ 2)) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $ra2 = ((3 * $rWc ^ 3) + (3 * $rK ^ 3) - (2 * $rWc ^ 2 * $rK) - (2 * $rWc * $rK ^ 2)) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))
            $ra3 = (($rWc ^ 3) - (2 * $rK * $rWc ^ 2) + (2 * $rK ^ 2 * $rWc) - ($rK ^ 3)) / (($rWc ^ 3) + ($rK ^ 3) + (2 * $rWc ^ 2 * $rK) + (2 * $rWc * $rK ^ 2))

        Case Else
            MsgBox(0, "", "No case was true")
    EndSelect

    $rn = $rM_Input

    $rMy_Output = ($rb0 * $rn) + ($rb1 * $rn_1) + ($rb2 * $rn_2) + ($rb3 * $rn_3)
    $rMy_Output = $rMy_Output - ($ra1 * $ry_1)
    $rMy_Output = $rMy_Output - ($ra2 * $ry_2)
    $rMy_Output = $rMy_Output - ($ra3 * $ry_3)

    $rn_3 = $rn_2
    $rn_2 = $rn_1
    $rn_1 = $rn

    $ry_3 = $ry_2
    $ry_2 = $ry_1
    $ry_1 = $rMy_Output

    $rMy_Output *= $rGain

    Return $rMy_Output
EndFunc   ;==>OKPressed

Share this post


Link to post
Share on other sites

That certainly gives a good visual of the filter response

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now
Sign in to follow this  
Followers 0