понедельник, 7 октября 2024 г.

Продолжение по Owen и Codesys

В прошлый раз писал о том как запустить опрос нескольких устройств по протоколу modbus чтобы опрос велся в пакетном режиме - тогда советовали использовать символы, и приходилось делать еще множество преобразований, а еще чтобы сделать опрос сразу 30 устройств пришлось даже расширять память. Оказалось что Овен выпустили давным давно библиотеку, которая так же в пакетном режиме опрашивает модбас устройства и преобразований становится меньше.

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


Еще хотел бы написать еще об одной интересной штучке, подсмотрел на форуме, но хочу сохранить еще раз - логика для отображения времени скана программы:


Простейший принцип - фиксируется время каждого цикла и отнимается от времени предыдущего цикла - сработает на любом другом ПЛК, интересно даже проверить это потом как-нибудь.

Еще одна интересная фишка - есть и в документации и снова как всегда пишу тут чтобы не искать в документации:

Как видно на картинке можно задать разные цвета заливки для блока с восклицательным знаком - при разных условиях цвет будет разный. При этом удобно использовать массив цветов (в данном случае cell_err, причем обратить внимание на тип DINT - цвет требует больше памяти чем просто INT) и цикл для задания цветов для нескольких устройств. Конечно же даже если условий сработает несколько, то цвет останется в итоге по последнему условию, но в данном случае такое поведение не принципиально, потому что при любом раскладе требуется обратить внимание на состоянии ячейки. Чтобы при нормальной работе не отображать восклицательный знак - его показ можно скрыть по условию если цвет будет равен нулю, но в конструкции добавляется NOT - потому что свойство невидимости (или тогда <>0 без NOT)
.cell_err[1]=0
И еще кое-что. Для того чтобы реализовать мигающий красный восклицательный знак, пришлось добавить мигающий бит в программу. Сначала сделал на таймерах ,а потом увидел что есть готовый блок в библиотеке Utils:


пятница, 23 августа 2024 г.

Передача сигнала с IBA PDA в PLC

IBA PDA может собирать кучу сигналов через множество протоколов с разных ПЛК: TCP, UDP, S7, Modbus TCP (но иба не мастер а слейв), Modbus RTU (как мастер та ки слейв через COM порт), OPC DA и другие. Фишка в том что оказывается через OPC можно и отправлять данные в ПЛК, и об этом хоел написать небольшую заметку, чтобы как обычно в случе если снова понадобится, можно было это сделать еще раз. (сейчас смотрю и как будто слишком сложно все, но та кработает. не знаю можно ли упростить, но оставлю именно так как делал сам)

Для настройки передачи используется функция ИБЫ Alarms (OPC output module), где в качестве выходного сигнала выбирается тот который поддерживает записть. На скрине ниже видно как в ИБА Qpanel ввели в специальное поле значение 20, и это значение изменилось (4 график):


 Видно так же то что этот сигнал пишется еще и в виртуальный модуль (7:0)

А кнопка на Qpanel привязывается к этому сигналу (на скрине кстати видно как можно скрыть кнопку Apply, или можно ее текст изменить):

Все. Теперь если с ибы ввести новое значение, то оно передается в ПЛК посредством OPC. 

B еще немного про интересную функцию ИБЫ - technostring, вот так она примерно работает:

То есть можно передавать ASCII символы, которые будут отображаться в анализе в момент передачи. Туда можно передавать например номера рулонов. Как видно на скрине выше передавать на ибу можно строку по TCP протоколу и выделять в строке нужную часть, которая будет отображаться на графике. Заканчиваться строка должна переводом каретки (0x0D). Также можно передать строку в файле - во время сохранения файла показывается та часть первой строки (оканчивающаяся так же переводом каретки) которая настраивается аналогичным образом как и с TCP. В общем все это очень интересно, но для применения в реальности чаще всего врядли понадобится: если не знать что так можно делать, то значит так можно не делать)

воскресенье, 11 августа 2024 г.

Codesys 2.3 немного о визуализации

Мне лень читать документацию, а иногда требуется сделать что-то не совсем очевидное, поэтому решил написать небольшую заметку, чтобы вернуться к ней если понадобится когда-нибудь еще. Была задача добавить визуализацию нескольких однотипных модулей. Рисовать 10, 20 картинок конечно же было бы тупо, а вот нарисовать одну, и привязать к ней промежуточный тег - это правильно. Обычно это называется фейсплейт или faceplate, или шаблон. То есть был сделан шаблон визуализации в Codesys 2.3. 

Чтобы выйти из ситуации, придумал такой план: создал массив с 20 элементами (по числу модулей) со структурой визуализации, в которой записываются интересующие параметры - собирается больше 20 сигналов с каждого модуля. Как это выглядит (создана структура depStruct и создан массив DEP):

вторник, 6 августа 2024 г.

Добавление устройств с протоколом ModBus TCP в ПЛК AllenBradley

