Сенсор XGZP6897A. Выбор фильтра

Здравствуйте!
ардуино , подключен дифференциальный датчик давления XGZP6897A для измерения потока воздуха в системе приточной вентиляции. Сама система представляет собой: на входе канальный вентилятор (355 м.куб/ч (190Па)), далее главный воздуховод, с него отводы через демпферы (на более меньшее ДУ) , на выходах заслонки управляемые SG90. всего таких заслонок 4 (кухня, гостиная, ванная, туалет). Суть дела вот в чем, из-за того что поток воздуха с вентилятора неравномерный, а так же влияют внешние факторы, то сигнал с датчика “пляшет” (скрин прилагается) . в скетче использую три вида фильтрации, лучше конечно, но все-равно не комильфо, хотелось бы лучше, тем более что планируется ПИД регулирование для поддержания одинакового давления в системе. Посоветуйте какую фильтрацию лучше использовать для моего случая. Спасибо!





собственно сама плата управления и заслонка на настоечном стенде.



ну и скетч:

#define DAMPER_MAX            0
#define DAMPER_MIN            99
#define DAMPER_PIN            5  //пин для сервы
#define PRESSURE_SENSOR_PIN   A1


#include <Servo.h>
Servo damper;
const float pressureCoeff = 977;   // коэффициент преобразования давления
int zeroPressure;// значение нулевого давления

void setup() {
  Serial.begin(9600);
  zeroPressure = 490;
  pinMode(DAMPER_PIN, INPUT);
  damper.attach(DAMPER_PIN);
  damper.write(DAMPER_MIN);
  delay(50);
}
float _Pressure;
void loop() {
  if (Serial.available() > 1) {
    char incoming = Serial.read();
    int value = Serial.parseInt();
    switch (incoming) {
      case 's':
        damper.write(map(value, 0, 100, DAMPER_MIN, DAMPER_MAX));
        delay(50);
        break;
      case 'z':
        zeroPressure = value;
        break;
    }
  }

  //_Pressure = (analogRead(PRESSURE_SENSOR_PIN) - zeroPressure);
  //Serial.println(_Pressure); 
  Serial.println(getPressure()); 
}


float getPressure() {
  float pressure;
  pressure = (analogRead(PRESSURE_SENSOR_PIN) - zeroPressure);
  pressure = filtered(runMiddleArifmOptim(pressure));
  pressure = expRunningAverageAdaptive(pressure);
  // Преобразуем в паскали
  float voltage = (pressure / 1023.0) * 5.0;   // преобразование значения АЦП в напряжение (В)
  pressure = voltage * pressureCoeff; // преобразование напряжения в давление в Па
  // Ограничиваем значение давления от 0 до 1000 Па
  return constrain(pressure, 0, 1000);
}


static const int NUM_READ = 32;  // количество усреднений для средних арифм. фильтров
float runMiddleArifmOptim(float newVal) {
  static int t = 0;
  static int vals[NUM_READ];
  static int average = 0;
  if (++t >= NUM_READ) t = 0; // перемотка t
  average -= vals[t];         // вычитаем старое
  average += newVal;          // прибавляем новое
  vals[t] = newVal;           // запоминаем в массив
  return (((float)average / NUM_READ) * 500) / 1024;
}
float _err_measure = 5.0;//разброс измерения
float _err_estimate = 8.0;//разброс оценки
float _q = 0.1;//скорость изменения значений
float _last_estimate = 0.0;
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;
}

// бегущее среднее с адаптивным коэффициентом
float expRunningAverageAdaptive(float newVal) {
  static float filVal = 0;
  float k;
  // резкость фильтра зависит от модуля разности значений
  if (abs(newVal - filVal) > 1.5) k = 0.9;
  else k = 0.03;

  filVal += (newVal - filVal) * k;
  return filVal;
}

И каким образом пид-регулирование будет что-то регулировать, если ты хочешь не замечать влияние внешних факторов? Вся суть регулирования в том, чтобы откликаться на эти факторы.

внешние факторы в моем случае не так важны как давление в системе. большее влияние оказывает вентилятор.

А давление отчего меняется? А вентилятор и его неравномерность это не внешний фактор?

написано же:поток воздуха с вентилятора неравномерный, а так же влияют внешние факторы… Под внешними факторами имеется ввиду сквозняк при открытии двери.
Будем обсуждать факторы, или же все-таки возможную фильтрацию сигнала?

А как такое может быть? Вентилятор дергается?

Любая крылатка вентилятора имеет лопасти и поток воздуха не постянен, т.к. вентиляционная система не имеет ресивера, а поток воздуха фактически проходит напрямую, то возникают такие помехи.

посмотреть как измеряете, сама механическая конструкция датчика

А разве скетч не понятен? На датчик есть даташит, поиск рулит.

Давай еще раз попробую. Читай ВНИМАТЕЛЬНО.

Что вы привязались к регулированию, надо решать проблемы по мере их поступления. Сейчас проблема одна, если будут другие, возможно обращусь за помощью.

Какая проблема-то? Тебе не нравится, как измеренное давление выглядит на графике? Ну нарисуй себе сам что хочешь видеть, если плевать на реальность.

для начала выяснить, правильно ли измеряется поток, какова конструкция датчика куда подключен этот девайс

Ветер на улице тоже существенно влияет.
Тут , чтобы выровнять поток воздуха надо чутко реагировать, однако предугадать порыв ветра, или хотя-бы успеть за ним та ещё задача.
Как по мне , для бытовой вентиляции достаточно усреднить показания до приемлемых значений ИМХО.
Например, увеличить количество выборок NUM_READ .

простой фильтр Калмана в гугеле поищи (simple Kalman filter github Arduino example)

А это что по вашему?:

  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;
}

По-моему, вы не умеете им пользоваться. Там надо коэффициенты подбирать, почитайте доки в репозитории откуда слили код, может получится.

Влияет, ни кто и не спорит, но влияние по времени не такое уж и значимое. Как видно из графика основной шум дают лопасти вентилятора.

Подбирал, далее сильно увеличивается время реагирования системы, хотя наверное придется жертвовать этим.

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