Показано с 1 по 10 из 48

Тема: CODESYS 2.3 Помогите очень нужно СЧЕТЧИК ВОДЫ

Древовидный режим

Предыдущее сообщение Предыдущее сообщение   Следующее сообщение Следующее сообщение
  1. #16

    По умолчанию

    Цитата Сообщение от Сергей0308 Посмотреть сообщение
    Подобная задача в ОЛ решается элементарно
    И что считает эта схема? Без каких-то личных претензий, но как применить ваш пример для "среднего расхода за последние сутки" как-то неясно.

    Если я правильно прочитал вашу схему, то вы считаете "общее количество импульсов/общее время". Верно?
    Такой подход будет работать только при постоянной скорости. Если же расход меняется со временем, то ваш алгоритм будет показывать погоду.


    Если что, то я выше экспоненциальное сглаживание для ПЛК выложил. Оно адаптируется к изменяющимся скоростям.

    И кода там 15 строк. Открываем статью в Wikipedia, сверяем алгоритм. На всякий пожарный проверяем в симуляции.
    Наверное, это можно переделать в CFC или даже ПР, но, на мой взгляд, на ST нагляднее (да и сравнить с оригиналом в wikipedia проще).

    Код:
    PROGRAM averages
    (* https://en.wikipedia.org/wiki/Exponential_smoothing#Basic_exponential_smoothing *)
    VAR CONSTANT
      sampling_interval: REAL := 10; (* seconds, should be equal to interval in task configuration *)
    END_VAR
    VAR_OUTPUT
      last1m: REAL;
      last1h: REAL;
      last1d: REAL;
    END_VAR
    VAR
      a1m: REAL;
      a1h: REAL;
      a1d: REAL;
      prevCnt: INT;
      delta: REAL;
    END_VAR
    
    delta := (PLC_PRG.CV - prevCnt)/sampling_interval; (* current flow  ITEMS PER SECOND *)
    prevCnt := PLC_PRG.CV; (* <-- интересно, тут может возникнуть ошибка из-за того, что мы 2 раза читаем переменную PLC_PRG.CV ? *)
    
    a1m := 1-EXP(-sampling_interval/60); (* можно вычислить заранее и прямо константой забить *)
    a1h := 1-EXP(-sampling_interval/3600);
    a1d := 1-EXP(-sampling_interval/86400);
    
    last1m := a1m*delta + (1-a1m)*last1m;
    last1h := a1h*delta + (1-a1h)*last1h;
    last1d := a1d*delta + (1-a1d)*last1d;
    Код:
    PROGRAM PLC_PRG
    VAR_INPUT
     inp: BOOL;
    END_VAR
    VAR_OUTPUT
      CV: INT;
    END_VAR
    VAR
      cntr: CTU;
    END_VAR
    
    cntr(CU := inp); (* тут просто считаем импульсы *)
    CV := cntr.CV;

    Если сглаженное значение нужно довольно часто (например, раз в секунду-две-три), то можно сделать без "отдельных программ для усреднения".
    Нужно всего несколько строк и одна переменная, в которой будет хранится усреднённое значение -- avg_period:
    Код:
    period := new-old; (* т.е. время, прошедшее с прошлого раза, в миллисекундах *)
    a := 1.0 - EXP(-period / 200.0);  (* тут 200.0 мс это как раз период усреднения -- его можно менять *)
    avg_period := a*Period + (1.0-a)*avg_period; (* тут накапливается усреднение *)
    
    rate := 1000/avg_period; (* Результат, "оборотов в секунду". Что выводить в случае "деления на ноль" предлагаю рассмотреть отдельно *)
    Вот пример, как оно может выглядеть: https://docs.google.com/spreadsheets...it?usp=sharing
    Видно, что при увеличении константы результат сглаживания меняется более плавно, но медленнее.

    Если характерная частота -- 5-20Гц, то, судя по графику, значение 200 должно неплохо работать. За секунду-полторы оно "выходит на режим", и потом несильно колбасится.
    Последний раз редактировалось Владимир Ситников; 25.07.2016 в 16:48. Причина: добавил пример "усреднения в одну строку"

Похожие темы

  1. Ответов: 9
    Последнее сообщение: 07.07.2015, 19:37
  2. Ответов: 23
    Последнее сообщение: 21.02.2015, 04:32
  3. Счетчик воды РСЦ
    от mib_z в разделе Master SCADA 3
    Ответов: 1
    Последнее сообщение: 14.03.2013, 07:55
  4. Датчики бесконтактные. Очень помогите!!!
    от Антон ТТС в разделе Трёп (Курилка)
    Ответов: 1
    Последнее сообщение: 05.09.2007, 14:59

Ваши права

  • Вы не можете создавать новые темы
  • Вы не можете отвечать в темах
  • Вы не можете прикреплять вложения
  • Вы не можете редактировать свои сообщения
  •