Skip to content

Commit

Permalink
add
Browse files Browse the repository at this point in the history
  • Loading branch information
AlexGyver committed May 25, 2021
1 parent 686d0a2 commit 0a6fd70
Show file tree
Hide file tree
Showing 24 changed files with 857 additions and 0 deletions.
139 changes: 139 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
![License: MIT](https://img.shields.io/badge/License-MIT-green.svg)
![author](https://img.shields.io/badge/author-AlexGyver-informational.svg)
# GyverFilters
GyverFilters - библиотека с некоторыми удобными фильтрами для Arduino
- GFilterRA - компактная альтернатива фильтра экспоненциальное бегущее среднее (Running Average)
- GMedian3 - быстрый медианный фильтр 3-го порядка (отсекает выбросы)
- GMedian - медианный фильтр N-го порядка. Порядок настраивается в GyverFilters.h - MEDIAN_FILTER_SIZE
- GABfilter - альфа-бета фильтр (разновидность Калмана для одномерного случая)
- GKalman - упрощённый Калман для одномерного случая (на мой взгляд лучший из фильтров)
- GLinear - линейная аппроксимация методом наименьших квадратов для двух массивов
- FastFilter - быстрый целочисленный экспоненциальный фильтр
- RingAverage - бегущее среднее с кольцевым буфером

### Совместимость
Совместима со всеми Arduino платформами (используются Arduino-функции)

### Документация
К библиотеке есть [расширенная документация](https://alexgyver.ru/GyverFilters/)

## Содержание
- [Установка](#install)
- [Инициализация](#init)
- [Использование](#usage)
- [Пример](#example)
- [Версии](#versions)
- [Баги и обратная связь](#feedback)

<a id="install"></a>
## Установка
- Библиотеку можно найти по названию **GyverFilters** и установить через менеджер библиотек в:
- Arduino IDE
- Arduino IDE v2
- PlatformIO
- [Скачать библиотеку](https://github.com/GyverLibs/GyverFilters/archive/refs/heads/main.zip) .zip архивом для ручной установки:
- Распаковать и положить в *C:\Program Files (x86)\Arduino\libraries* (Windows x64)
- Распаковать и положить в *C:\Program Files\Arduino\libraries* (Windows x32)
- Распаковать и положить в *Документы/Arduino/libraries/*
- (Arduino IDE) автоматическая установка из .zip: *Скетч/Подключить библиотеку/Добавить .ZIP библиотеку…* и указать скачанный архив
- Читай более подробную инструкцию по установке библиотек [здесь](https://alexgyver.ru/arduino-first/#%D0%A3%D1%81%D1%82%D0%B0%D0%BD%D0%BE%D0%B2%D0%BA%D0%B0_%D0%B1%D0%B8%D0%B1%D0%BB%D0%B8%D0%BE%D1%82%D0%B5%D0%BA)

<a id="init"></a>
## Инициализация
См. примеры

<a id="usage"></a>
## Использование
```cpp
// ============== Бегущее среднее ==============
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(); // получить аппроксимированное изменение
```
<a id="example"></a>
## Пример
Остальные примеры смотри в **examples**!
```cpp
/*
Пример использования медианного фильтра.
*/
#include "GyverFilters.h"
// указываем размер окна и тип данных в <>
GMedian<10, int> 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(value);
Serial.print(',');
value = testFilter.filtered(value);
Serial.println(value);
}
```

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

<a id="feedback"></a>
## Баги и обратная связь
При нахождении багов создавайте **Issue**, а лучше сразу пишите на почту [[email protected]](mailto:[email protected])
Библиотека открыта для доработки и ваших **Pull Request**'ов!
16 changes: 16 additions & 0 deletions examples/GFilterRA/GFilterRA.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
#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)));
}
32 changes: 32 additions & 0 deletions examples/GLinear_arrays/GLinear_arrays.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
/*
Пример линейной аппроксимации методом наименьших квадратов
Два массива: по оси Х и по оси У
Линейная аппроксимация повозоляет получить уравнение прямой,
равноудалённой от точек на плоскости ХУ. Удобно для расчёта
роста изменяющейся шумящей величины. Уравнение вида у = 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 <GyverFilters.h>
GLinear<int> 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() {

}
Binary file added examples/GLinear_arrays/excel.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 34 additions & 0 deletions examples/GLinear_running/GLinear_running.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/*
Пример линейной аппроксимации методом наименьших квадратов
Два массива: по оси Х и по оси У
Наполнение массивов осуществляется динамически: сдвигом и записью в крайнюю ячейку,
то есть аппроксимация по последним ARRAY_SIZE изменениям!!
*/
#define ARRAY_SIZE 10 // размер пространства для аппроксимации

// два массива с данными (одинаковой размероности и размера)
int x_array[ARRAY_SIZE] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}; // ось x от 1 до 10, допустим СЕКУНД
int y_array[ARRAY_SIZE]; // значения по оси У будем брать с датчика

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

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

void loop() {
for (byte i = 0; i < ARRAY_SIZE - 1; i++) { // счётчик от 0 до ARRAY_SIZE
y_array[i] = y_array[i + 1]; // сдвинуть массив давлений КРОМЕ ПОСЛЕДНЕЙ ЯЧЕЙКИ на шаг назад
}
// последний элемент массива теперь - новое значение (просто с аналог. датчика)
y_array[ARRAY_SIZE - 1] = analogRead(0);

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

// по нашим исходным данным это будет производная, т.е. "изменение единиц в секунду"
Serial.println(test.getDelta()); // получить изменение (аппроксимированное)

delay(1000); // секундная задержка
}
11 changes: 11 additions & 0 deletions examples/RingAverage/RingAverage.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#include "GyverFilters.h"
RingAverage<int, 50> fil;

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

void loop() {
Serial.println(fil.filtered(random(50)));
delay(10);
}
24 changes: 24 additions & 0 deletions examples/alphabeta_example/alphabeta_example.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
Пример альфа-бета фильтра
*/

#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(";");
}
16 changes: 16 additions & 0 deletions examples/fastFilter/fastFilter.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// быстрый запаздывающйи фильтр

#include <GyverFilters.h>
FastFilter fil(29); // 0-32
void setup() {
Serial.begin(9600);
fil.setK(30);
fil.setRaw(1000);
fil.setFil(0);
}

void loop() {
fil.computeNow();
Serial.println(fil.getFil());
delay(100);
}
30 changes: 30 additions & 0 deletions examples/filters_comparsion/filters_comparsion.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/*
Сравнение калмана и бегущего среднего
*/
#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);
}
31 changes: 31 additions & 0 deletions examples/kalman_example/kalman_example.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
Пример простого одномерного фильтра
*/

#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(";");
}
21 changes: 21 additions & 0 deletions examples/median3_example/median3_example.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
Пример использования быстрого медианного фильтра 3 порядка
*/

#include "GyverFilters.h"
GMedian3<int> 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);
}
23 changes: 23 additions & 0 deletions examples/median_example/median_example.ino
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
Пример использования медианного фильтра.
*/

#include "GyverFilters.h"

// указываем размер окна и тип данных в <>
GMedian<10, int> 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(value);
Serial.print(',');
value = testFilter.filtered(value);
Serial.println(value);
}
Loading

0 comments on commit 0a6fd70

Please sign in to comment.