Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: UIT_ACM1602NI UIT_ADDA mbed
Revision 0:b8bffbcb85fd, committed 2014-11-10
- Comitter:
- MikamiUitOpen
- Date:
- Mon Nov 10 02:45:18 2014 +0000
- Child:
- 1:24c33c8719b2
- Commit message:
- 1
Changed in this revision
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UIT_ACM1602NI.lib Mon Nov 10 02:45:18 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/UIT_ACM1602NI/#7c6b2df4e60b
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/UIT_ADDA.lib Mon Nov 10 02:45:18 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/MikamiUitOpen/code/UIT_ADDA/#651809e96a2d
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WindowingDesignLpfHpf/WindowingDesignLH.cpp Mon Nov 10 02:45:18 2014 +0000
@@ -0,0 +1,92 @@
+//------------------------------------------------------------------------------
+// Design of FIR filter of LPF and HPF using window method
+//
+// 2014/11/09, Copyright (c) 2014 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#include "WindowingDesignLH.hpp"
+
+namespace Mikami
+{
+ WindowingDesign::WindowingDesign(int order, float fs)
+ : FS_(fs), PI_FS_(3.1415926536f/fs)
+ {
+ order_ = order;
+ if ((order % 2) != 0)
+ {
+ fprintf(stderr, "order must be even.");
+ return;
+ }
+ hm_ = new float[order/2+1];
+ wn_ = new float[order/2+1];
+
+ HammWindow();
+ }
+
+ void WindowingDesign::Design(int order, Type pb, float fc,
+ float hk[])
+ {
+ if (pb == LPF) fC_ = fc;
+ if (pb == HPF) fC_ = 0.5f*FS_ - fc;
+
+ if (order != order_)
+ {
+ order_ = order_;
+ if (hm_ != NULL) delete[] hm_;
+ hm_ = new float[order/2+1];
+ if (wn_ != NULL) delete[] wn_;
+ wn_ = new float[order/2+1];
+ HammWindow();
+ }
+
+ // Calculate coefficients for LPF
+ LpfCoefficients();
+ // If HPF, transform coefficients
+ if (pb != LPF) ToHpf();
+
+ for (int k=0; k<=order/2; k++)
+ hk[k] = hm_[order/2-k];
+
+ // For compensation of gain
+ float sum = hk[order_/2];
+ if (pb == LPF)
+ for (int k=0; k<order_/2; k++)
+ sum = sum + 2.0f*hk[k];
+ if (pb == HPF)
+ {
+ float sign = -1.0;
+ for (int k=order_/2-1; k>=0; k--)
+ {
+ sum = sum + sign*2.0f*hk[k];
+ sign = -sign;
+ }
+ }
+ for (int k=0; k<=order_/2; k++)
+ hk[k] = hk[k]/sum;
+ }
+
+ // Calculation of coefficients for LPF
+ void WindowingDesign::LpfCoefficients()
+ {
+ float w = 2.0f*PI_FS_*fC_;
+ hm_[0] = 2.0f*fC_/FS_;
+ for (int k=1; k<=order_/2; k++)
+ hm_[k] = (sinf(k*w)/(PI_*k))*wn_[k];
+ }
+
+ // Transform LPF to HPF
+ void WindowingDesign::ToHpf()
+ {
+ for (int k=1; k<=order_/2; k+=2)
+ hm_[k] = -hm_[k];
+ }
+
+ // Hamming window
+ void WindowingDesign::HammWindow()
+ {
+ float pi2OvM = 2.0f*PI_/(float)(order_ + 1);
+ for (int n=0; n<=order_/2; n++)
+ wn_[n] = 0.54f + 0.46f*cosf(pi2OvM*n);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/WindowingDesignLpfHpf/WindowingDesignLH.hpp Mon Nov 10 02:45:18 2014 +0000
@@ -0,0 +1,52 @@
+//------------------------------------------------------------------------------
+// Design of FIR filter of LPF and HPF using window method -- Header
+//
+// 2014/11/09, Copyright (c) 2014 MIKAMI, Naoki
+//------------------------------------------------------------------------------
+
+#ifndef HAMMING_WINDOWING_DESIGN_HPP
+#define HAMMING_WINDOWING_DESIGN_HPP
+
+#include "mbed.h"
+
+namespace Mikami
+{
+ class WindowingDesign
+ {
+ public:
+ struct Coefs { float a1, a2, b1; };
+ enum Type { LPF, HPF };
+
+ // Constructor
+ WindowingDesign(int order, float fs);
+
+ //Destructor
+ ~WindowingDesign()
+ {
+ delete[] hm_;
+ delete[] wn_;
+ }
+
+ // Execution of design
+ void Design(int order, Type pb, float fc, float hk[]);
+
+ private:
+ static const float PI_ = 3.1415926536f;
+ const float FS_; // Sampling frequency
+ const float PI_FS_;
+
+ float *hm_; // For coefficients
+ float *wn_; // For Windwo
+
+ int order_; // Order
+ float fC_; // Cutoff frequency
+
+ // Calculation of coefficients for LPF
+ void LpfCoefficients();
+ // Transform LPF to HPF
+ void ToHpf();
+ // Hamming window
+ void HammWindow();
+ };
+}
+#endif // HAMMING_WINDOWING_DESIGN_HPP
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/main.cpp Mon Nov 10 02:45:18 2014 +0000
@@ -0,0 +1,125 @@
+//------------------------------------------------------------------
+// Cutoff frequency variable LPF and HPF by FIR 160th-order filter
+// A0: Signal to be filtered
+// A2: Value which controls cutoff frequency
+//
+// 2014/11/10, 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 "WindowingDesignLH.hpp" // for design of IIR filter
+
+using namespace Mikami;
+
+const int FS_ = 16000; // Sampling frequency: 16 kHz
+ADC_Intr myAdc_(A0, FS_, A1, A2);
+DAC_MCP4922 myDac_;
+
+const int ORDER_ = 160;
+float hm_[ORDER_/2+1];
+float xn_[ORDER_+1];
+
+DigitalIn sw1_(D2, PullDown); // 0: disable filter
+ // 1: enable filter
+DigitalIn sw2_(D3, PullDown); // 0: LPF
+ // 1: HPF
+WindowingDesign design_(ORDER_, FS_);
+DigitalOut dOut_(D7);
+
+uint16_t a2_ = 0; // Inputted data from A2 pin
+
+// Interrupt service routine for ADC
+void AdcIsr()
+{
+ dOut_.write(1);
+ xn_[0] = myAdc_.Read(); // Read from A0
+
+ myAdc_.Select3rdChannel(); // Select A2
+ myAdc_.SoftStart(); // ADC start for A2 input
+
+ //-----------------------------------------
+ // Execute FIR filter
+ float yn = hm_[ORDER_/2]*xn_[ORDER_/2];
+ for (int k=0; k<ORDER_/2; k++)
+ yn = yn + hm_[k]*(xn_[k] + xn_[ORDER_-k]);
+
+ for (int k=ORDER_; k>0; k--)
+ xn_[k] = xn_[k-1]; // move input signals
+ //-----------------------------------------
+
+ if (sw1_ == 0) myDac_.Write(xn_[0]); // 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
+ dOut_.write(0);
+}
+
+int main()
+{
+ ScfClockTim3(670000); // cutoff frequency: 6.7 kHz
+
+ WindowingDesign lpfDsgn(ORDER_, FS_);
+ Acm1602Ni lcd; // objetc for display using LCD
+
+ // Clear buffer in FIR filter
+ for (int n=0; n<=ORDER_; n++)
+ xn_[n] = 0;
+ myAdc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
+
+ float fc1 = 0;
+ WindowingDesign::Type pb = WindowingDesign::LPF;
+ while (true)
+ {
+ // fc: cutoff frequency, 100 -- 2000 Hz
+ float fc = 1900.0f*(a2_/4095.6f) + 100.0f;
+
+ if (sw1_ == 0)
+ {
+ printf("Through\r\n");
+ lcd.ClearLine(1);
+ lcd.WriteStringXY("Through ", 0, 0);
+ wait(0.2f);
+ lcd.ClearLine(0);
+ fc1 = 0;
+ }
+ else
+ {
+ 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.WriteStringXY(str, 0, 0);
+ if (sw2_ == 0)
+ {
+ pb = WindowingDesign::LPF;
+ printf("LPF\r\n");
+ lcd.WriteStringXY("LPF", 0, 1);
+ }
+ else
+ {
+ pb = WindowingDesign::HPF;
+ printf("HPF\r\n");
+ lcd.WriteStringXY("HPF", 0, 1);
+ }
+ fc1 = fc;
+
+ // Design new coefficients based on new fc
+ design_.Design(ORDER_, pb, fc1, hm_);
+ }
+ }
+ wait(0.1f);
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mbed.bld Mon Nov 10 02:45:18 2014 +0000 @@ -0,0 +1,1 @@ +http://mbed.org/users/mbed_official/code/mbed/builds/031413cf7a89 \ No newline at end of file