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

Committer:
MikamiUitOpen
Date:
Sat Jul 25 06:41:36 2015 +0000
Revision:
6:116f72cda0f4
Parent:
5:b291c4653eb9
Child:
7:34eced3597bb
7

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:a9412b9e85b7 1 //--------------------------------------------------------------
MikamiUitOpen 6:116f72cda0f4 2 // Cutoff frequency variable LPF by IIR 8th-order filter
MikamiUitOpen 0:a9412b9e85b7 3 // A0: Signal to be filtered
MikamiUitOpen 0:a9412b9e85b7 4 // A2: Value which controls cutoff frequency
MikamiUitOpen 0:a9412b9e85b7 5 //
MikamiUitOpen 6:116f72cda0f4 6 // 2015/07/25, Copyright (c) 2015 MIKAMI, Naoki
MikamiUitOpen 0:a9412b9e85b7 7 //--------------------------------------------------------------
MikamiUitOpen 0:a9412b9e85b7 8
MikamiUitOpen 0:a9412b9e85b7 9 #include "ADC_Interrupt.hpp" // for ADC using interrupt
MikamiUitOpen 6:116f72cda0f4 10 #include "DAC_MCP4921.hpp" // for DAC MCP4921, MCP4922
MikamiUitOpen 6:116f72cda0f4 11 using namespace Mikami;
MikamiUitOpen 0:a9412b9e85b7 12
MikamiUitOpen 0:a9412b9e85b7 13 #include "BilinearDesignLH.hpp" // for design of IIR filter
MikamiUitOpen 0:a9412b9e85b7 14 #include "IIR_Cascade.hpp" // for IIR filter of cascade structure
MikamiUitOpen 0:a9412b9e85b7 15
MikamiUitOpen 6:116f72cda0f4 16 // ACM1602Ni を使う場合は次の define 文をコメントにすること
MikamiUitOpen 6:116f72cda0f4 17 #define AQM1602
MikamiUitOpen 6:116f72cda0f4 18
MikamiUitOpen 6:116f72cda0f4 19 #ifdef AQM1602
MikamiUitOpen 6:116f72cda0f4 20 #include "AQM1602.hpp"
MikamiUitOpen 6:116f72cda0f4 21 Aqm1602 Lcd_;
MikamiUitOpen 6:116f72cda0f4 22 #else
MikamiUitOpen 6:116f72cda0f4 23 #include "ACM1602NI.hpp"
MikamiUitOpen 6:116f72cda0f4 24 Acm1602Ni Lcd_;
MikamiUitOpen 6:116f72cda0f4 25 #endif
MikamiUitOpen 0:a9412b9e85b7 26
MikamiUitOpen 0:a9412b9e85b7 27 const int FS_ = 24000; // Sampling frequency: 24 kHz
MikamiUitOpen 0:a9412b9e85b7 28 ADC_Intr myAdc_(A0, FS_, A1, A2);
MikamiUitOpen 6:116f72cda0f4 29 DAC_MCP4921 myDac_;
MikamiUitOpen 0:a9412b9e85b7 30
MikamiUitOpen 6:116f72cda0f4 31 const int ORDER_ = 8;
MikamiUitOpen 0:a9412b9e85b7 32 IirCascade<ORDER_/2> iirLpf_; // IIR filter object
MikamiUitOpen 0:a9412b9e85b7 33
MikamiUitOpen 0:a9412b9e85b7 34 DigitalIn sw1_(D2, PullDown); // 0: disable filter
MikamiUitOpen 0:a9412b9e85b7 35 // 1: enable filter
MikamiUitOpen 0:a9412b9e85b7 36
MikamiUitOpen 0:a9412b9e85b7 37 uint16_t a2_ = 0; // Inputted data from A2 pin
MikamiUitOpen 0:a9412b9e85b7 38
MikamiUitOpen 0:a9412b9e85b7 39 // Interrupt service routine for ADC
MikamiUitOpen 0:a9412b9e85b7 40 void AdcIsr()
MikamiUitOpen 0:a9412b9e85b7 41 {
MikamiUitOpen 0:a9412b9e85b7 42 float xn = myAdc_.Read(); // Read from A0
MikamiUitOpen 0:a9412b9e85b7 43
MikamiUitOpen 0:a9412b9e85b7 44 myAdc_.Select3rdChannel(); // Select A2
MikamiUitOpen 0:a9412b9e85b7 45 myAdc_.SoftStart(); // ADC start for A2 input
MikamiUitOpen 0:a9412b9e85b7 46
MikamiUitOpen 0:a9412b9e85b7 47 // Execute IIR filter
MikamiUitOpen 0:a9412b9e85b7 48 float yn = iirLpf_.Execute(xn);
MikamiUitOpen 0:a9412b9e85b7 49
MikamiUitOpen 0:a9412b9e85b7 50 if (sw1_ == 0) myDac_.Write(xn); // Using no filter
MikamiUitOpen 0:a9412b9e85b7 51 else myDac_.Write(yn); // Using filter
MikamiUitOpen 0:a9412b9e85b7 52
MikamiUitOpen 0:a9412b9e85b7 53 // Read value which controls cutoff frequency
MikamiUitOpen 0:a9412b9e85b7 54 a2_ = myAdc_.ReadWait_u16();
MikamiUitOpen 0:a9412b9e85b7 55
MikamiUitOpen 0:a9412b9e85b7 56 myAdc_.Select1stChannel(); // Select A0
MikamiUitOpen 0:a9412b9e85b7 57 myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
MikamiUitOpen 0:a9412b9e85b7 58 // and enable ADC_IRQn
MikamiUitOpen 0:a9412b9e85b7 59 }
MikamiUitOpen 0:a9412b9e85b7 60
MikamiUitOpen 0:a9412b9e85b7 61 int main()
MikamiUitOpen 0:a9412b9e85b7 62 {
MikamiUitOpen 3:4086d5ad6e7a 63 myDac_.ScfClockTim3(1000000); // cutoff frequency: 10 kHz
MikamiUitOpen 0:a9412b9e85b7 64
MikamiUitOpen 6:116f72cda0f4 65 BilinearDesign lpfDsgn(ORDER_, FS_, BilinearDesign::LPF);
MikamiUitOpen 0:a9412b9e85b7 66
MikamiUitOpen 0:a9412b9e85b7 67 myAdc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
MikamiUitOpen 0:a9412b9e85b7 68
MikamiUitOpen 0:a9412b9e85b7 69 float fc1 = 0;
MikamiUitOpen 0:a9412b9e85b7 70 while (true)
MikamiUitOpen 0:a9412b9e85b7 71 {
MikamiUitOpen 4:460f2285dd87 72 // fc: cutoff frequency, 100 -- 2000 Hz
MikamiUitOpen 4:460f2285dd87 73 float fc = 1900.0f*(a2_/4095.6f) + 100.0f;
MikamiUitOpen 0:a9412b9e85b7 74
MikamiUitOpen 1:e9b451a71ebf 75 if (sw1_ == 0)
MikamiUitOpen 0:a9412b9e85b7 76 {
MikamiUitOpen 1:e9b451a71ebf 77 printf("Through\r\n");
MikamiUitOpen 6:116f72cda0f4 78 Lcd_.WriteStringXY("Through ", 0, 0);
MikamiUitOpen 1:e9b451a71ebf 79 wait(0.2f);
MikamiUitOpen 6:116f72cda0f4 80 Lcd_.ClearLine(0);
MikamiUitOpen 1:e9b451a71ebf 81 fc1 = 0;
MikamiUitOpen 1:e9b451a71ebf 82 }
MikamiUitOpen 1:e9b451a71ebf 83 else
MikamiUitOpen 1:e9b451a71ebf 84 {
MikamiUitOpen 1:e9b451a71ebf 85 if (fabs(fc - fc1) > 10.0f)
MikamiUitOpen 1:e9b451a71ebf 86 {
MikamiUitOpen 1:e9b451a71ebf 87 printf("fc = %4d\r\n", int(fc+0.5f));
MikamiUitOpen 1:e9b451a71ebf 88 char str[18];
MikamiUitOpen 1:e9b451a71ebf 89 sprintf(str, "fc = %4d Hz", int(fc+0.5f));
MikamiUitOpen 6:116f72cda0f4 90 Lcd_.WriteStringXY(str, 0, 0);
MikamiUitOpen 1:e9b451a71ebf 91 fc1 = fc;
MikamiUitOpen 0:a9412b9e85b7 92
MikamiUitOpen 1:e9b451a71ebf 93 // Design new coefficients based on new fc
MikamiUitOpen 6:116f72cda0f4 94 BilinearDesign::Coefs coefsLpf[ORDER_/2];
MikamiUitOpen 1:e9b451a71ebf 95 float g0;
MikamiUitOpen 1:e9b451a71ebf 96 lpfDsgn.Execute(fc, coefsLpf, g0);
MikamiUitOpen 0:a9412b9e85b7 97
MikamiUitOpen 1:e9b451a71ebf 98 // Update new coefficients
MikamiUitOpen 6:116f72cda0f4 99 Biquad::Coefs coefsIir[ORDER_/2];
MikamiUitOpen 6:116f72cda0f4 100 for (int n=0; n<ORDER_/2; n++)
MikamiUitOpen 1:e9b451a71ebf 101 {
MikamiUitOpen 1:e9b451a71ebf 102 coefsIir[n].a1 = coefsLpf[n].a1;
MikamiUitOpen 1:e9b451a71ebf 103 coefsIir[n].a2 = coefsLpf[n].a2;
MikamiUitOpen 1:e9b451a71ebf 104 coefsIir[n].b1 = coefsLpf[n].b1;
MikamiUitOpen 1:e9b451a71ebf 105 coefsIir[n].b2 = 1.0f;
MikamiUitOpen 1:e9b451a71ebf 106 }
MikamiUitOpen 1:e9b451a71ebf 107 iirLpf_.SetCoefs(g0, coefsIir);
MikamiUitOpen 0:a9412b9e85b7 108 }
MikamiUitOpen 0:a9412b9e85b7 109 }
MikamiUitOpen 0:a9412b9e85b7 110 wait(0.1f);
MikamiUitOpen 0:a9412b9e85b7 111 }
MikamiUitOpen 0:a9412b9e85b7 112 }