Modbus — открытый коммуникационный протокол, основанный на архитектуре ведущий — ведомый (англ. master-slave; в стандарте Modbus используются термины client-server). Широко применяется в промышленности для организации связи между электронными устройствами. Может использоваться для передачи данных через последовательные линии связи RS-485, RS-422, RS-232 и сети TCP/IP (Modbus TCP).
Для того чтобы организовать обмен с ведомым устройством, посредством протокола Modbus, в ПЛК Allenbradley предусмотрена стандартная функция, которую можно добавить, скачав с официального сайта. В скаченном архиве есть английская инструкция по работе с функцией, и файл с расширением L5X, через который импортируется логика функции. Архив с сайта добавил себе в облако.
Последовательность шагов для импорта функции Modbus TCP (все шаги делаются в онлайн режиме):

среда, 31 июля 2024 г.

Открыть чат WhatApp

 Открыть чат WhatsApp для номеров телефонов не в телефонной книге - например если нужно отправить сообщение тому кого нет в вашей телефонной книге



понедельник, 3 июня 2024 г.

Owen Codesys: опрос сигналов по ModBus и передача их по UDP

Попытался в заголовке изложить полную суть проблемы, чтобы было понятно что же требуется. Ну и чтобы решить общую задачу, разбиваем ее на несколько подзадач: сначала принимаем сигналы, потом их отправляем.Для того чтобы в Codesys настроить прием сигналов по протоколу Модбас, нужно настроить ПЛК Овен на режим Модбас Мастер:

Все это делалось по инструкции с сайта Овен, там очень хорошо построен сайт - есть все драйвера, софт, прошивки, вспомогательные библиотеки, примеры проектов, видео инструкции, обычные инструкции - в общем очень и очень хорошо поставлена работа, за что Овену большой плюс. Вот конкретная ссылка на видео, на основании, которой делалась эта конфигурация: https://www.youtube.com/watch?v=77fdfnfdJME Если коротко описать словами, то нужно во вкладке ресурсы нужно открыть "Конфигурация ПЛК" и там через контекстное меню добавить элемент ModBus Master. В нем нужно настроить порт (RS485) и другие параметры. Потом уже к мастеру добавляем опрашиваемое устройство: Universal Modbus Device, которое тоже параметрируем так как надо: главное выставить его адрес и скорость обмена. И вот уже потом добавляется Подэлемент - Теги которые опрашиваются у устройства, в зависимости от их типа данных, можно выбрать разные опции. У каждого тега настраивается его адрес. И вот тут есть небольшой нюанс, который и побудил написать эту заметку. Как видно на скрине в качестве опрашиваемого типа используется String Input module и это не просто так.

Дело в том, что с самого начала при добавлении тегов по той видео инструкции, я обратил внимание что каждый новый тег визуально замедляет обмен с устройством- в онлайн режиме данные при опросе одного тега меняются очень и очень быстро, а уже при 4 визуально видно что замедляется, при 20 это видно очень и очень хорошо. При этом обмен с OPC сервером был довольно быстрый, но зато там я обратил внимание на опцию - "опрашивать каждый тег по-отдельности". Когда включил эту опцию, то скорость визуально стала в несколько раз меньше. Это навело меня на мысль, что ПЛК опрашивает теги не в пакетном режиме, а каждый по-отдельности, и нужно было как-то эту проблему решить. На форуме нашлось решение такое, что  посоветовали выбирать Строковую переменную, а в ней можно выбрать количество опрашиваемых символов (байт). Таким образом вся строка (несколько подряд идущих тегов) опрашивается одним пакетом, и теперь только требуется правильно разделить принятые данные. 

Мне требовалось опросить 8 input регистров (код операции 0х04) типа real, которые идут подряд и начинаются с адреса 33000. Для того чтобы опросить их одним пакетом, я добавил опрос строки с адреса 33000 длиной 32 байт (8 шт * 4 байта в Real). Теперь данные опрашивались с такой же скоростью, как и скорость опроса одного тега (по сути один тег и есть), но в ответ приходила строка с кучей непонятных символов. Оказалось что в памяти ПЛК можно выделить область памяти куда эти данные можно поместить в виде массива (байт, или WORD, или Real как в моем случае), и делается это в разделе регистрации глобальных переменных, конструкцией AT %IB9.1.0.0 (как ссылка на область памяти зарезервированной для устройства, то есть как я понимаю массив байт с устройства копируется в новый массив, но зато с ним проще работать):

RTU1_R AT %IB9.1.0.0: ARRAY [0..7] OF REAL;

То есть как видно, создается массив из 8 элементов типа REAL. Но теперь выявилась другая проблема: эти данные в контроллере стали отображаться неверно - поменяны местами первое и второе слово, и чтобы вернуть им нормальный вид, пришлось снова искать решение. Готовых библиотек в составе пакета Codesys для такого не было, нужно было добавлять их, но зато оказалось что написать функцию стандартными средствами (через указатели), которая будет делать SWAP (менять слова в составе Real переменной местами) не так-то и сложно (подсмотрел на форуме):

