Мал, да удал. ASCADA. Простейшая система диспетчеризации (SCADA) для Arduino и других микроконтроллеров
Я, как любой другой любитель «поковыряться» в различных железках, связанных с датчиками, микроконтроллерами и сопутствующих штуках, несколько лет назад столкнулся с необходимостью связать очередную микроконтроллерную историю с ПК, а именно, мне нужно было выводить в реальном времени значения различных сигналов с МК на дисплей компьютера в виде различных графиков, прогресс‑баров, а также, с помощью кнопок и ползунков управлять моим «железом».
В тот момент я уже относительно продолжительное количество времени работал на должности «инженер АСУ ТП», поэтому не понаслышке знал о популярных существующих системах диспетчеризации (по другому — SCADA системах) и для моих целей этого было крайне избыточно, особенно если учитывать их физический объем на жестком диске, необходимость использования OPC‑сервера и/или специфичных протоколов обмена.
Было принято решение написать свою с нуля! С функционалом близким (ну, или частичным) к крупным SCADA, но ориентированную на простого юзера, без лишних усложнений чтобы любой начинающий мог быстро в пару кликов создать необходимый графический интерфейс. Плюс к этому, давно хотел начать изучать C# и попробовать написать десктопное приложение с графическим интерфейсом.
Этот проект уже несколько лет как «завершен» и свою задачу выполнил, поэтому решил поделиться им с Вами, вдруг кто то, как и я в свое время, ищет подобный софт для своих задач, но не хочет углубляться в тонкости проектирования систем диспетчеризации!
Кратко, что такое SCADA-система
Случайный пример реализации SCADA, который я нашел в интернете
SCADA (Supervisory Control And Data Acquisition — диспетчерское управление и сбор данных) — программный пакет, предназначенный для разработки или обеспечения работы в реальном времени систем сбора, обработки, отображения и архивирования информации об объекте мониторинга или управления. (взято тут)
Более подробное описание того что это такое можно с легкостью найти на просторах интернета, я лишь хотел сразу обозначить, что, под термином «SCADA», часто имеют в виду весь комплекс от контроллеров и различных датчиков до HMI (человеко‑машинный интерфейс — то самое, что мы видим на дисплее компьютера и жмакаем по различным кнопкам). В пределах данной статьи разговор будет идти именно о HMI, что тоже покрывается термином «SCADA», особенно, на реальных объектах в разговорной речи.
ASCADA. Что это такое и почему я её называю «простейшей».
ASCADA — это программа, основанная на C# Winforms (.Net 3.5 для большей совместимости, чтобы на каждом «тапочке» работала без проблем). Предназначена для быстрого и простого проектирования систем визуального контроля технологических параметров, передаваемых от микроконтроллеров через последовательный порт или промышленных контроллеров через протоколы Modbus RTU/TCP. Используется в домашних решениях для управления и отображения различных параметров.
С первого взгляда видно то, что это сделано на Winforms, о чем сейчас сожалею, так как почти 90% времени работаю с линуксом, а там, через wine это дело работает мягко говоря кривовато (но работает), да и по «красивости» интерфейса есть вопросы, но да ладно.
Общий принцип такой: внутри проекта создаются так называемые теги — так в АСУ ТП называют различные сигналы, или более привычно — переменные. Теги, как и переменные, могут быть разных типов, в моем варианте предусмотрены следующие типы: bool, int, float, string. Здесь важно понимать, что тег — это не совсем переменная в привычном смысле, поэтому его тип это почти условность, которая определяет его предназначение.
Пример созданных тегов в 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
На примере с изображения видно что если кликнуть по объекту, то в внизу экрана в поле «Object Tag Property» отображается список из заранее созданных тегов и групп, в которых они были созданы. Также, всегда указывается какие типы тегов выбранный объект поддерживает.
Как «запустить/воспроизвести» созданный проект в ASCADA?
На момент публикации реализовано только два способа запуска созданного проекта:
Первый способ заключается в том, что при сохранении изменений в проекте создается файл с расширением .ascproj, который по своей сути это бинарная сериализация всего и вся что есть в проекте, включая изображения и т.д. Следовательно, если вы сохраните проект в директории программы в папке /Projects, то он отобразится в менеджере проектов, который запускается при старте программы:
Как выглядит менеджер проектов в ASCADA. Это первое что вы увидите при запуске программы ASCADA
Здесь мы кликаем по нужному проекту и видим его превью в виде того что в нем находится и текстовое описание (если мы, конечно, создавали это описание). Далее, у нас есть выбор — запустить его или редактировать, мы нажимаем запустить — кнопку START. После этого в новом окне откроется проект уже не в редакторе, а в виде программы, которая разворачивается на весь экран. Нам остается лишь открыть нужный COM-порт на нужном бодрейте, и, если в этот момент наш микроконтроллер или радиомодем шлет туда пакеты в приведенном выше формате, наши объекты начнут шевелиться, изменять свои значения и т.д.
Пример того куда нужно ткнуть чтобы отрыть необходимый COM-порт для запуска обмена
«Но ведь это долго и неудобно» — скажете вы. И будете правы. Именно поэтому я сделал второй способ запуска — генерация иконки быстрого запуска.
Для этого при редактировании проекта необходимо перейти в его свойства (иконка шестеренки в правом верхнем углу редактора или в Project/Properties).
Свойства проекта в ASCADA
Здесь мы можем выбрать: запускать ли проект на весь экран сразу или нет, с какого экрана начнется запуск (можно создавать много разных экранов и между ними переключаться), активировать авто подключение к COM-порту и к какому именно COM-порту и, что самое интересное на мой взгляд — это генерация иконки быстрого запуска.
Стоит лишь выбрать в каком месте на компьютере создать иконку и дать ей имя. Как только мы нажмем Accept, то по указанному пути создастся иконка приложения, при нажатии по которой, наш проект сразу запустится, и, при необходимости, откроет нужный COM-порт!
Итак, с основным смыслом данной программы, я думаю, уже не осталось вопросов. Кратко поговорим про возможности:
Возможности ASCADA
Для реализации наших проектов в нашем арсенале есть несколько типов объектов, это:
Тулбар с объектами, доступными для использования в проекте ASCADA
Динамические объекты, в контексте данной программы, это объекты к которым можно привязать тег (переменную) и эти объекты будут каким-либо способом реагировать на это, например: прогресс-бары, текстовые окна, ползунки, кнопки, переключатели, графики (тренды) и т.д.
Статические объекты — это объекты, к которым не привязывается тег, то есть это: изображения, геометрические фигуры, системные дата и время, обычный текст (например, если хотим сделать какую то подпись).
Компоненты — объекты, которые работают в фоновом режиме, например: звуковой сигнал, который реагирует на значение »1» тега с типом bool и воспроизводит мелодию выбранную на компьютере, CSV-логгер, который с заданным периодом времени пишет значение тега в .csv таблицу и создает тем самым лог, и компонент изменения свойств объекта, который позволяет к свойству какого-либо объекта привязать тег (например положение/размер объекта).
Фейсплэйты — это объекты, которые которые представляют собой кастомные объекты, созданные из стандартных. Например, мы хотим сделать меню проекта с кнопками навигации по проекту, и, чтобы нам не пришлось каждый раз копировать одни и те же кнопки с экрана на экран — мы создаем один фейсплэйт с ними и вставляем готовый фейсплэйт туда куда на необходимо. Удобно, согласитесь?:)
Все графические объекты в ASCADA реализованы с помощью векторной графики и имеет достаточно гибкие свойства для кастомизации — от толщины границ и их цвета, до использования псевдо-прозрачности (свойство Crop Background, которое позволяет сымитировать эффект прозрачности объекта, но по факту делает фоновым изображением объекта скрин из области под объектом).
Однако, на случай, когда покажется что этого мало и картинка все равно выглядит «топорно», я предусмотрел возможность использовать изображения для различных прогресс-баров, круглых баров и т.д., что дает возможность создавать красивые объекты если брать .png объектов с различных фотостоков.
Пример реализаций круглых баров в ASCADA. Слева встроенной векторной графикой, посередине и справа с использованием .png с фотостоков
Как видите, при желании, можно создать очень даже симпатичный графический интерфейс для своих проектов по диспетчеризации.
Также, хочется отдельно упомянуть возможности самих «экранов» на которых находятся объекты. У экранов тоже есть несколько свойств — вы можете задавать им разрешение, задавать фоновый цвет или выбрать изображение для фона.
Пример использования изображения как фон экрана в 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# и создание графических приложений как таковых, а значит, данный софт просто весь состоит из костылей и неправильных решений. Спустя столько лет я бы все делал абсолютно по другому, с нормальной архитектурой и т.д. Но что есть, то есть :)
Буду рад критике, как мы знаем, без нее не бывает развития. А еще больше, если кому то было интересно!
Делюсь ссылкой на гитхаб уже скомпиллированного проекта, который нужно только запустить и пользоваться. Всем добра!