PDA

Просмотр полной версии : Проблема с библиотекой modbus



Evgenn
23.05.2011, 14:04
Здравствуйте.
Использую библиотеку modbus. ПЛК мастер. Версия codesys 2.3.9.26. Возникли следующие вопросы:

1) Куда в буфер записывается ответ от устройства slave? Такое ощущение что при каждом запуске запись происходит рандомом. На первом скрине видно что запись произошла в buffer[24]..buffer[29], причем в каждом следующем цикле происходит сдвиг.

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

Заранее спасибо за помощь.

4094

4095

4096

Алексей Дмитриев
25.05.2011, 09:44
Таймаут имеет право быть из-за рассинхронизации.:( То есть когда получаете таймаут в приемном буфере мусор, если cmpl & err=0 - забираете данные. Как-то так.;) Успехов.

Evgenn
25.05.2011, 11:30
Алексей Дмитриев, В буфере не мусор, а адекватный ответ от slave устройства, но в неадекватном месте буфера:( А err всегда равно 255, то есть ошибка таймаута. Даже не знаю что делать, хоть брать и писать свои функции modbus:)

Алексей Дмитриев
25.05.2011, 14:37
Я пользовал на ПЛК63, работает. err=255 не всегда. Интересно, что когда читаешь из регистров ввода, то данные в буфере верные только когда err=0.
И с чего Вы взяли, что данные не там, где должны быть это не мусор? Похоже у Вас всегда таймаут, то есть слейв не понимает запрос, подумайте над этим (скорость, четность и т. п.).

Вот кусок кода чтения входов с МДВВ:

1:
(*Чтение маски значений входов МДВВ *)

RD_REGS(
Enable:= ENABL, (* разрешение работы блока *)
Mode:= MB_RTU, (*режим приема*)
DevAddr:= SLAVE_ADDR, (*адрес*)
FirstAddr:= 51, (*номер первого регистра*)
Quantity:= 1, (*количество читаемых регистров*)
ComHandle:=Settings.Port , (*номер сом-порта*)
TimeOut:=TimeOut, (*таймаут*)
Buffer:=RD_Buffer , (* буфер данных *)
Complete=>cmpl , (* скопировать признак завершения операции *)
Exception=>err , (* скопировать регистр ошибок *)
ByteCnt=> DataSize); (*кол-во считанных байтов *)

IF CMPL AND ERR=0 THEN
INP_WORD:=BYTE_TO_WORD(RD_BUFFER[1]) OR SHL(BYTE_TO_WORD(RD_BUFFER[0]),8);
WORK_IDENT:=0;
END_IF

Успехов!;)

Evgenn
26.05.2011, 09:16
И с чего Вы взяли, что данные не там, где должны быть это не мусор? Похоже у Вас всегда таймаут, то есть слейв не понимает запрос, подумайте над этим (скорость, четность и т. п.).


В том то и дело, я не знаю в каком месте массива buffer должен быть ответ от slave, при каждом запуске ответ появляется в разных местах, а потом при каждом новом цикле инкрементируется, slave запрос понимает и отвечает на него, потому что приходит адекватный ответ, на первом скрине я указал этот ответ slave. И да, действительно, таймаут у меня всегда.

Для проверки настроек порта (скорость, четность) просто формировал посылку (без использования библиотеки modbus) и принимал ответ от slave, все работает.

И все таки интересно, ответ надо смотреть в buffer[], правильно? а где его там надо смотреть? buffer[0]..buffer[5] ?

Алексей Дмитриев
26.05.2011, 11:52
Ответ надо читать, конечно, с нуля буфера!
Вот же - читаем один регистр и преобразуем в 16-ти разрядный (word) формат!
IF CMPL AND ERR=0 THEN
INP_WORD:=BYTE_TO_WORD(RD_BUFFER[1]) OR SHL(BYTE_TO_WORD(RD_BUFFER[0]),8);

Evgenn
27.05.2011, 08:59
Алексей Дмитриев, к сожалению ничего не получается с этой библиотекой:( Начал писать свою, написал одну функцию, работает:)
Спасибо за помощь:)

Evgenn
27.05.2011, 15:13
Валенок, на третьем скрине ВСЯ программа, там все указано. Могу сказать, что сейчас с теми же настройками порта все работает с моей функцией.

Королёв Максим
27.05.2011, 16:26
Evgenn, вы небоглибы выложить здесь вашу функцию.

Evgenn
27.05.2011, 16:46
Королёв Максим, пока написана только функция modbus 0x01, всего буду делать еще 3 функции, в понедельник постарюсь выложить:)

Еще забыл добавить, ПЛК у меня BECK SC143 - master и панель СП-270 - slave.

Evgenn
27.05.2011, 16:58
а еnable где падает ?

Нет, не падает.

Максим Tomahawk
22.07.2011, 13:42
Соединил два ПЛК-100 и хочу считать регистр из Slave. СОМ-порт нормально открывается, с номерами регистров и другими настройками тоже давно разобрался, но возникает такая же ошибка таймаута, потому что устройства не могут между собой связаться и вечное ожидание RX_WAIT происходит, даже старт-бит не приходит ) Программа уже написана, но не могу пока грамотно связать два устройства... Проблема как понимаю может быть из-за: 1) настроек в Slave и Master, 2) неисправном кабеле 232 или 485 интерфейса. А ещё из-за чего? На что бы посоветовали обратить внимание?

Насчёт того куда приходят данные. Открываете блокнотом овеновскую библиотеку Modbus, там всё русскими комментариями расписано. Ищите нужный вам ФБ по имени и среди языка ST можно разглядеть, что Buffer[4] это старший байт значения, Buffer[5] младший - в зависимости от ФБ найти нужное.

Максим Tomahawk
23.07.2011, 09:57
Валенок, маркер-старт будет привычнее звучать? В последовательной передаче он называется старт-бит, тем более StartFrame: BOOL; Не придирайтесь.

А в КДС никак ?
а по существу ответить никак? Какая разница где я код посмотрю, я вообще в view64 глядел, потому что оформление приятнее.

Максим Tomahawk
26.07.2011, 07:11
Задача простая, есть два ПЛК-100.24.К.М., которые соединены по RS-485, нужно записать регистр в устройсве Slave и считать из него другой регистр. Пробовал сделать как написано в примерах "Modbus запись Int и Real (FBD)" и чтение, но таким способом не получилось. Сделал через конфигурацию ПЛК, где в Master просто добавил Universal Modbus Device, и в нём Register Input Module и Register Output Module. Через них всё заработало, а программно никак )

Номер СОМ-порта в примерах указан как нулевой для 485 интерфейса, поэтому Кодесис при подключении всегда пишет Invalid и из-за этого нельзя посмотреть результат своей программы. В библиотеке SysLibCom.lib в типах данных указано
TYPE PORTS : (COM1:=1, COM2, COM3, COM4, COM5, COM6, COM7, COM8);
Но везде в примерах пишут 0. У меня RS-485 через СОМ1 заработал.


Время цикла какое ?
5 мс на обоих, пробовал менять, не повлияло. Для простых задач 1 мс было бы достаточно?