FUNCTION SWAP_R : REAL
VAR_INPUT
    Input:REAL;
END_VAR
VAR
    pInput:POINTER TO ARRAY [0..3] OF BYTE;
    pResult:POINTER TO ARRAY [0..3] OF BYTE;
END_VAR

pInput:=ADR(Input);
pResult:=ADR(SWAP_R);
pResult^[0]:=pInput^[2];
pResult^[1]:=pInput^[3];
pResult^[2]:=pInput^[0];
pResult^[3]:=pInput^[1];

 

Как видно сначала должны идти 2 и 3 байты, а потом 0 и 1. Знак ^  означает что нужно брать контент расположенный по адресу указателя. Теперь данные имели понятный вид и их можно передавать по UDP.

Чтобы передать по UDP на сайте Овен также нашел пример проекта: оттуда тупо копипастой скопировал код в блок UDP_FC, который вызывается из основной программы. Чтобы код заработал, нужно было импортировать библиотеку syslibsockets.lib которая тоже нашлась на сайте Овен

Как видно из названий FC блоков на скрине, UDP понадобился для того чтобы передавать данные на сервер IBA. Чтобы упаковать все полученные данные с устройств ModBus (в данном примере пока только 2 устройства с 2 наборами тегов: Real и DWORD) в телеграмму для передачи по UDP, бал добавлен функциональный блок с таким содержимым:

sendArray[0]:= QW1_mobbus;
(*MODBUS #1*)
sendArray[1]:= SWAP_R(RTU1_R[0]);
...
sendArray[8]:= SWAP_R(RTU1_R[7]);
sendArray[9]:= RTU1_D[0];
sendArray[10]:= RTU1_D[1];
...
sendArray[18]:= RTU1_D[9];
(*MODBUS #2*)
sendArray[19]:= SWAP_R(RTU2_R[0]);
...
sendArray[26]:= SWAP_R(RTU2_R[7]);
sendArray[27]:= RTU2_D[0];
...
sendArray[36]:= RTU2_D[9];

Как видим Real значения передаются через функцию SWAP, а DWORD в том виде, какой есть (там порядок байт прямой).

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

суббота, 4 мая 2024 г.

Почему это красиво? Странный эксперимент со спиралью Фибоначчи

В фотографии часто используется правило третей и золотое сечение - фраза буквально из статьи которая выдается первой по поиску в Яндексе. Есть подозрение, что не все фото делаются специально по этому правилу, но итоге почти все "красивые" фото оказываются соответствующими такому правилу, и человек просто любуется таким фото, не подозревая что любуется математикой. Мало того, любуясь фотографиями девушек, я обратил внимание, что и там часто присутствует такое же золотое сечение - женские формы и изгибы тела очень часто хорошо вписываются в золотую спираль. Смотрите сами:


Как видно изгиб тела практически идеально повторяет форму золотой спирали.

Я давно уже хотел проверить эти слова на практике, и для того чтобы быстро проверять "красоту" захотелось сделать онлайн инструмент, который рисовал бы золотую спираль поверх фотографии, и у меня это получилось.

Для начала нашел в интернете генератор спирали Фибоначчи на js: ответ на stackoverflow.com, где в конце автор ответа дал ссылку на JSFiddle, где можно погонять спираль и понять как она работает. Важно было сделать чтобы спираль рисовалась не из центра, но это решилось вставкой простой конструкции:

canvas.addEventListener("mousedown", function (e) {
    center.x = e.clientX;
    center.y = e.clientY;
}, false);

А для того чтобы спираль рисовалась поверх открытой вебстраницы, нужно добавить элемент canvas, который я сделал по размеру всего окна, и который скролится вместе с вебстраницей (свойство css position:sticky) и рисуется поверх других элементов (z-index:2000):
let el = document.getElementsByTagName("body")[0];
let canvas = document.createElement("canvas");
canvas.id = "can";
el.insertBefore(canvas, el.firstChild);
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
canvas.style.zIndex = "2000";
canvas.style.position = "sticky";
canvas.style.top = "0";
ctx = canvas.getContext("2d");
Чтобы сделать выход из режима рисования спирали, нужно добавить в код такую конструкцию:
document.addEventListener("keydown", function(){
    var x=event.key || event.code;
    if(x=="Escape"){
canvas.remove();
    }
})  
Потом весь код копируется и минимизируется, например при помощи сервиса https://jsminify.org/
Минимизированный код теперь можно поместить в букмарклет, который можно сгенерировать у меня на сайте. А можно воспользоваться уже готовой ссылкой: fibo. Эту ссылку можно добавить на панель ссылок и если увидел фото, красивой девушки, то всегда можешь проверить ее фигуру на золотое сечение. 

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

В общем-то на этом и все о чем хотелось бы рассказать. В конце вот еще немного красивого:

Потренироваться накладывать спиральки можно и тут, например.

ЗЫ а можно и на кошках тренироваться)