Cutoff frequency variable LPF, HPF, BPF, and BRF by FIR 160th-order filter.

Dependencies:   UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602

Revision:
0:ca94cfc90365
Child:
1:58271fae2e01
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Mon Dec 08 08:14:48 2014 +0000
@@ -0,0 +1,135 @@
+//------------------------------------------------------------------------------
+// Cutoff frequency variable LPF and HPF,
+// center frequency variable BPF and BRF by FIR 160th-order filter
+//      A0: Signal to be filtered
+//      A2: Value which controls cutoff frequency
+//
+//      1: LPF, 3: HPF, 5: BPF, 7: BRF, even: through
+// 2014/12/07, Copyright (c) 2014 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#include "mbed.h"
+
+#include "ADC_Interrupt.hpp"    // for ADC using interrupt
+#include "DAC_MCP4922.hpp"      // for DAC MCP4922
+#include "ACM1602NI.hpp"        // for LCD display
+
+#include "WindowingDesign.hpp"  // for design of FIR 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);
+DigitalIn sw2_(D3, PullDown);
+DigitalIn sw4_(D4, PullDown);
+DigitalIn sw8_(D5, PullDown);
+
+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()
+{
+    myDac_.ScfClockTim3(670000);    // cutoff frequency: 6.7 kHz
+
+    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;
+    while (true)
+    {
+        // fc: cutoff or center frequency, 200 -- 2000 Hz
+        float fc = 1800.0f*(a2_/4095.6f) + 200.0f;
+
+        int sw = (sw8_ << 3) | (sw4_ << 2) | (sw2_ << 1) | sw1_;
+        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, 1);
+
+                if (sw == 1)
+                {
+                    printf("LPF\r\n");
+                    lcd.WriteStringXY("LPF", 0, 0);
+                    design_.Design(ORDER_, WindowingDesign::LPF, fc, 0, hm_);
+                }
+                if (sw == 3)
+                {
+                    printf("HPF\r\n");
+                    lcd.WriteStringXY("HPF", 0, 0);
+                    design_.Design(ORDER_, WindowingDesign::HPF, fc, 0, hm_);
+                }
+                if (sw == 5)
+                {
+                    printf("BPF\r\n");
+                    lcd.WriteStringXY("BPF", 0, 0);
+                    design_.Design(ORDER_, WindowingDesign::BPF, fc-100, fc+100, hm_);
+                }
+                if (sw == 7)
+                {
+                    printf("BRF\r\n");
+                    lcd.WriteStringXY("BRF", 0, 0);
+                    design_.Design(ORDER_, WindowingDesign::BRF, fc-100, fc+100, hm_);
+                }
+                fc1 = fc;
+            }
+        }
+        wait(0.1f);
+    }
+}