arduino digital filter class
介紹:
因為光敏電阻讀到的數值雜訊、擾動太大,所以需要一個數位低通過濾來處理。
由林高遠編寫。
此例中使用離散的有限脈衝響應,優點是實作簡單,缺點是要達到理想的脈衝響應需要的級數較大。
通常在嵌入式(尤其是 mcu)系統中,考慮效能會使用無限脈衝響應,級數較小但是設計較困難。
用在 arduino 中,若 filter coefficient(響應參數)不會改變,應該放進 PROGMEM。
此部分就交給其他勇者......
討論串
- https://www.facebook.com/photo.php?fbid=10153036400776375&set=a.10152092316591375.1073742128.628761374&type=1&theater
參考資料
- http://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
程式碼:
- class 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(0)
- {
- }
-
- 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 < _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;
- 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);
- }