Просмотр полной версии : ПЛК210 Глюки опроса
Задумкин Сергей
05.02.2024, 12:55
Имею ПЛК210, который по RS-485 M(Modbus RTU) опрашивает панель управления ДГУ.
Опрос в Codesys разбит на три канала (66 регистров, 1 регистр и 7 регистров соответственно).
Программа в данный момент отлаживается на стенде в офисе и я решил для пущей достоверности имитировать обмен с помощью ПО Modbus Slave, сгенерировав там все необходимые регистры.
И что я вижу:
Первый канал на 66 регистров ПЛК не читает, по нему идут ошибки.
Вторые два канала (на 1 и 7 регистров) читаются отлично.
После долгих мучений проблема решилась так. Я просто создал еще один такой же к***** скопировал туда все из "неработающего" канала, а первый просто удалил. Ничего больше не менял. И вуаля - все летает.
Проблема замечена уже во второй раз.
Сталкивался кто-нибудь? В каком направлении капать?
Евгений Кислов
05.02.2024, 13:12
Имею ПЛК210, который по RS-485 M(Modbus RTU) опрашивает панель управления ДГУ.
Опрос в Codesys разбит на три канала (66 регистров, 1 регистр и 7 регистров соответственно).
Программа в данный момент отлаживается на стенде в офисе и я решил для пущей достоверности имитировать обмен с помощью ПО Modbus Slave, сгенерировав там все необходимые регистры.
И что я вижу:
Первый канал на 66 регистров ПЛК не читает, по нему идут ошибки.
Вторые два канала (на 1 и 7 регистров) читаются отлично.
После долгих мучений проблема решилась так. Я просто создал еще один такой же к***** скопировал туда все из "неработающего" канала, а первый просто удалил. Ничего больше не менял. И вуаля - все летает.
Проблема замечена уже во второй раз.
Сталкивался кто-нибудь? В каком направлении капать?
Добрый день.
Если проблема повторится еще раз - предлагаю связаться со мной по телеграм (в подписи) и "покопать" вместе.
kondor3000
05.02.2024, 13:14
Проблема замечена уже во второй раз.
Сталкивался кто-нибудь? В каком направлении капать?
С таким же успехом, можно было очистить всё, компилировать всё. А потом перезалить проект в ПЛК.
Stanislav_Y
26.04.2024, 15:10
Добрый день.
1. Есть ПЛК210-12-CS, СП310 (мастер по отношению к ПЛК, подключен по ModbusTCP).
Сам ПЛК как мастер опрашивает по TCP и RTU модули ввода-вывода, датчики уровня, загазованности и прочее (из всего этого пока подключена только СП310).
Для общения с СП310 в узле Ethernet создан ModbusTCP_Slave_Device, в котором 100 Holding-регистров и 160 Input-регистров.
К Input-регистрам привязаны переменные, которые подготавливает ПО ПЛК.
2. На этапе отладки связки СП310-ПЛК210 замечено, что один из Input-регистров в старшем байте (биты с 8 по 15) имеет всегда нули. Т.е. в режиме отладки видно, что привязанная переменная имеет значение 43690 (dec). Однако СП310 читает вместо этого значение 170 (dec).
Отключил СП310, подключил ModbusPoll - то же самое (исключил вариант, что сама панель внутри себя чем то перезаписывает регистр).
3. Если отвязать переменную от "проблемного" регистра и в режиме отладки принудительно фиксировать значение вручную - все отлично. И СП310 и ModbusPoll читают регистр корректно.
4. Закомментировал весь код программы. Оставил только одну строчку "w37Value := 43690;". И эту переменную привязал к регистру. Результат такой же - старший байт где то чем то перезаписывается.
5. Начал последовательно удалять переменные из остальных Input-регистров. И вот что увидел. К первым пяти битам регистра 36, который находится перед "проблемным" 37-мым привязаны переменные типа BOOL (переменные в составе структуры). Вот если эти булевские переменные отвязать, то "проблемный" регистр читается корректно.
Как бороться? Наблюдаем нечто похожее уже не в первый раз
Stanislav_Y
26.04.2024, 15:24
либо с адресацией на единицу не угадали, либо помимо этого еще слова(байты) не перевернули
В этом плане всё в порядке. Все остальные регистры панелью читаются корректно и интерпретируются как надо.
kondor3000
26.04.2024, 15:26
Это называется выравнивание, в вашем случае, при использовании структуры, выравнивание может сдвинуть адреса от 1 до 4 регистров вроде.
Здесь показано выравнивание на примере BYTE, WORD, DWORD
https://owen.ru/forum/showthread.php?t=10555&page=1042#10416
В СDS3.5 так же как в 2.3 работает, в ПЛК слейве.
Проверить можно, создав в панели тиражированием, штук 8 дисплеев, с адресами по порядку, вернуть структуру и смотреть в какой адрес пишется ваш регистр.
МихаилГл
26.04.2024, 15:27
Да, смотрите внимательно. Где то что то забыли. У меня такая же структура сети, всё работает. Была одна проблема при переходе с 14 версии кодесиса на 17, там надо было байты в словах поменять местами.
Stanislav_Y
26.04.2024, 17:28
Это называется выравнивание, в вашем случае, при использовании структуры, выравнивание может сдвинуть адреса от 1 до 4 регистров вроде.
Здесь показано выравнивание на примере BYTE, WORD, DWORD
https://owen.ru/forum/showthread.php?t=10555&page=1042#10416
В СDS3.5 так же как в 2.3 работает, в ПЛК слейве.
Проверить можно, создав в панели тиражированием, штук 8 дисплеев, с адресами по порядку, вернуть структуру и смотреть в какой адрес пишется ваш регистр.
Да, я подозревал выравнивание памяти в структуре, читал про это.
Была структура данных для чтения панелью СП310. В структуре были вперемешку и WORD, и BOOL, плюс еще объединения. Убрал все BOOL и упаковал в прорамме их все в WORD'ды. Проблема решилась.
Все равно не очень понимаю сути, как влияет привязка булевской переменной к полю bit в регистре ModbusTCP_Slave_Device на другой регистр. Для чего тогда эти поля бит нужны в регистрах?
Я ведь когда читаю из модуля ввода битовую маску, я присваиваю битовым полям булевские переменные, которые в свою очередь также упакованы в структуры. Так тоже получается нехорошо делать?
Ставите переменные бит, поставьте сразу 8 или 16, даже если не будете использовать все.
Так как именно так ПЛК и выровнять до 8 или до 16 если последующая real
kondor3000
26.04.2024, 21:38
Все равно не очень понимаю сути, как влияет привязка булевской переменной к полю bit в регистре ModbusTCP_Slave_Device на другой регистр. Для чего тогда эти поля бит нужны в регистрах?
Я ведь когда читаю из модуля ввода битовую маску, я присваиваю битовым полям булевские переменные, которые в свою очередь также упакованы в структуры. Так тоже получается нехорошо делать?
Структура из Маски типа WORD - занимает в памяти 2 байта, все норм, скрин 75454
а вот структура из 8 бит типа BOOL - занимает целых 8 байт.
Если будет нечётное количество BOOL , то и байт будет не четное, соответственно, может залезть на следующую переменную, а точнее сдвинуть её адрес.
Размер структуры измеряю через SIZEOF, вот и думайте что лучше.
Да, я подозревал выравнивание памяти в структуре, читал про это.
Была структура данных для чтения панелью СП310. В структуре были вперемешку и WORD, и BOOL, плюс еще объединения. Убрал все BOOL и упаковал в прорамме их все в WORD'ды. Проблема решилась.
Все равно не очень понимаю сути, как влияет привязка булевской переменной к полю bit в регистре ModbusTCP_Slave_Device на другой регистр. Для чего тогда эти поля бит нужны в регистрах?
Я ведь когда читаю из модуля ввода битовую маску, я присваиваю битовым полям булевские переменные, которые в свою очередь также упакованы в структуры. Так тоже получается нехорошо делать?
Посмотрите здесь (https://blog.engcore.ru/2022/03/21/программирование-плк-на-codesys-bit-c-bool/) про это - интересная статья
Задумкин Сергей
27.04.2024, 10:34
Если будет нечётное количество BOOL , то и байт будет не четное, соответственно, может залезть на следующую переменную, а точнее сдвинуть её адрес.
Не понимаю как это связано. Ну предположим в структуре у меня нечетное кол-во BOOL (обзовем х1, х2, х3, х4, х5), ну выровняется у меня память в структуре. Будет под экземпляр структуры отведено какое-то количества байт неравное кол-ву BOOL-переменных.
Я же могу обращаться к полям этой структуры - скажем, присвоить другой переменной хА значение переменной х1 из объявленной структуры. Не должно же при этом меняться значение какой-то третьей переменной.
Могу ответить невпопад. Есть ещё одна версия, которая может запутить и рассчитана на профессионалов.
Это когда из-за ошибокк в коде программы одна память налезает на другую. Например, если не проверяются границы массивов.
Условно, если ПЛК расположил в его памяти сначала массив на 10 элементов (например), а потом структуру - то если мы начнём записывать в элементами за границами массива (11, 12) - то будем портить память структуры.
Такие ошибки сложно ловятся (и поэтому стараются программировать так, чтобы границы массивов или проверялись, или задавались константами типа VAR arrData [1..MaxBufferSize]. MaxBufferSize - это наша константа, её можно потом и в циклах по массивам использовать), потому что если память за границами массива существует - то она просто затирается, а программа работает. До некоторых пор.
Если же это всё же выравнивание, то лучше протестировать структуру из нескольких WORD, чтобы проверить то, как выравнивание работает.
И ещё, если я не вру (пишу по памяти). Если поискать в справке по CodeSys 3.5, то там в разделе pragma была возможность включить режим выравнивания побайтно.
Задумкин Сергей
27.04.2024, 11:45
Если же это всё же выравнивание, то лучше протестировать структуру из нескольких WORD, чтобы проверить то, как выравнивание работает.
И ещё, если я не вру (пишу по памяти). Если поискать в справке по CodeSys 3.5, то там в разделе pragma была возможность включить режим выравнивания побайтно.
Я пробовал выравнивать побайтно через pragme pack_mode. Не помогло. Все стало работать нормально когда удалил из структуры все BOOL, оставил только WORD и объединения. Необходимые битовые маски из BOOL собрал в коде программы в WORD. И в полях узла ModbusTCP_Slave_Device привязывал уже WORD-переменные, а не битовые.
75458
Кстати, если кто не знал (я точно не знал, но подозревал), то на скриншоте выше область памяти под %QW48 и под %QX96.0 - одна и та же область. Но слово "BOOL" справа от адресов %QX96.n сбивала с толку. Я думал под каждый %QX96.n отводится по байту и %QX96.0 и %QX96.1 будут иметь два разных адреса. Однако если через POINTER взять адреса %QX96.0 и %QX96.1, то они будут одинаковыми и %QX96.0 по %QX96.7 занимают 1 байт. Таким образом логичнее было бы разработчикам Codesys в соотнесении входов-выходов писать тип переменной не BOOL, а BIT.
Я пробовал выравнивать побайтно через pragme pack_mode. Не помогло. Все стало работать нормально когда удалил из структуры все BOOL, оставил только WORD и объединения. Необходимые битовые маски из BOOL собрал в коде программы в WORD. И в полях узла ModbusTCP_Slave_Device привязывал уже WORD-переменные, а не битовые.
75458
Кстати, если кто не знал (я точно не знал, но подозревал), то на скриншоте выше область памяти под %QW48 и под %QX96.0 - одна и та же область. Но слово "BOOL" справа от адресов %QX96.n сбивала с толку. Я думал под каждый %QX96.n отводится по байту и %QX96.0 и %QX96.1 будут иметь два разных адреса. Однако если через POINTER взять адреса %QX96.0 и %QX96.1, то они будут одинаковыми и %QX96.0 по %QX96.7 занимают 1 байт. Таким образом логичнее было бы разработчикам Codesys в соотнесении входов-выходов писать тип переменной не BOOL, а BIT.
Ну надписи в столбце слева "bit0...bit15" тоже как-бы намекают... А BOOL наверное говорит о том, что можно к каждому из битов %QX... привязать отдельную переменную типа BOOL
Powered by vBulletin® Version 4.2.3 Copyright © 2025 vBulletin Solutions, Inc. All rights reserved. Перевод: zCarot