Библиотека фильтров данных для Arduino

ОБНОВЛЕНИЯ


  • v1.6 от 12.11.2019
  • v1.7: исправлен GLinear
  • v1.8: небольшие улучшения
  • v2.0:
    • Улучшен и исправлен median и median3
    • Улучшен linear
    • Смотрите примеры! Использование этих фильтров чуть изменилось
  • v2.1: Исправлен расчёт дельты в линейном фильтре
  • v2.2: Исправлена ошибка компиляции
  • v3.0: Добавлен FastFilter и RingAverage

ТЕОРИЯ


Несколько фильтров подробно разобраны в этом уроке

БИБЛИОТЕКА


GyverFilters v3.0

GyverFilters — библиотека с некоторыми удобными фильтрами для Arduino

  • GFilterRA — компактная альтернатива фильтра экспоненциальное бегущее среднее (Running Average)
  • GMedian3 — быстрый медианный фильтр 3-го порядка (отсекает выбросы)
  • GMedian — медианный фильтр N-го порядка. Порядок настраивается в GyverFilters.h — MEDIAN_FILTER_SIZE
  • GABfilter — альфа-бета фильтр (разновидность Калмана для одномерного случая)
  • GKalman — упрощённый Калман для одномерного случая (на мой взгляд лучший из фильтров)
  • GLinear — линейная аппроксимация методом наименьших квадратов для двух массивов
  • FastFilter — быстрый целочисленный экспоненциальный фильтр
  • RingAverage — бегущее среднее с кольцевым буфером

Поддерживаемые платформы: все Arduino

УСТАНОВКА


  • Библиотеку можно найти и установить через менеджер библиотек по названию GyverFilters в:
    • Arduino IDE (Инструменты/Управлять библиотеками)
    • Arduino IDE v2 (вкладка «Library Manager»)
    • PlatformIO (PIO Home, вкладка «Libraries»)
  • Про ручную установку читай здесь

ДОКУМЕНТАЦИЯ


// ============== Бегущее среднее ==============
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);     // возвращает фильтрованное значение
// ============== Линейная аппроксимация ==============
void compute(int *x_array, int *y_array, int arrSize);    // аппроксимировать
float getA();    // получить коэффициент А
float getB();    // получить коэффициент В
float getDelta();  // получить аппроксимированное изменение

ПРИМЕРЫ


Остальные примеры смотри в папке examples библиотеки, также примеры можно открыть из Arduino IDE/Файл/Примеры

#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)));
}
/*
  Пример линейной аппроксимации методом наименьших квадратов
  Два массива: по оси Х и по оси У
  Линейная аппроксимация повозоляет получить уравнение прямой,
  равноудалённой от точек на плоскости ХУ. Удобно для расчёта
  роста изменяющейся шумящей величины. Уравнение вида у = A*x + B
  В папке с данным примером есть скриншот из excel,
  иллюстрирующий работу аппроксимации с такими же исходными
*/

// два массива с данными (одинаковой размероности и размера)
int x_array[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
int y_array[] = {1, 5, 2, 8, 3, 9, 10, 5, 15, 12};

#include 
GLinear test;    // указываем тип данных в <>

void setup() {
  Serial.begin(9600);

  // передаём массивы и размер одного из них
  test.compute((int*)x_array, (int*)y_array, 10);

  // Уравнение вида у = A*x + B
  Serial.println(test.getA());  // получить коэффициент А
  Serial.println(test.getB());  // получить коэффициент В
  Serial.println(test.getDelta());  // получить изменение (аппроксимированное)
}

void loop() {

}
/*
   Пример альфа-бета фильтра
*/

#include "GyverFilters.h"

// параметры: период дискретизации (измерений), process variation, noise variation
GABfilter testFilter(0.08, 40, 1);

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(80);
  int value = analogRead(0);
  value += random(2) * random(-1, 2) * random(10, 70);
  Serial.print("$");
  Serial.print(value);
  Serial.print(" ");
  value = testFilter.filtered((int)value);
  Serial.print(value);
  Serial.println(";");
}
/*
   Пример простого одномерного фильтра
*/

#include "GyverFilters.h"

// параметры: разброс измерения, разброс оценки, скорость изменения значений
// разброс измерения: шум измерений
// разброс оценки: подстраивается сам, можно поставить таким же как разброс измерения
// скорость изменения значений: 0.001-1, варьировать самому

GKalman testFilter(40, 40, 0.5);

// также может быть объявлен как (разброс измерения, скорость изменения значений)
// GKalman testFilter(40, 0.5);

void setup() {
  Serial.begin(9600);
}

void loop() {
  delay(80);
  int value = analogRead(0);
  value += random(2) * random(-1, 2) * random(10, 70);
  Serial.print("$");
  Serial.print(value);
  Serial.print(" ");
  value = testFilter.filtered((int)value);
  Serial.print(value);
  Serial.println(";");
}
/*
	Пример использования быстрого медианного фильтра 3 порядка
*/

#include "GyverFilters.h"
GMedian3 testFilter; 		// указываем тип данных в <>

void setup() {
  Serial.begin(9600);
}

void loop() {    
  int value = analogRead(0);
  // добавляем шум "выбросы"
  value += random(2) * random(2) * random(-1, 2) * random(50, 250);
  Serial.print(value);
  Serial.print(',');  
  value = testFilter.filtered(value);
  Serial.println(value);
  delay(80);
}

ПОДДЕРЖАТЬ


Вы можете поддержать меня за создание доступных проектов с открытым исходным кодом, полный список реквизитов есть вот здесь.

0 0 голоса
Рейтинг статьи
Подписаться
Уведомить о
guest

4 комментариев
Старые
Новые Популярные
Межтекстовые Отзывы
Посмотреть все комментарии
Прокрутить вверх