[Из песочницы] ПЛК100 + LabVIEW + джойстик
Однажды на моём рабочем столе оказались usb-джойстик и ПЛК (программируемый логический контроллер) фирмы ОВЕН — ПЛК100, при этом на компьютере была запущена среда LabVIEW. Я подумал, что всё это — хотя бы забавы ради — можно объединить, организовав управление ПЛК (его выходами) с помощью кнопок джойстика (позже я решил использовать не просто кнопки, а их комбинации — ВНИЗ, ВПЕРЁД, Y, например).Итак, как всё это работает. LabVIEW обрабатывает нажатие клавиши джойстика и передаёт информацию о нажатой клавише в ПЛК100 (в данном случае — через серийный порт); ПЛК100, в соответствии с загруженной в него программой, реагирует на определённые комбинации клавиш включением/отключением своих выходов.
Часть LabVIEWПрограмма, обрабатывающая нажатия кнопок джойстика и передающая информацию о них в ПЛК100, в общем виде выглядит так:
Теперь более подробно.1 — Инициализация джойстика. Можно найти в Function Palette в разделе Connectivity→Input Device Control. Если к компьютеру подключен один джойстик, как в моём случае, параметр Device Index рекомендуется приравнивать к 0.2 — Получение данных с устройства ввода. Данные о кнопках и направлениях осей (крестике) хранятся в кластерах, которые с помощью функции Unbundle нужно разбить на элементы, чтобы в последующем их как-то обрабатывать. «Кнопочный» кластер 3 (на рисунке он уже разбит на элементы) состоит из булевых элементов; при нажатой кнопке соответствующий элемент кластера принимает значение TRUE. С «осевым» кластером 4 дело обстоит немного иначе: он состоит из целочисленных элементов, и при нажатой клавише ВВЕРХ первый элемент кластера — X axis — принимает значение -32768, клавише ВНИЗ соответствует значение 32767. Со вторым элементом кластера — Y axis — всё примерно так же: НАЗАД = -32768, ВПЕРЁД = 32767.5 — Формирование строки. Функция Format Into String формирует (или же возвращает) строку из элементов разных типов данных. В моём случае это булевы элементы и их всего 8, поэтому на выходе будет строка из 8 символов. Здесь требуется пояснение: если ни одна кнопка не нажата, строка имеет вид »00000000»; если же, к примеру, нажата кнопка 1, то строка будет такой »1000000», если кнопка 2, то такой »01000000» и т.д. В зависимости от значения это строки в серийный порт будет записываться определённое число, которое уже и будет обрабатывать ПЛК100. Кстати, параметр «format string» функции Format Into String задан так »%d%d%d%d%d%d%d%d», чтобы преобразовывать входные булевы FALSE и TRUE в нули и единицы и в итоге получать строку вида, например,»10000000», а не «TRUEFALSEFALSEFALSE…». Вот так. Можно проще? Можно, но в другой раз.6 — Конфигурирование и открытие серийного порта. Я оставил все параметры по умолчанию, добавив только управляющий элемент для выбора номера порта. Для работы с COM-портом должна быть установлена NI-VISA (здесь www.ni.com/download/ni-visa-5.4.1/4626/en/).7 — Структура Case. В зависимости от значения строки, сформированной функцией Format Into String, пишет в серийный порт число (11, например, соответствует кнопке 1, 12 — кнопке 2 и т.д.). Это число предварительно конвертируется функцией Number To Decimal String — на рисунке цифра 8 (без этого блока ПЛК100 по непонятным причинам читал из порта какие-то кракозябры).
Программа ПЛК Немного о портах ПЛК100. Целых три разъёма могут работать в качестве COM-порта: это Debug-232 на лицевой панели, RS-232 и RS-485 внизу. При открытии порта нужно будет указать его номер: для Debug-232 это 4, для RS-232 — 1, для RS-485 — 0. Я использовал RS-485, подключив ПЛК к компьютеру через дешёвый китайский переходник RS-485→USB (на фото), соответственно, в программе в качестве номера порта стоит 0.
ПЛК100 программируется в среде Codesys 2.3. Кроме того, понадобится так называемый таргет — что-то вроде файла с описанием конфигурации программируемого устройства. Для инициализации и открытия порта я использовал библиотеку ComService.lib (библиотеку и пример к ней можно скачать здесь www.owen.ru/forum/showthread.php? t=551&page=6). Операции конфигурирования и открытия порта я объединил в одном функциональном блоке — см. рисунок ниже.
Видно, что объект 'set' объявлен как COMSETTINGS. Это экземпляр структуры COMSETTINGS, содержащей в себе настройки порта; она уже объявлена в библиотеке ComService (если быть точным, то в библиотеке SysComLib, которая входит в состав ComService). Настройки достаточно стандартные, стоит только обратить на set.Port = 0 — это RS-485, о котором было сказано выше.
Функциональный блок COM_SERVICE имеет два параметра: первый это имя структуры COMSETTINGS, второй — тип операции, где 0 соответствует настройке и открытию.
Далее при помощи функции SysComRead, входящей в библиотеку SysLibCom, читаем данные из порта. Параметр dwHandle это номер порта (RS-485 в данном случае), dwBufferAddress — указатель на переменную, куда будут читаться данные, dwBytesToRead — количество читаемых байт (в моём случае это 2), dwTimeout — время в мс, после которого функция обязана завершиться; если поставить слишком мало, то функция просто ничего не прочитает.
Далее идёт конвертация строки, считанной из порта, в целое число и сравнение этого числа: если оно, к примеру, равно 10, то ни одна кнопка не нажата, если 11 — то нажата X и т.д.
Для обработки комбинаций клавиш я запрограммировал 6 функциональных блоков — 3 для включения первых трёх релейных выходов ПЛК (думаю, трёх выходов будет для начала достаточно) и 3 для их отключения; четыре комбинации из 3-х клавиш и две из 4-х. Внутри эти блоки выглядят вот так:
i1, i2, i3 — это первая, вторая и третья кнопки комбинации соответственно. Функциональный блок для четырёхкнопочной комбинации отличается не сильно, и получить его из трёхкнопочного это дело техники, поэтому его содержание я опускаю.Следует добавить, что для каждого функционального блока я объявлял свои экземпляры блоков R_TRIG, TON и TOF, потому что на одну комбинацию реагировали бы все три выхода. Но для блоков включения и выключения одного и того же выхода я оставил их одинаковыми.
В итоге программа у меня выглядела так (пропускаю место с открытием порта):
На видео видно, как на ПЛК загораются светодиоды, говорящие о том, что выход активен. Для наглядности хотелось бы в качестве нагрузки подключить к выходам хотя бы лампочку или пускатель, но на момент записи видео под руками оказался лишь компьютерный кулер.
[embedded content]
Надо сказать, что на быстрые нажатия вся эта система (говорю «система», потому как не знаю, в каком именно месте был «затор») реагировала довольно неохотно, если вообще реагировала; неспешные нажатия (как на видео) немного улучшают ситуацию, но всё же иногда реакция на них отсутствовала. Но ведь у ПЛК100 есть ещё и разъём Ethernet. Так что в следующий раз я попытаюсь сделать хотя бы небольшое улучшение, привязав ПЛК к LabVIEW через OPC-сервер по Ethernet.
Спасибо за внимание.