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

Тема: ST, паузы, async/await/coroutines

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

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

    По умолчанию ST, паузы, async/await/coroutines

    Пока размышлял над Драконизацией программирования, пришла мысль, что, возможно, удобной штукой будет добавить coroutines в ST.

    Гипотеза в том, что последовательный код писать проще чем "автоматный".
    Да, есть CASE, но расщеплять состояния приходится вручную.

    Что можно было бы сделать: добавить оператор "пауза" в ST. Тогда код с паузами при компиляции автоматически бы превращался в CASE автомат.

    Пример:
    Код:
    PROGRAM запуск_насоса
    VAR
      номер_насоса: INT;
    
    WHILE TRUE
      номер_насоса := найти_рабочий_насос();
      IF номер_насоса=-1 THEN
        авария_всех_насосов();
        ПАУЗА t#1s;
        CONTINUE;
      END_IF;
    
      увеличить_количество_запусков(номер_насоса);
      запустить_насос(номер_насоса);
    
      ПАУЗА t#10s;
    
      WHILE давление_есть
        ПАУЗА;
      END_WHILE;
    
      (* Давление пропало, значит насос сломался *)
      остановить_насос(номер_насоса);
      установить_признак_аварии(номер_насоса);
    END_WHILE;
    END_PROGRAM
    Эта программа выглядит как бесконечный цикл (WHILE TRUE снаружи), но после компиляции она будет возвращать управление в момент "пауз". При повторном вызове она будет продолжать с места прошлой паузы.

    Иными словами, скомпилированный код может выглядеть вот так:

    Код:
    PROGRAM запуск_насоса
    VAR
      номер_насоса: INT;
      состояние : INT;
      ton1: TON;
      ton2: TON;
    WHILE TRUE
    CASE состояние OF
    0: 
      номер_насоса := найти_рабочий_насос();
      IF номер_насоса=-1 THEN
        авария_всех_насосов();
        состояние := 1; (* ПАУЗА 1s *)
        ton1(IN := FALSE, PT := t#1s);
        RETURN; (* возвращаем управление *)
      END_IF;
      состояние := 2;
    
    1: 
      ton1(IN := TRUE); (* ПАУЗА 1s *)
      IF ton1.Q THEN
        состояние := 0; (* continue *)
      ELSE
        RETURN; (* возвращаем управление *)
      END_IF;
    
    2:
      увеличить_количество_запусков(номер_насоса);
      запустить_насос(номер_насоса);
    
      ton2(IN := FALSE, PT := t#10s);
      состояние := 3;
      RETURN;
    
    3: 
      ton2(IN := TRUE); (* ПАУЗА 10s; *)
      IF ton2.Q THEN
        состояние := 4;
      ELSE
        RETURN;
      END_IF;
    
    4:
      IF давление_есть THEN
        RETURN;
      ELSE
        (* Давление пропало, значит насос сломался *)
        состояние := 5;
      END_IF;
    
    5:
      остановить_насос(номер_насоса);
      установить_признак_аварии(номер_насоса);
      состояние := 0;
    END_WHILE;
    END_PROGRAM
    С одной стороны, конечно, невелика наука расставить CASE.
    Но, с другой стороны, на паузах код гораздо внятнее. Особенно, когда паузы внутри. Была одна строка "ПАУЗА t#1s;", а превратилась в 9 строк кода (запуск таймера, заход, выход)
    Да и сам подход с async/await довольно широко сейчас используется в JavaScript, C#, Kotlin.

    Что думаете?
    Последний раз редактировалось Владимир Ситников; 09.10.2017 в 22:53.

Похожие темы

  1. Ответов: 4
    Последнее сообщение: 11.05.2018, 13:01
  2. Режим паузы в ТРМ251 на прошивке 2.10
    от Brewer в разделе Эксплуатация
    Ответов: 2
    Последнее сообщение: 29.03.2016, 16:10
  3. Реализация паузы в SFC
    от KoT'86 в разделе ПЛК1хх
    Ответов: 7
    Последнее сообщение: 05.06.2013, 22:28
  4. ПЛК63 - непонятные паузы в исполнении при опросе по 485
    от Alex_yu в разделе Помощь Разработчикам
    Ответов: 9
    Последнее сообщение: 02.07.2011, 23:54

Ваши права

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