Как на скрине нельзя, но по ТСР вы можете опросить любой сторонний слейв, главное иметь таблицу адресов регистров.
Добрый день, столкнулся с неясностью в работе блока OCL.UNM_SerialRequest.
Задача - установить связь с платой с микроконтроллером STM32 по RS-485 с помощью собственного протокола обмена. Нужно передавать данные с командой на плату (пакет из 17 байт), получать в ответ пакет с информацией о статусе платы (тоже 17 байт) и отслеживать, есть или нет в данный момент связь с платой. Написал следующую программу (под спойлером). Интервал для её задачи – 20 мс, время таймаута опроса – 100 мс.
Скрытый текст:
При подключении ПЛК к плате связь устанавливается, данные передаются и вычитываются. Непонятки начинаются, когда я физически отключаю плату от ПЛК. Я ожидаю, что ФБ SerialRequest с этого момента начнет на выходе xError выдавать TRUE, а на выходе eError – TIME_OUT. В реальности xError и xDone остаются в нуле, блок остается в статусе xBusy (иногда xBusy на долю секунды уходит в FALSE, затем возвращается), на выходе eError – NO_ERROR.
В буфере, куда помещаются читаемые данные – нули, буфер этот очищается по переменной bNeedReset, которая, по идее, взводится только при завершении работы ФБ с результатом xDone или xError. Если запустить программу, не подключая ПЛК к плате – результат такой же (в буфере нули, ошибки на выходе ФБ нет).
Что я упускаю и как можно добиться индикации ошибки при пропаже соединения?
Цитата:
Что я упускаю
В момент вызова fb_Serial_Request(xExecute:=FALSE); выходы "сбрасываются".Код:ELSIF fb_Serial_Request.xError THEN
bNeedReset:=TRUE; // флаг необходимости очистки буферов
fb_Serial_Request(xExecute:=FALSE);
END_IF
Поэтому глазами вы не видите xError и eError - к концу цикла, в котором они детектированы, они уже сброшены.
Вы можете добавить внутрь ELSIF счетчик ошибок для наглядности.
Или запускать таймер от NOT(fb_Serial_Request.xDone) - в стиле "успешных транзакций не было уже 5 секунд, пора бы зажечь аварийную лампу".
Спасибо за консультацию, именно это и происходило. Добавил запись события fb_Serial_Request.xError = TRUE в промежуточную переменную bCommunicationError, а также счётчик таких событий. При отключении провода от платы эта переменная уходит в TRUE, счетчик растёт. При подключении провода обратно - всё восстанавливается. Привязал переменную-индикатор связи дополнительно к этой промежуточной переменной.
Заодно выяснил, что при таймауте в 100 мс и интервале задачи 20 мс ошибки появляются и при подключенной линии (хотя буфер вычитывается), а при таймауте в 101мс ошибки пропадают. Похоже, связано с интервалом задачи, при его уменьшении до 15 мс при таймауте 90 мс все работает стабильно.
Добрый день
Подскажите как из кода работающей программы поменять параметры RS485 на плк 210
метод описанный в документе "Настройка обмена по протоколу Modbus" не срабатывает
Modbus_Master_COM_Port.xStop:=True;
Modbus_Master_COM_Port.UpdateComParameters(115000, 1,0,8,2,true,5);
Modbus_Master_COM_Port.xStop:=False;
Добрый день.
Посмотрите это видео:
https://oscat.ru/wp-content/Video/Co...geSettings.mp4
написал код как в Видео у меня ПЛК210 первый RS485 настроен на мое устройство и работает.
при подаче команды INIT запускающей Modbus_Master_COM_Port.UpdateComParameters с этими же параметрами контроллер пишет
в состоянии 'не запущено' и SLAVE становится серым
IF (Init) THEN
Modbus_Master_COM_Port.Enable:=FALSE;
Ton_1(IN:=TRUE, PT:=T#1S);
IF Ton_1.Q THEN
Modbus_Master_COM_Port.UpdateComParameters
(
udiBaudrate := 115200,
usiMedium := 1,
usiParity := 0,
usiDataBits := 8,
usiStopBits := 2,
xPolarization:= FALSE,
COMPORT := 5
);
Encoder_ob.SlaveAddress:=5;
Modbus_Master_COM_Port.Enable:=TRUE;
Ton_1(IN:=FALSE);
Init:=FALSE;
END_IF
END_IF
Повторил проблему у себя.
Она связана с
По каким-то причинам (вероятно, из-за бага) драйвер не воспринимает значение 2 и формирует ошибку.Код:usiStopBits := 2;
Если установить 1 - работает корректно.
Я бы рекомендовал проверить, имеет ли значение эта настройка на стороне прошивки вашего slave-устройства - возможно, подойдет и 1 стоп-бит.
Если нужно принципиально выставить именно 2 стоп-бита, то потребуется организовать обмен через библиотеку OwenCommunication.
решение найдено:
данный метод не понимает количество стоп бит равное 2 и это нигде не написано в описаниях
Здравствуйте.
Рассматриваю возможность опроса устройств RS-485 с СПК210 через шлюз МКОН (последовательные порты уже все заняты). Возник такой вопрос: можно ли менять адрес опрашиваемого МКОНа в Codesys без перепрограммирования контроллера?
Поясняю. Допустим при разработке ПО задал IP-адрес СПК 192.168.0.10, адрес МКОН 192.168.0.11, в Codesys прописал адрес слейва и передал все это заказчику. Через некоторое время заказчик подключает СПК к своей системе диспетчеризации и меняет адрес СПК (например) на 10.0.0.20, после чего МКОН и СПК оказываются в разных подсетях и перестают друг друга видеть.
Вопрос: можно ли как-то вынести в интерфейс контроллера настройку параметров сети ведомого устройства? Или есть другой вариант решения этого вопроса?
Добрый день.
Поменять в проекте СПК IP-адрес устройства, которое он будет опрашивать, можно:
https://owen.ru/forum/showthread.php...l=1#post296714
Еще проще это сделать, если обмен организован через библиотеку OwenCommunication.
Другой вопрос - как будет изменен IP-адрес в настройках самого МКОН.
Заказчик сделает это через OwenConfigurator?
Потому что записать в регистры МКОН новый IP-адрес со стороны СПК, конечно, можно, а вот реализовать программный ребут МКОН, чтобы они вступили в силу - будет крайне трудоемко.
Разве что через релейный выход отключать/включать его питание, что выглядит довольно сомнительным и избыточным решением.
Ну это все же еще можно сделать, хотя бы в телефонном режиме - все же это проще, чем перезаливать ПО в контроллер.
В другую сторону если подумать - СПК можно два IP-адреса задать для двух разных подсетей - чтобы в одной он МКОН опрашивал, а в другой был доступен для диспетчеризации?
Понял, спасибо
В Linux есть IP aliasing (возможно и в Винде, ни разу не пользовался).
Доступно ли это для ПЛК тоже не знаю.
Может в эту сторону покопать?
Здравствуйте! Возможно ли использовать преобразователь волоконно-оптический "Ethernet-FX-SM40" BOLID для передачи данных по Modbus TCP от ПЛК210?
Все же я попробовал так сделать - и все заработало.
Выглядит это так: СПК имеет IP адрес 1 192.168.0.10 (предполагается, что его можно менять под сеть диспетчеризации) и IP адрес 2 192.168.2.10 (используется для опроса TCP-слейвов, его менять нельзя).
МКОН имеет IP адрес 192.168.2.11, к нему подключен для теста модуль МВ110-224.8А.
СПК нормально опрашивает модуль через МКОН и в свою очередь опрашивается по Modbus-TCP через IP адрес 1.
В web-конфигураторе это выглядит так:
Вложение 87781
Вложение 87782
А в экранном конфигураторе так:
Вложение 87783
Карбофос у вас оба адреса в одной подсети. Адрес 192.168.2.10/24 входит в сеть 192.168.0.10/16
Добрый день!
Необходимо организовать опрос ПЛК (ПЛК в режиме Slave) по Modbus с ВУ по двум интерфейсам: RS485 и Ethernet. Регистры для обоих интерфейсов должны быть общие.
Подскажите, пожалуйста, возможно ли организовать такой опрос стандартными средствами конфигурирования в среде Codesys 3.5 SP16 или необходимо использовать библиотеки?
Добрый день.
Через библиотеку будет существенно проще, чем стандартными средствами:
https://oscat.ru/wp-content/Video/Co...RtuTcpSync.mp4
Для Modbus RTU Slave:
https://ftp.owen.ru/CoDeSys3/04_Libr...mpiled-library
https://ftp.owen.ru/CoDeSys3/04_Libr...mpiled-library
Эти библиотеки будут работать на любых контроллерах.
Они созданы в старой версии CODESYS, но будут работать и в новых.
Пример их использования: https://oscat.ru/wp-content/Video/Co...aveLibrary.mp4
Для Modbus TCP Slave - встроенная библиотека CODESYS:
https://content.helpme-codesys.com/e...busServer.html
Имя: Modbus Slave, COM Port
Производитель: 3S - Smart Software Solutions GmbH
Группы: Слейв Modbus Serial
Версия: 3.5.16.0
Подскажите пожалуйста это последняя версия?
Всем Доброго времени суток.
Столкнулся с такой бедой как "Числа в формате PIC с плавающей запятой" при опросе по RS485 счетчика газа Ирвис К-300.
Вложение 88112
Прошу вашей помощи, может кто то сталкивался с такой проблемой ранее, как эти значения привести к понятным REAL?
В сети нашел только пример на языке С, но я в нем вообще не понимаю, что в нем происходит, может у кого есть пример на ST?
Код:class Program
{
static void Main(string[] args)
{
byte[] send = new byte[3] {0x65, 0x29, 0x8A};
Console.WriteLine(PICtoIARfloat(send));
Console.ReadLine();
}
static float PICtoIARfloat(byte[] PICfloat)
{
byte[] bt = new byte[4];
//Первый байт float IAR
bt[0] = 0x00;
//Второй байт
bt[1] = PICfloat[0];
//Третий байт
bt[2] = PICfloat[1];
bt[2] &= 0x7f; //Сброс знака
if ((PICfloat[2] & 0x01) > 0)
{
//Если мл.бит установлен
bt[2] |= 0x80;
}
//Четвертый байт
bt[3] = PICfloat[2];
bt[3] >>= 1;
if ((PICfloat[1] & 0x80)>0)
{
//Если знак отрицательный
bt[3] |= 0x80;
}
else
{
bt[3] &= 0x7F;
}
return ToFloat(bt);
}
static float ToFloat(byte[] input)
{
return BitConverter.ToSingle(input, 0);
}
}
Им блин что, регистров было жалко?
Вот функция на ST, можете проверить её с примером из документа. У меня результаты совпали.
Можно упростить, если использовать объединение (UNION).
Код:FUNCTION PIC_TO_REAL : REAL
VAR_INPUT
picData : ARRAY[0..2] OF BYTE; // Три байта в формате PIC: [мл.байт мантиссы, ст.байт мантиссы, порядок]
END_VAR
VAR
abyTemp : ARRAY[0..3] OF BYTE; // 4 байта
dwTemp : DWORD;
result : REAL;
END_VAR
Код:abyTemp[0] := 0; //Нулевой байт REAL = 0
abyTemp[1] := picData[0]; // Первый байт REAL = нулевой байт PIC (мл. байт мантиссы)
abyTemp[2] := picData[1] AND 16#7F; // Второй байт REAL = первый байт PIC (ст. байт мантиссы) со сброшенным знаком
// Проверка младшего бита порядка (из второго байта PIC)
IF (picData[2] AND 16#01) <> 0 THEN
// Если младший бит установлен, устанавливаем старший бит второго байта REAL
abyTemp[2] := abyTemp[2] OR 16#80;
END_IF
// Третий байт REAL = второй байт PIC, сдвинутый вправо на 1 бит
abyTemp[3] := SHR(picData[2], 1);
// Установка знакового бита в третьем байте REAL
IF (picData[1] AND 16#80) <> 0 THEN
// Если знак отрицательный (старший бит первого байта PIC установлен)
abyTemp[3] := abyTemp[3] OR 16#80;
ELSE
abyTemp[3] := abyTemp[3] AND 16#7F;
END_IF
// Копируем байты в DWORD
dwTemp := SHL(TO_DWORD(abyTemp[1]), 8) OR
SHL(TO_DWORD(abyTemp[2]), 16) OR
SHL(TO_DWORD(abyTemp[3]), 24);
// Копируем DWORD в REAL через указатель
MEM.MemMove(ADR(dwTemp), ADR(result), SIZEOF(result));
PIC_TO_REAL := result;
Здравствуйте!
Есть несколько похожих проектов на разных объектах, но суть одна.
ПЛК 210-03 выступает в роли Modbus Slave. Периодически к нему подключаются различные ПЛК-мастера, которые передают свой ID. Если ID = 0, то ПЛК-Slave считает, что никто не подключен.
На одном объекте при отключении мастера ID всегда обнуляется самостоятельно, на другом объекте при отключении ID остаётся прежним и не сбрасывается в "0".
Через сравнение проектов практически нет отличий.
Вопрос - где-то есть настройка на подобии "обработка ошибок" для Master (сохранять последнее значение / установить в ноль), но для Slave-устройства?
Скрин настроке ПЛК-SlaveВложение 88124
Благодарю, Евгений! Попробую галочку "Закрыть сокет TCP".
Насчёт версий:
Modbus TCP Slave Device: 4.3.0.0 0 - одинаковые в обоих проектах;
Ethernet: 3.5.15.0 - одинаковые в обоих проектах;
Device PLC210: 3.5.14.36 - старый проект, в котором данные при отключении мастера обнуляются, 3.5.17.31 - новый проект, с теми же настройками, в котором данные сохраняются.
Друзья , у меня есть частотник INVT GD350-19 с платой расширения EC-TX510B . Помогите подключить его к ПЛК210-12 по модбас TCP , второй день мучаюсь.