yegorpetrov (yegorpetrov) wrote,
yegorpetrov
yegorpetrov

Говорящий код

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

Недавно открыл для себя новый подход к управлению множеством дискретных выходов контроллера. Традиционно каждый выход именуется и управляется отдельно. Например, так открываются третий и пятый клапаны и включается второй насос: V3 := V5 := P2 := TRUE. Если один из этих элементов нужно включать по условию, то он выходит на свою строку. И описывая цикл автомата, эти элементы приходится индивидуально отключать на следующих этапах.

Вместо этого я обозначил все выходы одним 32-битным целым и ввёл в программу константные маски элементов. Например, маской mP2 второго насоса, за которым закреплён седьмой выход, будет 26 = 64 (двоичная единица в седьмом разряде). Используя простую арифметику, при таком подходе можно писать даже сложные инструкции c разными условиями в одну строку: D_OUTS := mV3 + mV5 * NOT BOOL_TO_DWORD(TMP1 > 30) + mP2 * BOOL_TO_DWORD(TMP2 > 40). Функция с монструозным названием BOOL_TO_DWORD лишь выдаёт 32-разрядную 1 или 0 в зависимости от значения булевой переменной на входе. Заменяем её своей под именем when, и получаем тот самый человеческий язык: D_OUTS := mV3 + mV5 * NOT when (TMP1 > 30) + mP2 * when (TMP2 > 40). Знак умножения читать как but или не читать вовсе — он мелкий.

Вдобавок при программировании автомата уже не нужно заботиться о сбросе состояний, заданных на предыдущих этапах. Каждый шаг рассматривается отдельно и любая запись в D_OUTS целиком определяет состояние всех выходов. Конечно, при условии что все выходы уместились в одну переменную.
Tags: ПЛК, программирование
Subscribe
  • Post a new comment

    Error

    Anonymous comments are disabled in this journal

    default userpic

    Your IP address will be recorded 

  • 0 comments