Cutoff frequency variable LPF by 160th-order FIR filter designed by window method usin Hamming window for ST Nucleo F401RE.

Dependencies:   UIT_ACM1602NI UIT_ADDA mbed

Committer:
MikamiUitOpen
Date:
Mon Dec 08 05:47:04 2014 +0000
Revision:
6:ccd700fb3f3a
Parent:
5:9dd178ff6239
7

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:b8bffbcb85fd 1 //------------------------------------------------------------------
MikamiUitOpen 1:24c33c8719b2 2 // Cutoff frequency variable LPF by FIR 160th-order filter
MikamiUitOpen 0:b8bffbcb85fd 3 // A0: Signal to be filtered
MikamiUitOpen 0:b8bffbcb85fd 4 // A2: Value which controls cutoff frequency
MikamiUitOpen 0:b8bffbcb85fd 5 //
MikamiUitOpen 6:ccd700fb3f3a 6 // 2014/12/08, Copyright (c) 2014 MIKAMI, Naoki
MikamiUitOpen 0:b8bffbcb85fd 7 //------------------------------------------------------------------
MikamiUitOpen 0:b8bffbcb85fd 8
MikamiUitOpen 0:b8bffbcb85fd 9 #include "mbed.h"
MikamiUitOpen 0:b8bffbcb85fd 10
MikamiUitOpen 0:b8bffbcb85fd 11 #include "ADC_Interrupt.hpp" // for ADC using interrupt
MikamiUitOpen 0:b8bffbcb85fd 12 #include "DAC_MCP4922.hpp" // for DAC MCP4922
MikamiUitOpen 0:b8bffbcb85fd 13 #include "ACM1602NI.hpp" // for LCD display
MikamiUitOpen 0:b8bffbcb85fd 14
MikamiUitOpen 5:9dd178ff6239 15 #include "WindowingDesignLH.hpp" // for design of FIR filter
MikamiUitOpen 0:b8bffbcb85fd 16
MikamiUitOpen 0:b8bffbcb85fd 17 using namespace Mikami;
MikamiUitOpen 0:b8bffbcb85fd 18
MikamiUitOpen 0:b8bffbcb85fd 19 const int FS_ = 16000; // Sampling frequency: 16 kHz
MikamiUitOpen 0:b8bffbcb85fd 20 ADC_Intr myAdc_(A0, FS_, A1, A2);
MikamiUitOpen 0:b8bffbcb85fd 21 DAC_MCP4922 myDac_;
MikamiUitOpen 0:b8bffbcb85fd 22
MikamiUitOpen 0:b8bffbcb85fd 23 const int ORDER_ = 160;
MikamiUitOpen 0:b8bffbcb85fd 24 float hm_[ORDER_/2+1];
MikamiUitOpen 0:b8bffbcb85fd 25 float xn_[ORDER_+1];
MikamiUitOpen 0:b8bffbcb85fd 26
MikamiUitOpen 0:b8bffbcb85fd 27 DigitalIn sw1_(D2, PullDown); // 0: disable filter
MikamiUitOpen 0:b8bffbcb85fd 28 // 1: enable filter
MikamiUitOpen 0:b8bffbcb85fd 29 WindowingDesign design_(ORDER_, FS_);
MikamiUitOpen 0:b8bffbcb85fd 30 DigitalOut dOut_(D7);
MikamiUitOpen 0:b8bffbcb85fd 31
MikamiUitOpen 0:b8bffbcb85fd 32 uint16_t a2_ = 0; // Inputted data from A2 pin
MikamiUitOpen 0:b8bffbcb85fd 33
MikamiUitOpen 0:b8bffbcb85fd 34 // Interrupt service routine for ADC
MikamiUitOpen 0:b8bffbcb85fd 35 void AdcIsr()
MikamiUitOpen 0:b8bffbcb85fd 36 {
MikamiUitOpen 0:b8bffbcb85fd 37 dOut_.write(1);
MikamiUitOpen 0:b8bffbcb85fd 38 xn_[0] = myAdc_.Read(); // Read from A0
MikamiUitOpen 0:b8bffbcb85fd 39
MikamiUitOpen 0:b8bffbcb85fd 40 myAdc_.Select3rdChannel(); // Select A2
MikamiUitOpen 0:b8bffbcb85fd 41 myAdc_.SoftStart(); // ADC start for A2 input
MikamiUitOpen 0:b8bffbcb85fd 42
MikamiUitOpen 0:b8bffbcb85fd 43 //-----------------------------------------
MikamiUitOpen 0:b8bffbcb85fd 44 // Execute FIR filter
MikamiUitOpen 0:b8bffbcb85fd 45 float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
MikamiUitOpen 0:b8bffbcb85fd 46 for (int k=0; k<ORDER_/2; k++)
MikamiUitOpen 0:b8bffbcb85fd 47 yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);
MikamiUitOpen 0:b8bffbcb85fd 48
MikamiUitOpen 0:b8bffbcb85fd 49 for (int k=ORDER_; k>0; k--)
MikamiUitOpen 0:b8bffbcb85fd 50 xn_[k] = xn_[k-1]; // move input signals
MikamiUitOpen 0:b8bffbcb85fd 51 //-----------------------------------------
MikamiUitOpen 0:b8bffbcb85fd 52
MikamiUitOpen 0:b8bffbcb85fd 53 if (sw1_ == 0) myDac_.Write(xn_[0]); // Using no filter
MikamiUitOpen 0:b8bffbcb85fd 54 else myDac_.Write(yn); // Using filter
MikamiUitOpen 0:b8bffbcb85fd 55
MikamiUitOpen 0:b8bffbcb85fd 56 // Read value which controls cutoff frequency
MikamiUitOpen 0:b8bffbcb85fd 57 a2_ = myAdc_.ReadWait_u16();
MikamiUitOpen 0:b8bffbcb85fd 58
MikamiUitOpen 0:b8bffbcb85fd 59 myAdc_.Select1stChannel(); // Select A0
MikamiUitOpen 0:b8bffbcb85fd 60 myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
MikamiUitOpen 0:b8bffbcb85fd 61 // and enable ADC_IRQn
MikamiUitOpen 0:b8bffbcb85fd 62 dOut_.write(0);
MikamiUitOpen 0:b8bffbcb85fd 63 }
MikamiUitOpen 0:b8bffbcb85fd 64
MikamiUitOpen 0:b8bffbcb85fd 65 int main()
MikamiUitOpen 0:b8bffbcb85fd 66 {
MikamiUitOpen 3:54eac4891e35 67 myDac_.ScfClockTim3(670000); // cutoff frequency: 6.7 kHz
MikamiUitOpen 0:b8bffbcb85fd 68
MikamiUitOpen 0:b8bffbcb85fd 69 WindowingDesign lpfDsgn(ORDER_, FS_);
MikamiUitOpen 0:b8bffbcb85fd 70 Acm1602Ni lcd; // objetc for display using LCD
MikamiUitOpen 0:b8bffbcb85fd 71
MikamiUitOpen 0:b8bffbcb85fd 72 // Clear buffer in FIR filter
MikamiUitOpen 0:b8bffbcb85fd 73 for (int n=0; n<=ORDER_; n++)
MikamiUitOpen 0:b8bffbcb85fd 74 xn_[n] = 0;
MikamiUitOpen 0:b8bffbcb85fd 75 myAdc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
MikamiUitOpen 0:b8bffbcb85fd 76
MikamiUitOpen 0:b8bffbcb85fd 77 float fc1 = 0;
MikamiUitOpen 0:b8bffbcb85fd 78 while (true)
MikamiUitOpen 0:b8bffbcb85fd 79 {
MikamiUitOpen 0:b8bffbcb85fd 80 // fc: cutoff frequency, 100 -- 2000 Hz
MikamiUitOpen 0:b8bffbcb85fd 81 float fc = 1900.0f*(a2_/4095.6f) + 100.0f;
MikamiUitOpen 0:b8bffbcb85fd 82
MikamiUitOpen 0:b8bffbcb85fd 83 if (sw1_ == 0)
MikamiUitOpen 0:b8bffbcb85fd 84 {
MikamiUitOpen 0:b8bffbcb85fd 85 printf("Through\r\n");
MikamiUitOpen 0:b8bffbcb85fd 86 lcd.WriteStringXY("Through ", 0, 0);
MikamiUitOpen 0:b8bffbcb85fd 87 wait(0.2f);
MikamiUitOpen 0:b8bffbcb85fd 88 lcd.ClearLine(0);
MikamiUitOpen 0:b8bffbcb85fd 89 fc1 = 0;
MikamiUitOpen 0:b8bffbcb85fd 90 }
MikamiUitOpen 0:b8bffbcb85fd 91 else
MikamiUitOpen 0:b8bffbcb85fd 92 {
MikamiUitOpen 0:b8bffbcb85fd 93 if (fabs(fc - fc1) > 10.0f)
MikamiUitOpen 0:b8bffbcb85fd 94 {
MikamiUitOpen 0:b8bffbcb85fd 95 printf("fc = %4d\r\n", int(fc+0.5f));
MikamiUitOpen 0:b8bffbcb85fd 96 char str[18];
MikamiUitOpen 0:b8bffbcb85fd 97 sprintf(str, "fc = %4d Hz", int(fc+0.5f));
MikamiUitOpen 0:b8bffbcb85fd 98 lcd.WriteStringXY(str, 0, 0);
MikamiUitOpen 0:b8bffbcb85fd 99 fc1 = fc;
MikamiUitOpen 0:b8bffbcb85fd 100 // Design new coefficients based on new fc
MikamiUitOpen 1:24c33c8719b2 101 design_.Design(ORDER_, WindowingDesign::LPF, fc1, hm_);
MikamiUitOpen 0:b8bffbcb85fd 102 }
MikamiUitOpen 0:b8bffbcb85fd 103 }
MikamiUitOpen 0:b8bffbcb85fd 104 wait(0.1f);
MikamiUitOpen 0:b8bffbcb85fd 105 }
MikamiUitOpen 0:b8bffbcb85fd 106 }
MikamiUitOpen 6:ccd700fb3f3a 107