Мал, да удал. ASCADA. Простейшая система диспетчеризации (SCADA) для Arduino и других микроконтроллеров

Я, как любой другой любитель «поковыряться» в различных железках, связанных с датчиками, микроконтроллерами и сопутствующих штуках, несколько лет назад столкнулся с необходимостью связать очередную микроконтроллерную историю с ПК, а именно, мне нужно было выводить в реальном времени значения различных сигналов с МК на дисплей компьютера в виде различных графиков, прогресс‑баров, а также, с помощью кнопок и ползунков управлять моим «железом».

В тот момент я уже относительно продолжительное количество времени работал на должности «инженер АСУ ТП», поэтому не понаслышке знал о популярных существующих системах диспетчеризации (по другому — SCADA системах) и для моих целей этого было крайне избыточно, особенно если учитывать их физический объем на жестком диске, необходимость использования OPC‑сервера и/или специфичных протоколов обмена.

Было принято решение написать свою с нуля! С функционалом близким (ну, или частичным) к крупным SCADA, но ориентированную на простого юзера, без лишних усложнений чтобы любой начинающий мог быстро в пару кликов создать необходимый графический интерфейс. Плюс к этому, давно хотел начать изучать C# и попробовать написать десктопное приложение с графическим интерфейсом.

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

Кратко, что такое SCADA-система

Случайный пример реализации SCADA, который я нашел в интернете

Случайный пример реализации SCADA, который я нашел в интернете

SCADA (Supervisory Control And Data Acquisition — диспетчерское управление и сбор данных) — программный пакет, предназначенный для разработки или обеспечения работы в реальном времени систем сбора, обработки, отображения и архивирования информации об объекте мониторинга или управления. (взято тут)

Более подробное описание того что это такое можно с легкостью найти на просторах интернета, я лишь хотел сразу обозначить, что, под термином «SCADA», часто имеют в виду весь комплекс от контроллеров и различных датчиков до HMI (человеко‑машинный интерфейс — то самое, что мы видим на дисплее компьютера и жмакаем по различным кнопкам). В пределах данной статьи разговор будет идти именно о HMI, что тоже покрывается термином «SCADA», особенно, на реальных объектах в разговорной речи.

ASCADA. Что это такое и почему я её называю «простейшей».

cc0da29c4b70fd2f30c794f9268a1f1c.png

ASCADA — это программа, основанная на C# Winforms (.Net 3.5 для большей совместимости, чтобы на каждом «тапочке» работала без проблем). Предназначена для быстрого и простого проектирования систем визуального контроля технологических параметров, передаваемых от микроконтроллеров через последовательный порт или промышленных контроллеров через протоколы Modbus RTU/TCP. Используется в домашних решениях для управления и отображения различных параметров.

С первого взгляда видно то, что это сделано на Winforms, о чем сейчас сожалею, так как почти 90% времени работаю с линуксом, а там, через wine это дело работает мягко говоря кривовато (но работает), да и по «красивости» интерфейса есть вопросы, но да ладно.

Общий принцип такой: внутри проекта создаются так называемые теги — так в АСУ ТП называют различные сигналы, или более привычно — переменные. Теги, как и переменные, могут быть разных типов, в моем варианте предусмотрены следующие типы: bool, int, float, string. Здесь важно понимать, что тег — это не совсем переменная в привычном смысле, поэтому его тип это почти условность, которая определяет его предназначение.

Пример созданных тегов в ASCADA

Пример созданных тегов в ASCADA

Например:

int — это любое целочисленное число, которое поместится в стандартный int и означает то, что если мы хотим привязать к какому то объекту (или его свойству) этот тип, то этот объект должен поддерживать работу с таким типом о чем заботливо будет подсказано при попытке это сделать.

float — это числа с плавающей точкой, следовательно, вы успешно можете привязать его к прогресс-бару, но не получится привязать к этому типу позицию x: y объекта.

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

bool — это тот же int, с той лишь разницей, что используется в дискретных объектах — кнопках, переключателях и т.д. и оперирует со значениями 0 либо 1.

Путем привязки созданных тегов к объектам на экране и передачи значений по этим тегам (если быть точнее то передаем значения мы по ID тега) и происходит так называемая диспетчеризация. Объекты светятся, моргают, отображают значения параметров и все замечательно. Обмен может происходить в обе стороны, как со стороны микроконтроллера, так и со стороны ASCADA, например при нажатии на кнопку или перемещении ползунка. По моему мнению — это абсолютно просто. Но обо всем по порядку.

