Простейшие программы на Rapid Scada

Просмотр 9 сообщений - с 61 по 69 (из 69 всего)
  • Автор
    Сообщения
  • #2176
    MikhailMikhail
    Модератор

    замените на object

    #2211
    djbond07djbond07
    Участник

    Добрый день! Реализую задачу подсчёта времени работы насоса. Эта тема как-то поднималась уже, но однозначного ответа вроде как не получилось.
    В общем объясню пошагово что сделал.
    1. Завёл переменную Sbros1 — это флаг сброса счётчика времени. (1-сбрасываем, 0-нет)
    2. Завёл канал управления, №10 допустим, с формулой для сброса

    public double Sbros1Upr()
    {
    int f = Sbros1;
    Sbros1 = 1;
    return f;
    return double.NaN;
    }

    3. Завёл канал минутный ТИ в котором считается количество минут работы. В нём формула: (Val(293)>0?Val()+1:Val())*Sbros1Inp()
    И сама формула Sbros1Inp() выглядит так

    public int Sbros1Inp()
    {
    int f = Sbros11;
    if (Sbros1>0) {Sbros11=0;}
    else {Sbros11=1;}
    return f;
    }

    В итоге имею следующее. При включении насоса начинается отсчёт времени, всё работает. Если отправить команду на канал управления №10, то значение сбрасывается. Но если после этого включить насос снова, то отсчёт времени не происходит, имею просто «0».
    Как мне подправить формулы, чтобы после сброса время работы опять считалось?

    #2212
    EvgenEvgen
    Участник

    Здравствуйте!
    Я не конца решил эту проблему, Мое решение не красивое и не удобное.
    Поясняю:
    в моем решении приходится канал управления вводить 2 раза.
    1 раз задаем время работы до следующего ППР второй раз канал управления присваиваем «0».
    Если Вам подойдет такое решение могу поделится.

    #2213
    MikhailMikhail
    Модератор

    Для отладки Вы можете добавить функцию записи в лог.

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

    #2214
    djbond07djbond07
    Участник

    Evgen, поделитесь, пожалуйста. Некрасивое решение лучше, чем его отсутствие.

    #2216
    EvgenEvgen
    Участник

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

    djbond07
    Учет времени работы с точностью до минуты!

    Я сделал следующие функции:
    Словарь для минут
    public Dictionary<int, DateTime> MinuteBegDict = new Dictionary<int, DateTime>();

    Функция которая возвращает true в начале каждой минуты
    public bool MinuteBeg() //возвращает единицу в начале минуты
    {
    DateTime nowDT = DateTime.Now; //текущая дата
    DateTime execDT; //дата которая вытягивается из словаря
    if (!MinuteBegDict.TryGetValue(CnlNum, out execDT) || execDT.Minute != nowDT.Minute)
    {
    MinuteBegDict[CnlNum] = nowDT;
    return true;
    }
    else
    {
    return false;
    }
    }

    Это на форуме выложил Михаил:
    Словарь передачи значения с канала управления во входной канал
    public Dictionary<int, double> CnlValDict = new Dictionary<int, double>();

    Функция присвоения значения канала управления входному каналу
    public double CnlValGet(int cnlNum)
    {
    double val;
    return CnlValDict.TryGetValue(cnlNum, out val) ?
    val : Val(cnlNum);
    }

    Функция передачи серверу значения канала управления
    public double CnlValSet(int cnlNum)
    {
    CnlValDict[cnlNum] = Cmd;
    return double.NaN;
    }

    И сама функция учета времени работы (У меня до следующего ппр)
    public double VremyaRab(int CnlNumI, int CnlNumBut)
    //время работы привода с током CnlNumI и кнопкой CnlNumBut
    {
    bool m = MinuteBeg(); //начало новой минуты
    double Z = Val(CnlNum); //текущее время работы в минутах

    double V = Val(CnlNum) * 60; //текущее время работы в минутах

    if (m) //если начало новой минуты
    {
    if (Val(CnlNumI) > 1) //если ток привода больше единицы
    {
    V = V — 1;
    Z = V / 60;
    }
    }
    if ( Val(CnlNumBut) > 0)
    {
    Z = Val(CnlNumBut);
    V = Val(CnlNumBut) * 60;
    }

    return Z;
    }

    Как видно из последней функции я слежу за тем что бы входной канал(который присваивается из канала управления) был отличный от «0».
    Но у меня тут выплыла следующая проблема входной канал остается равный тому же значению
    Решение Входной канал приравниваю «0»(передаю значение «0») и все работает!
    Если что не так или есть предложения пишите

    #2217
    djbond07djbond07
    Участник

    Evgen, а Вы не пробовали использовать канал типа «Минутный ТИ» вместо формулы MinuteBeg(). Я имею ввиду, что этот канал уже возвращает «1» в начале каждой минуты, и необходимость в использовании формулы отпадает. Я в своей скаде использую именно его. Я думаю, что результат что у Вас, что у Меня один и тот же.
    Можно вопрос ещё по формуле. Что значит конструкция if (m)? Разве не нужно оператор сравнения здесь использовать? как эту конструкцию трактовать?

    • Этот ответ был изменен 5 лет, 3 месяца назад от djbond07djbond07.
    #2220
    EvgenEvgen
    Участник

    У меня учет времени работы
    за сутки
    за месяц
    и до следующего ППР(тут идет сброс по команде)
    и еще несколько задач связанных с временем воздействия пара
    временем прохождения продукта по трубе
    и поэтому что бы не путаться я везде использую формулы,
    да забыл написать я везде использую Дорасчетный ТИ
    if (m) это короткая запись след выражения
    if (m == true)

    • Этот ответ был изменен 5 лет, 3 месяца назад от EvgenEvgen.
    • Этот ответ был изменен 5 лет, 3 месяца назад от EvgenEvgen.
    • Этот ответ был изменен 5 лет, 3 месяца назад от EvgenEvgen.
    #2240
    djbond07djbond07
    Участник

    Evgen, я решил задачу со сбросом по одному нажатию кнопки. Смотрите как сделал:

    1. Создал переменную, которая является флагом для сброса (int Flag3=1;).
    2. Завёл входной канал минутный ТИ (№122) с формулой (Val(293)>0?Val()+1:Val())*GetFlag3(). Val(293) здесь это индикатор работы насоса.
    3. Сама формула выглядит так:
    public int GetFlag3()
    {
    int f = Flag3;
    if (Val(122)<=0) {Flag3=1;}
    return f;
    }
    Тут всё понятно, единственное, что условие Val(122)<=0, хитрое, о нём чуть позже. В итоге имеем подсчёт времени работы насоса с точностью до минуты, что в общем-то не ново.
    Теперь о самом сбросе:
    4. Создаём формулу сброса
    public double Sbros1Upr()
    {
    int f = Flag3;
    Flag3 = 0;
    return f;
    return double.NaN;
    }
    Опять же всё предельно ясно. Задаём стандартную команду «выполнить» в КУ, и прописываем эту формулу туда.
    В итоге имеем следующее. Допустим у нас насчиталось определённое кол-во минут. По нажатию кнопки флаг Flag3 устанавливается в 0. В следующую минуту, когда идёт расчёт канала 122, его значение ещё не равно 0, поэтому Flag3 у нас до сих пор 0, и происходит сброс значения канала 122. В следующую минуту происходит подсчёт формулы 122 снова, и Flag3 устанавливается в 1 (из условия if (Val(122)<=0) {Flag3=1;}). И всё, далее начинаем сначала. Если двигатель не включался в период от сброса значения наработки до следующей минуты, то погрешности дополнительной не будет. Если же включался, то будет примерно минутная погрешность. В моём случае необходимо сбрасывать значение наработки каждые 5000 часов (после проведения СО), поэтому минутная погрешность за 5000 часов меня вполне устраивает.

    Может решение косое и кривое, но у меня работает. Надеюсь, что чем-то Вам помог =)

Просмотр 9 сообщений - с 61 по 69 (из 69 всего)
  • Вы должны авторизироваться для ответа в этой теме.