Cutoff frequency variable LPF by IIR 6th-order Butterworth filter for ST Nucleo F401RE.

Dependencies:   UIT_IIR_Filter UIT_ACM1602NI UITDSP_ADDA mbed UIT_AQM1602

Revision:
0:a9412b9e85b7
Child:
1:e9b451a71ebf
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp	Thu Oct 23 06:44:40 2014 +0000
@@ -0,0 +1,98 @@
+//--------------------------------------------------------------
+// Cutoff frequency variable LPF by IIR 6th-order filter
+//      A0: Signal to be filtered
+//      A2: Value which controls cutoff frequency
+//
+// 2014/10/23, 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 "BilinearDesignLH.hpp" // for design of IIR filter
+#include "IIR_Cascade.hpp"      // for IIR filter of cascade structure
+
+using namespace Mikami;
+
+const int FS_ = 24000;          // Sampling frequency: 24 kHz
+ADC_Intr myAdc_(A0, FS_, A1, A2);
+DAC_MCP4922 myDac_;
+
+const int ORDER_ = 6;
+IirCascade<ORDER_/2> iirLpf_;   // IIR filter object
+
+DigitalIn sw1_(D2, PullDown);   // 0: disable filter
+                                // 1: enable filter
+
+uint16_t a2_ = 0;   // Inputted data from A2 pin
+
+// Interrupt service routine for ADC
+void AdcIsr()
+{   
+    float xn = myAdc_.Read();   // Read from A0
+
+    myAdc_.Select3rdChannel();  // Select A2   
+    myAdc_.SoftStart();         // ADC start for A2 input
+
+    // Execute IIR filter
+    float yn = iirLpf_.Execute(xn);
+
+    if (sw1_ == 0) myDac_.Write(xn);    // 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
+}
+
+int main()
+{
+    const int ORDER = 6;
+    ScfClockTim3(1000000);      // cutoff frequency: 10 kHz
+
+    BiliearDesign lpfDsgn(ORDER, FS_, BiliearDesign::LPF);
+    Acm1602Ni lcd;  // objetc for display using LCD
+
+    myAdc_.SetIntrVec(AdcIsr);  // Assign ISR for ADC interrupt
+
+    float fc1 = 0;
+    while (true)
+    {
+        // fc: cutoff frequency, 200 -- 1000 Hz
+        float fc = 800.0f*(a2_/4095.6f) + 200.0f;
+
+        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.SetXY(0, 0);
+            lcd.WriteString(str);
+            fc1 = fc;
+
+            // Design new coefficients based on new fc
+            BiliearDesign::Coefs coefsLpf[ORDER/2];
+            float g0;
+            lpfDsgn.Execute(fc, coefsLpf, g0);
+
+            // Update new coefficients
+            Biquad::Coefs coefsIir[ORDER/2];
+            for (int n=0; n<ORDER/2; n++)
+            {
+                coefsIir[n].a1 = coefsLpf[n].a1;
+                coefsIir[n].a2 = coefsLpf[n].a2;
+                coefsIir[n].b1 = coefsLpf[n].b1;
+                coefsIir[n].b2 = 1.0f;
+            }
+            iirLpf_.SetCoefs(g0, coefsIir);
+        }
+        wait(0.1f);
+    }
+}