不韋 呂 / Mbed 2 deprecated UIT2_VariableFIR_LPFHPF

Dependencies:   UIT_ACM1602NI UIT_ADDA mbed

Files at this revision

API Documentation at this revision

Comitter:
MikamiUitOpen
Date:
Mon Nov 10 03:03:18 2014 +0000
Child:
1:c99aed871609
Commit message:
1

Changed in this revision

UIT_ACM1602NI.lib Show annotated file Show diff for this revision Revisions of this file
UIT_ADDA.lib Show annotated file Show diff for this revision Revisions of this file
WindowingDesignLpfHpf/WindowingDesignLH.cpp Show annotated file Show diff for this revision Revisions of this file
WindowingDesignLpfHpf/WindowingDesignLH.hpp Show annotated file Show diff for this revision Revisions of this file
main.cpp Show annotated file Show diff for this revision Revisions of this file
mbed.bld Show annotated file Show diff for this revision Revisions of this file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UIT_ACM1602NI.lib	Mon Nov 10 03:03:18 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/MikamiUitOpen/code/UIT_ACM1602NI/#7c6b2df4e60b
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/UIT_ADDA.lib	Mon Nov 10 03:03:18 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/MikamiUitOpen/code/UIT_ADDA/#651809e96a2d
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WindowingDesignLpfHpf/WindowingDesignLH.cpp	Mon Nov 10 03:03:18 2014 +0000
@@ -0,0 +1,92 @@
+//------------------------------------------------------------------------------
+//  Design of FIR filter of LPF and HPF using window method
+//
+//  2014/11/09, Copyright (c) 2014 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#include "WindowingDesignLH.hpp"
+
+namespace Mikami
+{
+    WindowingDesign::WindowingDesign(int order, float fs)
+            : FS_(fs), PI_FS_(3.1415926536f/fs)
+    {
+        order_ = order;
+        if ((order % 2) != 0)
+        {
+            fprintf(stderr, "order must be even.");
+            return;
+        }
+        hm_ = new float[order/2+1];
+        wn_ = new float[order/2+1];    
+        
+        HammWindow();
+    }
+        
+    void WindowingDesign::Design(int order, Type pb, float fc,
+                                 float hk[])
+    {       
+        if (pb == LPF) fC_ = fc;
+        if (pb == HPF) fC_ = 0.5f*FS_ - fc;
+    
+        if (order != order_)
+        {
+            order_ = order_;
+            if (hm_ != NULL) delete[] hm_;
+            hm_ = new float[order/2+1];
+            if (wn_ != NULL) delete[] wn_;
+            wn_ = new float[order/2+1];
+            HammWindow();
+        }
+
+        // Calculate coefficients for LPF
+        LpfCoefficients();
+        // If HPF, transform coefficients
+        if (pb != LPF) ToHpf();
+        
+        for (int k=0; k<=order/2; k++)
+            hk[k] = hm_[order/2-k];
+
+        // For compensation of gain
+        float sum = hk[order_/2];
+        if (pb == LPF)
+            for (int k=0; k<order_/2; k++)
+                sum = sum + 2.0f*hk[k];
+        if (pb == HPF)
+        {
+            float sign = -1.0;
+            for (int k=order_/2-1; k>=0; k--)
+            {
+                sum = sum + sign*2.0f*hk[k];
+                sign = -sign;
+            }
+        }
+        for (int k=0; k<=order_/2; k++)
+            hk[k] = hk[k]/sum;
+    }
+
+    // Calculation of coefficients for LPF
+    void WindowingDesign::LpfCoefficients()
+    {
+        float w = 2.0f*PI_FS_*fC_;
+        hm_[0] = 2.0f*fC_/FS_;
+        for (int k=1; k<=order_/2; k++)
+            hm_[k] = (sinf(k*w)/(PI_*k))*wn_[k];  
+    }
+    
+    // Transform LPF to HPF
+    void WindowingDesign::ToHpf()
+    {
+        for (int k=1; k<=order_/2; k+=2)
+            hm_[k] = -hm_[k];
+    }    
+
+    // Hamming window
+    void WindowingDesign::HammWindow()
+    {
+        float pi2OvM = 2.0f*PI_/(float)(order_ + 1);
+        for (int n=0; n<=order_/2; n++)
+            wn_[n] = 0.54f + 0.46f*cosf(pi2OvM*n);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/WindowingDesignLpfHpf/WindowingDesignLH.hpp	Mon Nov 10 03:03:18 2014 +0000
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+//  Design of FIR filter of LPF and HPF using window method -- Header
+//
+//  2014/11/09, Copyright (c) 2014 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#ifndef HAMMING_WINDOWING_DESIGN_HPP
+#define HAMMING_WINDOWING_DESIGN_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+    class WindowingDesign
+    {
+    public:
+        struct Coefs { float a1, a2, b1; };
+        enum Type { LPF, HPF };
+
+        // Constructor
+        WindowingDesign(int order, float fs);
+
+        //Destructor
+        ~WindowingDesign()
+        {
+            delete[] hm_;
+            delete[] wn_;
+        }
+
+        // Execution of design
+        void Design(int order, Type pb, float fc, float hk[]);
+
+    private:
+        static const float PI_ = 3.1415926536f;
+        const float FS_;    // Sampling frequency
+        const float PI_FS_;
+        
+        float *hm_;     // For coefficients
+        float *wn_;     // For Windwo
+                
+        int order_;     // Order
+        float fC_;      // Cutoff frequency
+        
+        // Calculation of coefficients for LPF
+        void LpfCoefficients();
+        // Transform LPF to HPF
+        void ToHpf();
+        // Hamming window
+        void HammWindow();
+    };
+}
+#endif  // HAMMING_WINDOWING_DESIGN_HPP
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Nov 10 03:03:18 2014 +0000
@@ -0,0 +1,125 @@
+//------------------------------------------------------------------
+// Cutoff frequency variable LPF and HPF by FIR 160th-order filter
+//      A0: Signal to be filtered
+//      A2: Value which controls cutoff frequency
+//
+// 2014/11/10, Copyright (c) 2014 MIKAMI, Naoki
+//------------------------------------------------------------------
+
+#include "mbed.h"
+
+#include "ADC_Interrupt.hpp"    // for ADC using interrupt
+#include "DAC_MCP4922.hpp"      // for DAC MCP4922
+#include "ScfClockTim3.hpp"     // for clock supplied to SCF
+#include "ACM1602NI.hpp"        // for LCD display
+
+#include "WindowingDesignLH.hpp" // for design of IIR filter
+
+using namespace Mikami;
+
+const int FS_ = 16000;          // Sampling frequency: 16 kHz
+ADC_Intr myAdc_(A0, FS_, A1, A2);
+DAC_MCP4922 myDac_;
+
+const int ORDER_ = 160;
+float hm_[ORDER_/2+1];
+float xn_[ORDER_+1];
+
+DigitalIn sw1_(D2, PullDown);   // 0: disable filter
+                                // 1: enable filter
+DigitalIn sw2_(D3, PullDown);   // 0: LPF
+                                // 1: HPF
+WindowingDesign design_(ORDER_, FS_);
+DigitalOut dOut_(D7);
+
+uint16_t a2_ = 0;   // Inputted data from A2 pin
+
+// Interrupt service routine for ADC
+void AdcIsr()
+{   
+    dOut_.write(1);
+    xn_[0] = myAdc_.Read();   // Read from A0
+
+    myAdc_.Select3rdChannel();  // Select A2   
+    myAdc_.SoftStart();         // ADC start for A2 input
+
+    //-----------------------------------------
+    // Execute FIR filter
+        float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
+        for (int k=0; k<ORDER_/2; k++)
+            yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);
+
+        for (int k=ORDER_; k>0; k--)
+            xn_[k] = xn_[k-1];  // move input signals
+    //-----------------------------------------
+
+    if (sw1_ == 0) myDac_.Write(xn_[0]);    // Using no filter
+    else           myDac_.Write(yn);        // Using filter
+
+    // Read value which controls cutoff frequency
+    a2_ = myAdc_.ReadWait_u16();
+
+    myAdc_.Select1stChannel();      // Select A0
+    myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
+                                    // and enable ADC_IRQn
+    dOut_.write(0);
+}
+
+int main()
+{
+    ScfClockTim3(670000);       // cutoff frequency: 6.7 kHz
+
+    WindowingDesign lpfDsgn(ORDER_, FS_);
+    Acm1602Ni lcd;  // objetc for display using LCD
+
+    // Clear buffer in FIR filter
+    for (int n=0; n<=ORDER_; n++)
+        xn_[n] = 0;
+    myAdc_.SetIntrVec(AdcIsr);  // Assign ISR for ADC interrupt
+
+    float fc1 = 0;
+    WindowingDesign::Type pb = WindowingDesign::LPF;
+    while (true)
+    {
+        // fc: cutoff frequency, 100 -- 2000 Hz
+        float fc = 1900.0f*(a2_/4095.6f) + 100.0f;
+
+        if (sw1_ == 0)
+        {
+            printf("Through\r\n");
+            lcd.ClearLine(1);
+            lcd.WriteStringXY("Through         ", 0, 0);
+            wait(0.2f);
+            lcd.ClearLine(0);           
+            fc1 = 0;
+        }
+        else
+        {
+            if (fabs(fc - fc1) > 10.0f)
+            {
+                printf("fc = %4d\r\n", int(fc+0.5f));
+                char str[18];
+                sprintf(str, "fc = %4d Hz", int(fc+0.5f));
+                lcd.WriteStringXY(str, 0, 0);
+                if (sw2_ == 0)
+                {
+                    pb = WindowingDesign::LPF;
+                    printf("LPF\r\n");
+                    lcd.WriteStringXY("LPF", 0, 1);
+                }
+                else
+                {
+                    pb = WindowingDesign::HPF;
+                    printf("HPF\r\n");
+                    lcd.WriteStringXY("HPF", 0, 1);
+                }
+                fc1 = fc;
+
+                // Design new coefficients based on new fc
+                design_.Design(ORDER_, pb, fc1, hm_);
+            }
+        }
+        wait(0.1f);
+    }
+}
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/mbed.bld	Mon Nov 10 03:03:18 2014 +0000
@@ -0,0 +1,1 @@
+http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89
\ No newline at end of file