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:
Sun Dec 07 05:45:07 2014 +0000
Revision:
5:b291c4653eb9
Parent:
4:460f2285dd87
Child:
6:116f72cda0f4
6

Who changed what in which revision?

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