![](/media/cache/img/default_profile.jpg.50x50_q85.jpg)
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
main.cpp
- Committer:
- MikamiUitOpen
- Date:
- 2014-10-23
- Revision:
- 0:a9412b9e85b7
- Child:
- 1:e9b451a71ebf
File content as of revision 0:a9412b9e85b7:
//-------------------------------------------------------------- // 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); } }