Adaptive line enhancer (ALE) using leaky LMS algorithm. Step size parameter can be controled using input voltage of AD converter.

Dependencies:   UITDSP_ADDA UIT_ACM1602NI UIT_AQM1602 mbed

Committer:
MikamiUitOpen
Date:
Sat Jul 25 12:54:37 2015 +0000
Revision:
0:f81c448ea76b
1

Who changed what in which revision?

UserRevisionLine numberNew contents of line
MikamiUitOpen 0:f81c448ea76b 1 //--------------------------------------------------------------
MikamiUitOpen 0:f81c448ea76b 2 // FIR フィルタによる適応線スペクトル強調器(ALE)
MikamiUitOpen 0:f81c448ea76b 3 // アルゴリズム: Leaky LMS
MikamiUitOpen 0:f81c448ea76b 4 //
MikamiUitOpen 0:f81c448ea76b 5 // VR でステップサイズ・パラメータを 10^-5 ~ 10^-2 の範囲で変更できます.
MikamiUitOpen 0:f81c448ea76b 6 // ステップサイズ・パラメータが大きすぎると出力が発散する場合があります.
MikamiUitOpen 0:f81c448ea76b 7 // そのような場合は,ステップサイズ・パラメータを小さくした後,リセットボタ
MikamiUitOpen 0:f81c448ea76b 8 // ンを押してください.
MikamiUitOpen 0:f81c448ea76b 9 //
MikamiUitOpen 0:f81c448ea76b 10 // A0: 雑音の混入した周期信号
MikamiUitOpen 0:f81c448ea76b 11 // A2: ステップサイズ・パラメータ(μ)を変更するための入力
MikamiUitOpen 0:f81c448ea76b 12 // 出力: MCP4921 または MCP4922
MikamiUitOpen 0:f81c448ea76b 13 // 2015/07/13, Copyright (c) 2015 MIKAMI, Naoki
MikamiUitOpen 0:f81c448ea76b 14 //--------------------------------------------------------------
MikamiUitOpen 0:f81c448ea76b 15
MikamiUitOpen 0:f81c448ea76b 16 #include "ADC_Interrupt.hpp" // for ADC using interrupt
MikamiUitOpen 0:f81c448ea76b 17 #include "DAC_MCP4921.hpp" // for DAC MCP4921, MCP4922
MikamiUitOpen 0:f81c448ea76b 18
MikamiUitOpen 0:f81c448ea76b 19 using namespace Mikami;
MikamiUitOpen 0:f81c448ea76b 20 const int FS_ = 16000; // Sampling frequency: 16 kHz
MikamiUitOpen 0:f81c448ea76b 21 ADC_Intr myAdc_(A0, FS_, A1, A2); // for AD
MikamiUitOpen 0:f81c448ea76b 22 DAC_MCP4921 myDac_; // for DA
MikamiUitOpen 0:f81c448ea76b 23 DigitalIn sw_(D2, PullDown);
MikamiUitOpen 0:f81c448ea76b 24
MikamiUitOpen 0:f81c448ea76b 25 // ACM1602Ni を使う場合は次の define 文をコメントにすること
MikamiUitOpen 0:f81c448ea76b 26 #define AQM1602
MikamiUitOpen 0:f81c448ea76b 27
MikamiUitOpen 0:f81c448ea76b 28 #ifdef AQM1602
MikamiUitOpen 0:f81c448ea76b 29 #include "AQM1602.hpp"
MikamiUitOpen 0:f81c448ea76b 30 Aqm1602 Lcd_;
MikamiUitOpen 0:f81c448ea76b 31 #else
MikamiUitOpen 0:f81c448ea76b 32 #include "ACM1602NI.hpp"
MikamiUitOpen 0:f81c448ea76b 33 Acm1602Ni Lcd_;
MikamiUitOpen 0:f81c448ea76b 34 #endif
MikamiUitOpen 0:f81c448ea76b 35
MikamiUitOpen 0:f81c448ea76b 36 const int ORDER_ = 100; // Order of FIR filter
MikamiUitOpen 0:f81c448ea76b 37 const int DELAY_ = 5; // Number of delay to reduce correlation
MikamiUitOpen 0:f81c448ea76b 38 const int N_ALL_ = ORDER_ + DELAY_ + 1;
MikamiUitOpen 0:f81c448ea76b 39
MikamiUitOpen 0:f81c448ea76b 40 float mu_; // Step size parameter (μ)
MikamiUitOpen 0:f81c448ea76b 41 float err_mu_; // error*μ;
MikamiUitOpen 0:f81c448ea76b 42 uint16_t a2_ = 0; // Inputted data from A2 pin
MikamiUitOpen 0:f81c448ea76b 43 float xn_[N_ALL_], hm_[ORDER_+1];
MikamiUitOpen 0:f81c448ea76b 44
MikamiUitOpen 0:f81c448ea76b 45 // Interrupt service routine for ADC
MikamiUitOpen 0:f81c448ea76b 46 void AdcIsr()
MikamiUitOpen 0:f81c448ea76b 47 {
MikamiUitOpen 0:f81c448ea76b 48 const float GAMMA = 0.996f;
MikamiUitOpen 0:f81c448ea76b 49 xn_[0] = myAdc_.Read(); // Read from A0
MikamiUitOpen 0:f81c448ea76b 50
MikamiUitOpen 0:f81c448ea76b 51 myAdc_.Select3rdChannel(); // Select A2
MikamiUitOpen 0:f81c448ea76b 52 myAdc_.SoftStart(); // ADC start for A2 input
MikamiUitOpen 0:f81c448ea76b 53
MikamiUitOpen 0:f81c448ea76b 54 //-----------------------------------------
MikamiUitOpen 0:f81c448ea76b 55 // ALE の処理
MikamiUitOpen 0:f81c448ea76b 56
MikamiUitOpen 0:f81c448ea76b 57 // FIR フィルタの実行
MikamiUitOpen 0:f81c448ea76b 58 float yn = 0;
MikamiUitOpen 0:f81c448ea76b 59 for (int k=0; k<=ORDER_; k++)
MikamiUitOpen 0:f81c448ea76b 60 yn = yn + hm_[k]*xn_[k+DELAY_];
MikamiUitOpen 0:f81c448ea76b 61
MikamiUitOpen 0:f81c448ea76b 62 // 係数の更新
MikamiUitOpen 0:f81c448ea76b 63 err_mu_ = (xn_[0] - yn)*mu_;
MikamiUitOpen 0:f81c448ea76b 64 for (int k=0; k<=ORDER_; k++)
MikamiUitOpen 0:f81c448ea76b 65 hm_[k] = GAMMA*hm_[k] + err_mu_*xn_[k+DELAY_];
MikamiUitOpen 0:f81c448ea76b 66
MikamiUitOpen 0:f81c448ea76b 67 // FIR フィルタの遅延器および相関除去用遅延器のデータの移動
MikamiUitOpen 0:f81c448ea76b 68 for (int k=N_ALL_-1; k>0; k--)
MikamiUitOpen 0:f81c448ea76b 69 xn_[k] = xn_[k-1];
MikamiUitOpen 0:f81c448ea76b 70 //-----------------------------------------
MikamiUitOpen 0:f81c448ea76b 71 if ((sw_ & 0x01) == 0)
MikamiUitOpen 0:f81c448ea76b 72 myDac_.Write(xn_[0]); // 入力をそのまま出力
MikamiUitOpen 0:f81c448ea76b 73 else
MikamiUitOpen 0:f81c448ea76b 74 myDac_.Write(yn); // ALE の結果を出力
MikamiUitOpen 0:f81c448ea76b 75
MikamiUitOpen 0:f81c448ea76b 76 // μを変更するための値を読み込む
MikamiUitOpen 0:f81c448ea76b 77 a2_ = myAdc_.ReadWait_u16();
MikamiUitOpen 0:f81c448ea76b 78
MikamiUitOpen 0:f81c448ea76b 79 myAdc_.Select1stChannel(); // Select A0
MikamiUitOpen 0:f81c448ea76b 80 myAdc_.ClearPending_EnableIRQ();// Clear pending interrupt
MikamiUitOpen 0:f81c448ea76b 81 // and enable ADC_IRQn
MikamiUitOpen 0:f81c448ea76b 82 }
MikamiUitOpen 0:f81c448ea76b 83
MikamiUitOpen 0:f81c448ea76b 84 int main()
MikamiUitOpen 0:f81c448ea76b 85 {
MikamiUitOpen 0:f81c448ea76b 86 myDac_.ScfClockTim3(500000); // cutoff frequency: 5 kHz
MikamiUitOpen 0:f81c448ea76b 87 Lcd_.Clear();
MikamiUitOpen 0:f81c448ea76b 88 Lcd_.WriteStringXY("ALE", 0, 0);
MikamiUitOpen 0:f81c448ea76b 89 printf("\r\nAdaptive Line Enhancer\r\n");
MikamiUitOpen 0:f81c448ea76b 90
MikamiUitOpen 0:f81c448ea76b 91 for (int n=0; n<N_ALL_; n++) xn_[n] = 0;
MikamiUitOpen 0:f81c448ea76b 92 for (int n=0; n<=ORDER_; n++) hm_[n] = 0;
MikamiUitOpen 0:f81c448ea76b 93
MikamiUitOpen 0:f81c448ea76b 94 myAdc_.SetIntrVec(AdcIsr); // Assign ISR for ADC interrupt
MikamiUitOpen 0:f81c448ea76b 95
MikamiUitOpen 0:f81c448ea76b 96 while (true)
MikamiUitOpen 0:f81c448ea76b 97 {
MikamiUitOpen 0:f81c448ea76b 98 // VR から読み込んだ値でμを変更する
MikamiUitOpen 0:f81c448ea76b 99 float power = 3.0f*a2_/4095.0f - 5;
MikamiUitOpen 0:f81c448ea76b 100 mu_ = powf(10.0f, power);
MikamiUitOpen 0:f81c448ea76b 101
MikamiUitOpen 0:f81c448ea76b 102 printf("mu = %8.2e, error*mu = %8.2e\r\n", mu_, err_mu_);
MikamiUitOpen 0:f81c448ea76b 103
MikamiUitOpen 0:f81c448ea76b 104 char str[17];
MikamiUitOpen 0:f81c448ea76b 105 sprintf(str, "mu: %8.2e", mu_);
MikamiUitOpen 0:f81c448ea76b 106 Lcd_.WriteStringXY(str, 0, 1);
MikamiUitOpen 0:f81c448ea76b 107
MikamiUitOpen 0:f81c448ea76b 108 wait(0.5f);
MikamiUitOpen 0:f81c448ea76b 109 }
MikamiUitOpen 0:f81c448ea76b 110 }
MikamiUitOpen 0:f81c448ea76b 111