arduino digital filter class

最後編輯:2015-07-14 建立:2015-07-10 歷史紀錄

鄭鴻旗介紹:

因為光敏電阻讀到的數值雜訊、擾動太大,所以需要一個數位低通過濾來處理。

由林高遠編寫。

 

曾其威(VICTOR T此例中使用離散的有限脈衝響應,優點是實作簡單,缺點是要達到理想的脈衝響應需要的級數較大。

通常在嵌入式(尤其是 mcu)系統中,考慮效能會使用無限脈衝響應,級數較小但是設計較困難。

 

用在 arduino 中,若 filter coefficient(響應參數)不會改變,應該放進 PROGMEM。

此部分就交給其他勇者......

 

鄭鴻旗討論串

  • 曾其威(VICTOR Thttps://www.facebook.com/photo.php?fbid=10153036400776375&set=a.10152092316591375.1073742128.628761374&type=1&theater

 

鄭鴻旗參考資料

  • 曾其威(VICTOR Thttp://alberthuang314.blogspot.tw/2012/08/blog-post_24.html
  • https://en.wikipedia.org/wiki/Finite_impulse_response
  • 鄭鴻旗http://playground.arduino.cc/Code/Filters
  • http://playground.arduino.cc/Main/DigitalSmooth
  • http://jeroendoggen.github.io/Arduino-signal-filtering-library/
  • http://www.geek-workshop.com/thread-7694-1-1.html

 

程式碼:

  • 曾其威(VICTOR Tclass FIR
  • {
  • private:
  • int * const _sequence;
  • double const * const _response; // FIR coefficients
  • size_t const _length;
  • size_t _position;
  • public:
  • FIR(double const * const response, size_t const length):
  • _response(response), _sequence(new int[length]), _length(length), _position()
  • {
  • }
  • void push(double const value)
  • {
  • _sequence[_position] = value;
  • ++_position;
  • if(_length == _position)
  • _position = 0;
  • }
  • double const getSmoothValue()
  • {
  • double sum=0;
  • for(size_t i = 0; i < t_length ++i)
  • sum += _sequence[_position + i % _length] * _response[i];
  • return sum;
  • }
  • double pushGetSmoothValue(RESPONSE_T const value)
  • {
  • push(value);
  • return this->getSmoothValue();
  • }
  • };
  • // 我不知道這什麼通,自己想辦法生出正確的 coefficient。
  • // 給 {0.2, 0.2, 0.2, 0.2, 0.2} 就是 5 sample 的 moving average。
  • FIR lightSensorFIR({0.1, 0.15, 0.1, 0.05, 0.6}, 5);
  • int const sensorPin = A0;
  • 鄭鴻旗int const motorPin = 3;
  • 曾其威(VICTOR T
  • void setup()
  • {
  • pinMode(motorPin, OUTPUT);
  • Serial.begin(9600);
  • Serial.println(lightSensorFIR->getLength());
  • }
  • void loop()
  • {
  • int const sensorValue = analogRead(sensorPin);
  • int const val = map(sensorValue, 0, 1023, 0, 255);
  • Serial.print("Before=");
  • Serial.print(val,DEC);
  • val = lightSensorFIR.pushGetSmoothValue(val);
  • Serial.print(" Filtered=");
  • Serial.println(val,DEC);
  • if(val<130) val=0;
  • analogWrite(motorPin, val);
  • }