Несколько полезных фильтров для Arduino
- GFilterRA - компактная альтернатива фильтра экспоненциальное бегущее среднее (Running Average)
- GMedian3 - быстрый медианный фильтр 3-го порядка (отсекает выбросы)
- GMedian - медианный фильтр N-го порядка. Порядок настраивается в GyverFilters.h - MEDIAN_FILTER_SIZE
- GABfilter - альфа-бета фильтр (разновидность Калмана для одномерного случая)
- GKalman - упрощённый Калман для одномерного случая (на мой взгляд лучший из фильтров)
C++:
// ********************************** Бегущее среднее **********************************
GFilterRA(); // инициализация фильтра
GFilterRA(float coef, uint16_t interval); // расширенная инициализация фильтра (коэффициент, шаг фильтрации)
void setCoef(float coef); // настройка коэффициента фильтрации (0.00 - 1.00). Чем меньше, тем плавнее
void setStep(uint16_t interval); // установка шага фильтрации (мс). Чем меньше, тем резче фильтр
float filteredTime(int16_t value); // возвращает фильтрованное значение с опорой на встроенный таймер
float filtered(int16_t value); // возвращает фильтрованное значение
float filteredTime(float value); // возвращает фильтрованное значение с опорой на встроенный таймер
float filtered(float value); // возвращает фильтрованное значение
// ********************************** Медиана из трёх **********************************
GMedian3(); // инициализация фильтра
uint16_t filtered(uint16_t); // возвращает фильтрованное значение
// ***************** Медиана из MEDIAN_FILTER_SIZE (настраивается в GyverFilters.h) *****************
GMedian(); // инициализация фильтра
uint16_t filtered(uint16_t); // возвращает фильтрованное значение
// ********************************** Альфа-Бета фильтр **********************************
GABfilter(float delta, float sigma_process, float sigma_noise);
// период дискретизации (измерений), process variation, noise variation
void setParameters(float delta, float sigma_process, float sigma_noise);
// период дискретизации (измерений), process variation, noise variation
float filtered(float value); // возвращает фильтрованное значение
// ********************************** Упрощённый Калман **********************************
GKalman(float mea_e, float est_e, float q);
// разброс измерения, разброс оценки, скорость изменения значений
GKalman(float mea_e, float q);
// разброс измерения, скорость изменения значений (разброс измерения принимается равным разбросу оценки)
void setParameters(float mea_e, float est_e, float q);
// разброс измерения, разброс оценки, скорость изменения значений
void setParameters(float mea_e, float q);
// разброс измерения, скорость изменения значений (разброс измерения принимается равным разбросу оценки)
float filtered(float value); // возвращает фильтрованное значение
Пример бегущее среднее
C++:
#include "GyverFilters.h"
GFilterRA analog0; // фильтр назовём analog0
void setup() {
Serial.begin(9600);
// установка коэффициента фильтрации (0.0... 1.0). Чем меньше, тем плавнее фильтр
analog0.setCoef(0.01);
// установка шага фильтрации (мс). Чем меньше, тем резче фильтр
analog0.setStep(10);
}
void loop() {
Serial.println(analog0.filteredTime(analogRead(0)));
}
C++:
/*
Пример использования медианного фильтра.
Порядок фильтра настраивается в GyverHacks.h - MEDIAN_FILTER_SIZE
*/
#include "GyverFilters.h"
GMedian testFilter;
void setup() {
Serial.begin(9600);
}
void loop() {
delay(80);
int value = analogRead(0);
// добавляем шум "выбросы"
value += random(2) * random(2) * random(-1, 2) * random(50, 250);
Serial.print("$");
Serial.print(value);
Serial.print(" ");
value = testFilter.filtered(value);
Serial.print(value);
Serial.println(";");
}
C++:
/*
Сравнение калмана и бегущего среднего
*/
#include "GyverFilters.h"
// параметры: разброс измерения, разброс оценки, скорость изменения значений
// разброс измерения: шум измерений
// разброс оценки: подстраивается сам, можно поставить таким же как разброс измерения
// скорость изменения значений: 0.001-1, варьировать самому
GKalman kalman(90, 90, 0.5);
GFilterRA average(0.5, 80);
void setup() {
Serial.begin(9600);
}
void loop() {
int value = analogRead(0);
value += random(2) * random(-1, 2) * random(50, 100);
Serial.print("$");
Serial.print(value);
Serial.print(" ");
Serial.print((int)kalman.filtered(value));
Serial.print(" ");
Serial.print((int)average.filtered(value));
Serial.println(";");
delay(80);
}