Отслеживание резких изменений переменной

Тема в разделе "Arduino & Shields", создана пользователем sanik, 20 мар 2021.

  1. sanik

    sanik Гик

    Как отсечь резкое изменение переменной за промежуток
    времени (например за 300 миллисекунд) в пределах нужного числа например если переменная
    изменилась +-8
    Пробовал так не получается, отсечка ошибок идет, но реальные показания изменяются только при повышении и то не сразу.
    Код (C++):
    static uint32_t dataTimer = 0;
      if (millis() - dataTimer > 300) {
        dataTimer = millis();
        if ((fSens == 0) && (data[6] < (old_data + 8))) { // если значение  отличается на 8 г
          print_t = old_data;
        } else if ((old_data != 0) && ((old_data + 8) < data[6])) {
          print_t = old_data;
        } else {
          print_t = data[6];
          old_data = data[6];
          fSens = 1;
        }
      }
    if (fSens == 1) { // при первом запуске присваиваем значение
        old_data = data[6];
        print_t = data[6];
        fSens = 0;
      }
     
     
    Последнее редактирование: 20 мар 2021
  2. sanik

    sanik Гик

    В реальности переменная меняется плавно
     
  3. akl

    akl Гуру

    ваще непонятно что надо делать
    но засечь величину изменения можно например так

    Код (C++):

        data[6]=param;//где-то тут получается значение этой даты (читается датчик или еще че)
        if(millis()-dataTimer > 300){
            dataTimer=millis();
            int delta = abs(data[6]-data_old);//разность по модулю
            if(delta<8){//если разность в пределах
                //делаем что надо
            }else{
                //иначе делаем что-то другое
            }
            data_old=data[6];//запоминаем значение
        }
     
    но не факт что это то что надо, если надо сглаживать шум или типа того то лучше наверно усреднять сколько-то последовательных значений
     
    Airbus нравится это.
  4. Airbus

    Airbus Радиохулиган Модератор

    У меня отслеживает расстояние по УЗ датчегу и если больше гистерезиса то включает свет. Ну и код примерно такой же. Только dataTimer=millis() у меня в конце
     
  5. sanik

    sanik Гик

    Спасибо! но маленько не то Допустим data[6] это температура 20 градусов, приходит по радио сигналу в общем не важно как она приходит data_old это и есть delta , Данные приходят нормально но время от времени вместо 20 проскакивает 0 или 64 что вообще не допустимо Температура например не может резко упасть или увеличиться изменения идут плавно причем плавно в плюсовое значение или в минусовое ниже нуля. задача в том что нужно отсечь эти ложные значения и следить за плавным изменением.
     
  6. Igor68

    Igor68 Гуру

    ...массив измеренных значений. Новое измерение - другой адрес этого значения в массиве. Запись в массив по "кольцу".
    Среднее значение (среднеарифметическое) - это истинная величина. Регистрация ошибочных отклонений для исключения "плохой" записи в массив по заданной предельной разнице истинного значения и текущего измеренного(если надо).
    Инициализация массива - несколько реально измеренных(исходя из размера массива - заполнение).

    Этот вариант так же подходит для определения постоянной составляющей, выделение переменной составляющей, амплитудное значение и прочее. Давно это использую в приборе (контролирую/поддерживаю форму выходного сигнала при разной нагрузке, измеряю действующее значение переменного напряжения этого напряжения)
     
  7. akl

    akl Гуру

    вот самый простой вариант. тупо отбрасывает все сильно отличающиеся показания до тех пор пока они не придут 5 раз подряд. если выбросы единичные, то должно работать. если же будет 5 подряд хаотичных выбросов - начнет врать. но регулярные 5 подряд бредовых значений это уже повод пересмотреть всю систему
    Код (C++):

        static char n=0;//переменная счетчик
        if(millis()-dataTimer > 300){
            dataTimer=millis();
            int delta = abs(data[6]-data_old);//разность по модулю
            if(delta<10){//если разность в пределах +-10
                data_old=data[6];//сохраняем
                n=0;//обнуляем счетчик
            }else{//если новое значение отличается больше чем на 10
                n++;//прибавляем счетчик
                if(n<5){//пока не досчитало до 5
                    data[6]=data_old;//отбрасываем и заменяем предыдущим значением
                }
                else{//досчитало до 5 - значит идут стабильные новые показания
                    data_old=data[6];//сохраняем их как корректные
                }
            }
        }
     
    но лучше сделать как Игорь написал - но это сложнее, я как раз примерно что-то такое хотел запилить с усреднением и отбрасыванием крайностей, но стало лень, так что давай сам. там еще всякую матстатистику можно применить - непочатый край мозголюбства.
     
    sanik нравится это.
  8. sanik

    sanik Гик

    Спасибо подтолкнул на мысль буду юзать.
     
  9. akl

    akl Гуру

    это в любом случае костыль который не будет работать надежно. если данные приходят по радиосигналу, то правильно будет сделать протокол с проверкой целостности этих данных. контрольная сумма или хотя бы просто дублирование.
     
  10. Asper Daffy

    Asper Daffy Иксперд

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

    Что касается ошибок, то, в первую очередь, ты должен твёрдо знать что это за ошибки - ошибки измерения или ошибки передачи (проведи тесты и убедись - это надо знать точно, чтобы не бороться с несуществующей проблемой). Если это ошибки передачи, то, по мне, лучше использовать протокол передачи с коррекцией ошибок и не париться.
     
  11. parovoZZ

    parovoZZ Гуру

    читай про медианное усреднение. Лично я сортирую массив при вставке числа. Это позволяет взять медиану в произвольное время.
     
  12. sanik

    sanik Гик

    Ошибки при приеме!
     
  13. Asper Daffy

    Asper Daffy Иксперд

    Ну, раз при приёме, то можно использовать ECC. Ссылку я дал в #10
     
  14. akl

    akl Гуру

    если это температура, то что за датчик? не каждый датчик можно опрашивать 3 раза в секунду
     
  15. sanik

    sanik Гик

    3 раза в секунду проверяются данные пришедшие с радиоканала.
     
  16. parovoZZ

    parovoZZ Гуру

    а что за агрегат, в котором так быстро может смениться температура???
     
  17. sanik

    sanik Гик

    Оказалось все таки сам датчик выдает такой бред!