ПЛК на микроконтроллере. Визуализация цепей в реальном времени ч.2

—

от автора

В прошлой статье я рассказал о своем подходе к разработке среды программирования промышленного контроллера — а именно о части, касающейся визуализации данных из цепей лестничных диаграмм и функциональных блоков, которые выполняются на стороне микроконтроллера. В этот раз подробнее остановлюсь на цепочке событий.

Как я уже упоминал, вся модель среды ПЛК (которую я разрабатываю) содержится в XML-файле. Этот файл включает в себя список функциональных блоков:

<LD_Unit Name="GTM" Group="Timer" Width="100" Height="55">

На основе этих данных среда (GUI-приложение на ПК) группирует блоки по вкладкам, используя тег <Group>. Внутри этих модулей (юнитов) также содержатся графические примитивы, которые определяют визуальный облик каждого блока.

<lists>        <Item Type="RECT" color="#808080"  Style="box" >          <Value> </Value>          <xy x="1" y="20" />          <dimension width="117" height="57" />          <stroke Stroke="1" />          <fill Fill="1" />        </Item>

Вся цепочка — от XML-строки до отрисовки блока на экране — выглядит следующим образом:


В параметры FBD-блоков я добавил тип Style="box". Теперь при очень длинных названиях в момент отрисовки функциональный блок автоматически расширяется под размер строки. Поначалу я хотел просто обрезать строки (как это сделано в типичных китайских средах разработки), но вовремя понял, что это небезопасно. Если элемент ссылается на поле сложной структуры — например, на элемент массива в самом конце строки, — то важную часть данных можно просто выпустить из виду, что неминуемо приведет к ошибкам:

После того как мы получили список примитивов, определяющих логику отрисовки функционального блока, мы применяем указанный в XML стиль. Происходит это непосредственно перед рендерингом примитива (в моем случае код написан на Java):

    private void drawLine()     {         gc.setColor(AnimFabric.parseColor(color));                  if(Style!=null && sm!=null)          {                    if(Style.contains("onoff"))                    {                        gc.setColor(AnimFabric.onOff(sm.getValue(),Style));                    }          }         Graphics2D g2d = (Graphics2D) gc;        g2d.setStroke(new BasicStroke((float) stroke.Stroke));         g2d.drawLine((int) xy.x+X, (int) xy.y+Y, (int) x2y2.x+X, (int) x2y2.y+Y);    }

Класс AnimFabric содержит типы анимации, а объект sm — тег и данные, привязанные к этому примитиву.

Первоначально я хотел сделать среду более современной, но затем расставил приоритеты в пользу легковесности. Для этого я использовал стандартные классы OpenJDK — как для отрисовки графики, так и для дизайна GUI в целом. В итоге среда спокойно запускается даже на ранних версиях Raspberry Pi и требует всего 120–200 МБ ОЗУ. Таким образом, из слабого мини-ПК можно сделать полноценный самопрограммируемый промышленный контроллер.

Так же, еще раз процесс работы из прошлого поста:

ссылка на оригинал статьи https://habr.com/ru/articles/1103386/