Как передавать значения тегов от микроконтроллера в ASCADA

Так как цель разработки была — максимально все упростить, то и «протокол» обмена крайне прост (если вообще язык повернется назвать это протоколом). Передача происходит в символьном виде через последовательный порт, он же COM-порт. Выглядит это так:

0&100*

В этом примере пакета данных мы передали int или float значение 100 в тег с ID равным 0, где & — символ-разделитель, а * — символ конца пакета данных.

Еще несколько примеров: 19&Hello World* — передали строковое значение Hello World тегу с ID =19; 234&1958,59* — передали значение с плавающей точкой 1958,59 в тег ID =234. Как видите, все максимально просто и понятно.

Как выглядит процесс привязки тега к объекту в ASCADA

Как выглядит процесс привязки тега к объекту в ASCADA

На примере с изображения видно что если кликнуть по объекту, то в внизу экрана в поле «Object Tag Property» отображается список из заранее созданных тегов и групп, в которых они были созданы. Также, всегда указывается какие типы тегов выбранный объект поддерживает.

Как «запустить/воспроизвести» созданный проект в ASCADA?

На момент публикации реализовано только два способа запуска созданного проекта:

Первый способ заключается в том, что при сохранении изменений в проекте создается файл с расширением .ascproj, который по своей сути это бинарная сериализация всего и вся что есть в проекте, включая изображения и т.д. Следовательно, если вы сохраните проект в директории программы в папке /Projects, то он отобразится в менеджере проектов, который запускается при старте программы:

Как выглядит менеджер проектов в ASCADA. Это первое что вы увидите при запуске программы ASCADA

Как выглядит менеджер проектов в ASCADA. Это первое что вы увидите при запуске программы ASCADA

Здесь мы кликаем по нужному проекту и видим его превью в виде того что в нем находится и текстовое описание (если мы, конечно, создавали это описание). Далее, у нас есть выбор — запустить его или редактировать, мы нажимаем запустить — кнопку START. После этого в новом окне откроется проект уже не в редакторе, а в виде программы, которая разворачивается на весь экран. Нам остается лишь открыть нужный COM-порт на нужном бодрейте, и, если в этот момент наш микроконтроллер или радиомодем шлет туда пакеты в приведенном выше формате, наши объекты начнут шевелиться, изменять свои значения и т.д.

Пример того куда нужно ткнуть чтобы отрыть необходимый COM-порт для запуска обмена

Пример того куда нужно ткнуть чтобы отрыть необходимый COM-порт для запуска обмена

«Но ведь это долго и неудобно» — скажете вы. И будете правы. Именно поэтому я сделал второй способ запуска — генерация иконки быстрого запуска.

Для этого при редактировании проекта необходимо перейти в его свойства (иконка шестеренки в правом верхнем углу редактора или в Project/Properties).

Свойства проекта в ASCADA

Свойства проекта в ASCADA

Здесь мы можем выбрать: запускать ли проект на весь экран сразу или нет, с какого экрана начнется запуск (можно создавать много разных экранов и между ними переключаться), активировать авто подключение к COM-порту и к какому именно COM-порту и, что самое интересное на мой взгляд — это генерация иконки быстрого запуска.

Стоит лишь выбрать в каком месте на компьютере создать иконку и дать ей имя. Как только мы нажмем Accept, то по указанному пути создастся иконка приложения, при нажатии по которой, наш проект сразу запустится, и, при необходимости, откроет нужный COM-порт!

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

Возможности ASCADA

Для реализации наших проектов в нашем арсенале есть несколько типов объектов, это:

Тулбар с объектами, доступными для использования в проекте ASCADA

Тулбар с объектами, доступными для использования в проекте ASCADA

Динамические объекты, в контексте данной программы, это объекты к которым можно привязать тег (переменную) и эти объекты будут каким-либо способом реагировать на это, например: прогресс-бары, текстовые окна, ползунки, кнопки, переключатели, графики (тренды) и т.д.

Статические объекты — это объекты, к которым не привязывается тег, то есть это: изображения, геометрические фигуры, системные дата и время, обычный текст (например, если хотим сделать какую то подпись).

