mirror of
https://github.com/IoTManagerProject/IoTManager.git
synced 2026-03-26 22:22:16 +03:00
full size test
This commit is contained in:
16
lib/GyverFilters/examples/GFilterRA/GFilterRA.ino
Normal file
16
lib/GyverFilters/examples/GFilterRA/GFilterRA.ino
Normal file
@@ -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
lib/GyverFilters/examples/GLinear_arrays/GLinear_arrays.ino
Normal file
32
lib/GyverFilters/examples/GLinear_arrays/GLinear_arrays.ino
Normal file
@@ -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, sizeof(x_array));
|
||||
|
||||
// Уравнение вида у = A*x + B
|
||||
Serial.println(test.getA()); // получить коэффициент А
|
||||
Serial.println(test.getB()); // получить коэффициент В
|
||||
Serial.println(test.getDelta()); // получить изменение (аппроксимированное)
|
||||
}
|
||||
|
||||
void loop() {
|
||||
|
||||
}
|
||||
BIN
lib/GyverFilters/examples/GLinear_arrays/excel.jpg
Normal file
BIN
lib/GyverFilters/examples/GLinear_arrays/excel.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 48 KiB |
@@ -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); // секундная задержка
|
||||
}
|
||||
@@ -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(";");
|
||||
}
|
||||
@@ -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
lib/GyverFilters/examples/kalman_example/kalman_example.ino
Normal file
31
lib/GyverFilters/examples/kalman_example/kalman_example.ino
Normal file
@@ -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(";");
|
||||
}
|
||||
@@ -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
lib/GyverFilters/examples/median_example/median_example.ino
Normal file
23
lib/GyverFilters/examples/median_example/median_example.ino
Normal file
@@ -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);
|
||||
}
|
||||
28
lib/GyverFilters/keywords.txt
Normal file
28
lib/GyverFilters/keywords.txt
Normal file
@@ -0,0 +1,28 @@
|
||||
#######################################
|
||||
# Syntax Coloring Map For GyverFilters
|
||||
#######################################
|
||||
|
||||
#######################################
|
||||
# Datatypes (KEYWORD1)
|
||||
#######################################
|
||||
|
||||
GyverFilters KEYWORD1
|
||||
GFilterRA KEYWORD1
|
||||
GMedian3 KEYWORD1
|
||||
GMedian KEYWORD1
|
||||
GABfilter KEYWORD1
|
||||
GKalman KEYWORD1
|
||||
GLinear KEYWORD1
|
||||
|
||||
#######################################
|
||||
# Methods and Functions (KEYWORD2)
|
||||
#######################################
|
||||
|
||||
setCoef KEYWORD2
|
||||
setStep KEYWORD2
|
||||
filteredTime KEYWORD2
|
||||
filtered KEYWORD2
|
||||
setParameters KEYWORD2
|
||||
getA KEYWORD2
|
||||
getB KEYWORD2
|
||||
getDelta KEYWORD2
|
||||
9
lib/GyverFilters/library.properties
Normal file
9
lib/GyverFilters/library.properties
Normal file
@@ -0,0 +1,9 @@
|
||||
name=GyverFilters
|
||||
version=2.0
|
||||
author=AlexGyver <beragumbo@ya.ru>
|
||||
maintainer=AlexGyver <beragumbo@ya.ru>
|
||||
sentence=Library with few filters for data.
|
||||
paragraph=Includes median, running average, AB, simplified Kalman and linear approximation filtering algorithms.
|
||||
category=Data Processing
|
||||
url=https://github.com/AlexGyver/GyverLibs
|
||||
architectures=*
|
||||
26
lib/GyverFilters/src/GyverFilters.h
Normal file
26
lib/GyverFilters/src/GyverFilters.h
Normal file
@@ -0,0 +1,26 @@
|
||||
#pragma once
|
||||
#include <filters/alfaBeta.h>
|
||||
#include <filters/kalman.h>
|
||||
#include <filters/linear.h>
|
||||
#include <filters/median.h>
|
||||
#include <filters/median3.h>
|
||||
#include <filters/runningAverage.h>
|
||||
|
||||
/*
|
||||
GyverFilters - библиотека с некоторыми удобными фильтрами:
|
||||
- GFilterRA - компактная альтернатива фильтра экспоненциальное бегущее среднее (Running Average)
|
||||
- GMedian3 - быстрый медианный фильтр 3-го порядка (отсекает выбросы)
|
||||
- GMedian - медианный фильтр N-го порядка. Порядок настраивается в GyverFilters.h - MEDIAN_FILTER_SIZE
|
||||
- GABfilter - альфа-бета фильтр (разновидность Калмана для одномерного случая)
|
||||
- GKalman - упрощённый Калман для одномерного случая (на мой взгляд лучший из фильтров)
|
||||
- GLinear - линейная аппроксимация методом наименьших квадратов для двух массивов
|
||||
|
||||
Версии
|
||||
- 1.6 от 12.11.2019
|
||||
- 1.7: исправлен GLinear
|
||||
- 1.8: небольшие улучшения
|
||||
- 2.0:
|
||||
- Улучшен и исправлен median и median3
|
||||
- Улучшен linear
|
||||
- Смотрите примеры! Использование этих фильтров чуть изменилось
|
||||
*/
|
||||
37
lib/GyverFilters/src/filters/alfaBeta.h
Normal file
37
lib/GyverFilters/src/filters/alfaBeta.h
Normal file
@@ -0,0 +1,37 @@
|
||||
#pragma once
|
||||
#include <math.h>
|
||||
|
||||
// альфа-бета фильтр
|
||||
class GABfilter {
|
||||
public:
|
||||
// период дискретизации (измерений), process variation, noise variation
|
||||
GABfilter(float delta, float sigma_process, float sigma_noise) {setParameters(delta, sigma_process, sigma_noise);}
|
||||
|
||||
// период дискретизации (измерений), process variation, noise variation
|
||||
void setParameters(float delta, float sigma_process, float sigma_noise) {
|
||||
dt = delta;
|
||||
float lambda = (float)sigma_process * dt * dt / sigma_noise;
|
||||
float r = (4 + lambda - (float)sqrt(8 * lambda + lambda * lambda)) / 4;
|
||||
a = (float)1 - r * r;
|
||||
b = (float)2 * (2 - a) - 4 * (float)sqrt(1 - a);
|
||||
}
|
||||
|
||||
// возвращает фильтрованное значение
|
||||
float filtered(float value) {
|
||||
xm = value;
|
||||
xk = xk_1 + ((float) vk_1 * dt );
|
||||
vk = vk_1;
|
||||
rk = xm - xk;
|
||||
xk += (float)a * rk;
|
||||
vk += (float)( b * rk ) / dt;
|
||||
xk_1 = xk;
|
||||
vk_1 = vk;
|
||||
return xk_1;
|
||||
}
|
||||
|
||||
private:
|
||||
float dt;
|
||||
float xk_1, vk_1, a, b;
|
||||
float xk, vk, rk;
|
||||
float xm;
|
||||
};
|
||||
38
lib/GyverFilters/src/filters/kalman.h
Normal file
38
lib/GyverFilters/src/filters/kalman.h
Normal file
@@ -0,0 +1,38 @@
|
||||
#pragma once
|
||||
#include <math.h>
|
||||
|
||||
// упрощённый Калман для одномерного случая
|
||||
class GKalman {
|
||||
public:
|
||||
// разброс измерения, разброс оценки, скорость изменения значений
|
||||
GKalman(float mea_e, float est_e, float q) { setParameters(mea_e, est_e, q); }
|
||||
|
||||
// разброс измерения, скорость изменения значений (разброс измерения принимается равным разбросу оценки)
|
||||
GKalman(float mea_e, float q) {GKalman::setParameters(mea_e, mea_e, q);}
|
||||
|
||||
// разброс измерения, разброс оценки, скорость изменения значений
|
||||
void setParameters(float mea_e, float est_e, float q) {
|
||||
_err_measure = mea_e;
|
||||
_err_estimate = est_e;
|
||||
_q = q;
|
||||
}
|
||||
|
||||
// разброс измерения, скорость изменения значений (разброс измерения принимается равным разбросу оценки)
|
||||
void setParameters(float mea_e, float q) {setParameters(mea_e, mea_e, q);}
|
||||
|
||||
// возвращает фильтрованное значение
|
||||
float filtered(float value) {
|
||||
float _kalman_gain, _current_estimate;
|
||||
_kalman_gain = _err_estimate / (_err_estimate + _err_measure);
|
||||
_current_estimate = _last_estimate + _kalman_gain * (value - _last_estimate);
|
||||
_err_estimate = (1.0 - _kalman_gain)*_err_estimate + fabs(_last_estimate-_current_estimate)*_q;
|
||||
_last_estimate=_current_estimate;
|
||||
return _current_estimate;
|
||||
}
|
||||
|
||||
private:
|
||||
float _err_measure = 0.0;
|
||||
float _err_estimate = 0.0;
|
||||
float _q = 0.0;
|
||||
float _last_estimate = 0.0;
|
||||
};
|
||||
30
lib/GyverFilters/src/filters/linear.h
Normal file
30
lib/GyverFilters/src/filters/linear.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
// линейная аппроксимация методом наименьших квадратов
|
||||
template < typename TYPE >
|
||||
class GLinear {
|
||||
public:
|
||||
GLinear(){};
|
||||
void compute(TYPE *x_array, TYPE *y_array, int arrSize) { // аппроксимировать
|
||||
int32_t sumX = 0, sumY = 0, sumX2 = 0, sumXY = 0;
|
||||
arrSize /= sizeof(int);
|
||||
for (int i = 0; i < arrSize; i++) { // для всех элементов массива
|
||||
sumX += x_array[i];
|
||||
sumY += (long)y_array[i];
|
||||
sumX2 += x_array[i] * x_array[i];
|
||||
sumXY += (long)y_array[i] * x_array[i];
|
||||
}
|
||||
a = (long)arrSize * sumXY; // расчёт коэффициента наклона приямой
|
||||
a = a - (long)sumX * sumY;
|
||||
a = (float)a / (arrSize * sumX2 - sumX * sumX);
|
||||
b = (float)(sumY - (float)a * sumX) / arrSize;
|
||||
delta = a * arrSize; // расчёт изменения
|
||||
}
|
||||
float getA() {return a;} // получить коэффициент А
|
||||
float getB() {return b;} // получить коэффициент В
|
||||
float getDelta() {return delta;} // получить аппроксимированное изменение
|
||||
|
||||
private:
|
||||
float a, b, delta;
|
||||
};
|
||||
35
lib/GyverFilters/src/filters/median.h
Normal file
35
lib/GyverFilters/src/filters/median.h
Normal file
@@ -0,0 +1,35 @@
|
||||
#pragma once
|
||||
|
||||
// медианный фильтр N-го порядка
|
||||
template < int SIZE, typename TYPE >
|
||||
class GMedian {
|
||||
public:
|
||||
TYPE filtered(TYPE newVal) {
|
||||
buffer[_count] = newVal;
|
||||
if ((_count < _numRead - 1) && (buffer[_count] > buffer[_count + 1])) {
|
||||
for (int i = _count; i < _numRead - 1; i++) {
|
||||
if (buffer[i] > buffer[i + 1]) {
|
||||
float buff = buffer[i];
|
||||
buffer[i] = buffer[i + 1];
|
||||
buffer[i + 1] = buff;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if ((_count > 0) and (buffer[_count - 1] > buffer[_count])) {
|
||||
for (int i = _count; i > 0; i--) {
|
||||
if (buffer[i] < buffer[i - 1]) {
|
||||
float buff = buffer[i];
|
||||
buffer[i] = buffer[i - 1];
|
||||
buffer[i - 1] = buff;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (++_count >= _numRead) _count = 0;
|
||||
return buffer[(int)_numRead / 2];
|
||||
}
|
||||
private:
|
||||
TYPE buffer[SIZE];
|
||||
byte _count = 0;
|
||||
byte _numRead = SIZE;
|
||||
};
|
||||
30
lib/GyverFilters/src/filters/median3.h
Normal file
30
lib/GyverFilters/src/filters/median3.h
Normal file
@@ -0,0 +1,30 @@
|
||||
#pragma once
|
||||
|
||||
// быстрый медианный фильтр 3-го порядка
|
||||
template < typename TYPE >
|
||||
class GMedian3 {
|
||||
public:
|
||||
TYPE filtered(TYPE value) { // возвращает фильтрованное значение
|
||||
buffer[_counter] = value;
|
||||
if (++_counter > 2) _counter = 0;
|
||||
|
||||
TYPE middle;
|
||||
|
||||
if ((buffer[0] <= buffer[1]) && (buffer[0] <= buffer[2])) {
|
||||
middle = (buffer[1] <= buffer[2]) ? buffer[1] : buffer[2];
|
||||
}
|
||||
else {
|
||||
if ((buffer[1] <= buffer[0]) && (buffer[1] <= buffer[2])) {
|
||||
middle = (buffer[0] <= buffer[2]) ? buffer[0] : buffer[2];
|
||||
}
|
||||
else {
|
||||
middle = (buffer[0] <= buffer[1]) ? buffer[0] : buffer[1];
|
||||
}
|
||||
}
|
||||
return middle;
|
||||
}
|
||||
|
||||
private:
|
||||
TYPE buffer[3];
|
||||
uint8_t _counter = 0;
|
||||
};
|
||||
43
lib/GyverFilters/src/filters/runningAverage.cpp
Normal file
43
lib/GyverFilters/src/filters/runningAverage.cpp
Normal file
@@ -0,0 +1,43 @@
|
||||
#include <filters/runningAverage.h>
|
||||
|
||||
GFilterRA::GFilterRA() {}
|
||||
|
||||
GFilterRA::GFilterRA(float coef, uint16_t interval) {
|
||||
_coef = coef;
|
||||
_filterInterval = interval;
|
||||
}
|
||||
|
||||
GFilterRA::GFilterRA(float coef) {
|
||||
_coef = coef;
|
||||
}
|
||||
|
||||
void GFilterRA::setCoef(float coef) {
|
||||
_coef = coef;
|
||||
}
|
||||
void GFilterRA::setStep(uint16_t interval) {
|
||||
_filterInterval = interval;
|
||||
}
|
||||
|
||||
float GFilterRA::filteredTime(int16_t value) {
|
||||
if (millis() - _filterTimer >= _filterInterval) {
|
||||
_filterTimer = millis();
|
||||
return GFilterRA::filtered(value);
|
||||
}
|
||||
}
|
||||
|
||||
float GFilterRA::filteredTime(float value) {
|
||||
if (millis() - _filterTimer >= _filterInterval) {
|
||||
_filterTimer = millis();
|
||||
return GFilterRA::filtered(value);
|
||||
}
|
||||
}
|
||||
|
||||
float GFilterRA::filtered(int16_t value) {
|
||||
_lastValue += (float)(value - _lastValue) * _coef;
|
||||
return _lastValue;
|
||||
}
|
||||
|
||||
float GFilterRA::filtered(float value) {
|
||||
_lastValue += (float)(value - _lastValue) * _coef;
|
||||
return _lastValue;
|
||||
}
|
||||
24
lib/GyverFilters/src/filters/runningAverage.h
Normal file
24
lib/GyverFilters/src/filters/runningAverage.h
Normal file
@@ -0,0 +1,24 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
// экспоненциальное бегущее среднее
|
||||
class GFilterRA
|
||||
{
|
||||
public:
|
||||
GFilterRA(); // инициализация фильтра
|
||||
GFilterRA(float coef); // расширенная инициализация фильтра (коэффициент)
|
||||
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); // возвращает фильтрованное значение
|
||||
|
||||
private:
|
||||
float _coef = 0.0, _lastValue = 0.0;
|
||||
uint32_t _filterTimer = 0;
|
||||
uint16_t _filterInterval = 0;
|
||||
};
|
||||
Reference in New Issue
Block a user