PDA

Просмотр полной версии : MB_TcpSlave из Owen Communication - AT declaration и RETAIN



Dmitry_DAK
01.06.2026, 12:31
При использовании привязки переменных к памяти контроллера командой "АТ" перестаёт работать RETAIN. Записанные в регистры значения не сохраняются после перезагрузки контроллера. Привязка позволяет напрямую работать с регистрами MODBUS с разными форматами данных, без их конвертации что очень удобно. Если не использовать АТ, массив ModbusBuffer в RETAIN сохраняется.
В чем ошибка?

PROGRAM ModbusSlave
VAR
//ФБ Modbus Slave
fbTcpSlave : OCL.MB_TcpSlave;
END_VAR

VAR RETAIN
//Буфер MODBUS
ModbusBuffer AT %MW0:ARRAY [0..99] OF WORD;

//Регистр MODBUS в формате Real
Reg_REAL AT %MD1 :REAL;
END_VAR

//Программа MODBUS Slave
fbTcpSlave(xEnable:=TRUE,
pData:=ADR(ModbusBuffer),
szSize:=SIZEOF(ModbusBuffer),
);

Евгений Кислов
01.06.2026, 12:52
Добрый день.
Я предполагаю, что никакой ошибки нет - просто так работает механизм AT-адресации.
На мой взгляд, в вашем случае проще создать структуру с переменными нужного типа и объявить ее экземпляр в области RETAIN.
Пример есть здесь, начиная с 01:35:00: https://owen.ru/media/video/webinar_170625

Cs-Cs
01.06.2026, 12:57
Подтверждаю! У меня SLAVE через структуру, и объявлен как RETAIN.
Всё работает.

Dmitry_DAK
01.06.2026, 14:01
Задача такая. Есть различные переменные(INT,DINT,REAL). Их необходимо в произвольном порядке (в соответствии с ТЗ) привязывать к различным регистрам MODBUS. Допустим CalTemp должен лежать в Holding (INT) регистре 900, а CalPress(INT) в регистре 10. Регистры 100...899 пока зарезервированы. Как в структуре указать номер регистра для конкретной переменной? Или нужно описывать весь массив (1000 регистров)? Какое решение лучше использовать?

kondor3000
01.06.2026, 14:50
Задача такая. Есть различные переменные(INT,DINT,REAL). Их необходимо в произвольном порядке (в соответствии с ТЗ) привязывать к различным регистрам MODBUS. Допустим CalTemp должен лежать в Holding (INT) регистре 900, а CalPress(INT) в регистре 10. Регистры 100...899 пока зарезервированы. Как в структуре указать номер регистра для конкретной переменной? Или нужно описывать весь массив (1000 регистров)? Какое решение лучше использовать?
Изначально у вас Retain был на 100 регистров, теперь вы на 1000 перемахнули. Пример структуры слейва на 1000 регистров 89383
из которой используются только с 512 по 517 регистр, хотя и остальные доступны тоже.
Важно, все 32 битные переменные (2 регистра) поместить по чётным адресам, иначе адреса сместятся при выравнивании.

Cs-Cs
01.06.2026, 14:51
Оо! Это КЛАССНО для структуры!

Да! В ПЛК память расположена последовательно.
Так что описать надо будет всю тыщу.

Но сделать это, условно, так:
...
CallPress : INT;
...
wReserved: ARRAY [1..800] OF WORD;

CalTemp : INT;

(и подсчитать номера регистров)
(А всю структуру объявить в области RETAIN)

Я накну вот этот пост свой: https://cs-cs.net/codesys-modbus-karta-registrov-struktury
Он под 2.3, но там я показал пример структуры и того, как с ней работать.

Dmitry_DAK
01.06.2026, 20:30
Благодарю! Идея понятна. Так и сделаем. Сожалею что с AT не получается. Основная задача - импортозамещение, в буржуйском контроллере АТ и RETAIN хорошо дружат...