Компоненты — объекты, которые работают в фоновом режиме, например: звуковой сигнал, который реагирует на значение »1» тега с типом bool и воспроизводит мелодию выбранную на компьютере, CSV-логгер, который с заданным периодом времени пишет значение тега в .csv таблицу и создает тем самым лог, и компонент изменения свойств объекта, который позволяет к свойству какого-либо объекта привязать тег (например положение/размер объекта).

Фейсплэйты — это объекты, которые которые представляют собой кастомные объекты, созданные из стандартных. Например, мы хотим сделать меню проекта с кнопками навигации по проекту, и, чтобы нам не пришлось каждый раз копировать одни и те же кнопки с экрана на экран — мы создаем один фейсплэйт с ними и вставляем готовый фейсплэйт туда куда на необходимо. Удобно, согласитесь?:)

Все графические объекты в ASCADA реализованы с помощью векторной графики и имеет достаточно гибкие свойства для кастомизации — от толщины границ и их цвета, до использования псевдо-прозрачности (свойство Crop Background, которое позволяет сымитировать эффект прозрачности объекта, но по факту делает фоновым изображением объекта скрин из области под объектом).

Однако, на случай, когда покажется что этого мало и картинка все равно выглядит «топорно», я предусмотрел возможность использовать изображения для различных прогресс-баров, круглых баров и т.д., что дает возможность создавать красивые объекты если брать .png объектов с различных фотостоков.

Пример реализаций круглых баров в ASCADA. Слева встроенной векторной графикой, посередине и справа с использованием .png с фотостоков

Пример реализаций круглых баров в ASCADA. Слева встроенной векторной графикой, посередине и справа с использованием .png с фотостоков

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

Также, хочется отдельно упомянуть возможности самих «экранов» на которых находятся объекты. У экранов тоже есть несколько свойств — вы можете задавать им разрешение, задавать фоновый цвет или выбрать изображение для фона.

Пример использования изображения как фон экрана в ASCADA

Пример использования изображения как фон экрана в ASCADA

Также, есть очень интересная функция — использовать экран как темплэйт. Это означает что выбранный экран можно использовать как «шаблон» для всех других, а именно — все объекты что есть на этом экране, будут отображаться на остальных. Зачем это нужно? А для того, что если вам в вашем проекте, опять же, нужно меню с навигацией или панель с отображением даты и времени, то при реализации темплэйта вам не придется это все создавать/копировать на другие экраны. Как по мне, это удобно:)

А еще, хотелось бы упомянуть что в «плеера проекта», то есть когда проект уже запущен, есть возможность просматривать значения тегов в реальном времени в специальном окне, плюс есть эмулятор в котором вы можете текстом набрать пакет, который ожидаете от микроконтроллера и смотреть как на это реагируют различные объекты — что тоже удобно, чтобы каждый раз не подключать устройство.

Эпилог

Данная программа создавалась лишь для того, чтобы мне в моих проектах не приходилось каждый раз писать графический интерфейс в различных Processing и т.д., а делать это в пару кликов и с нужным мне функционалом. А также, с минимальными заморочками в плане программирования и траты на это времени.

Как выглядит примитивный пример как отправить в тег ASCADA с ID 4 значение float 36.6 от Arduino:

void send()
{
  float temper = 36.6F;
  String data_pack = "4&" + String(temper) + "*";
  Serial.print(data_pack);
}

На мой взгляд это максимально просто, что справится даже самый начинающий.

Не буду в подробностях описывать другие возможности ASCADA в данной статье, как например, возможность работы через протоколы Modbus RTU и Modbus TCP, так как не вижу смысла. Если кого-то это интересует, то этот человек и сам разберется с интерфейсом.

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

Даже больше, если будет какая то обратная связь и данный проект кого-то заинтересует, то я открою исходники в общий доступ для возможного развития — мне абсолютно не жалко:) Но скажу сразу, что в тот момент я только начинал изучать C# и создание графических приложений как таковых, а значит, данный софт просто весь состоит из костылей и неправильных решений. Спустя столько лет я бы все делал абсолютно по другому, с нормальной архитектурой и т.д. Но что есть, то есть :)

Буду рад критике, как мы знаем, без нее не бывает развития. А еще больше, если кому то было интересно!

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

© Habrahabr.ru