ПЛК на микроконтроллере. Визуализация цепей в реальном времени ч.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 МБ ОЗУ. Таким образом, из слабого мини-ПК можно сделать полноценный самопрограммируемый промышленный контроллер.
KioskNews shows a cleaned-up reading view extracted from the publisher’s page — the original always lives on their site, not ours.