PDA

Просмотр полной версии : Вызов таймера без параметров (modbus.lib)



aRRma99
23.05.2017, 19:30
Добрый день уважаемые товарищи. Уже не первую неделю веду войну с чекнутой библиотекой modbus.lib. Искажение буффера я уже поправил. Но вой проблемы с таймингом. В частности ни как не пойму что же означает вызов таймера без параметров на языке ST.
пример из ФБ MB_UNI_IO


tonTimer(); (* отработать цикл таймера тайм-аута *)
IF tonTimer.Q = TRUE THEN (* стработал таймер любого тайм-аута *)
IF StartFrame = FALSE (* кадр не принимался или *)
OR DataSize < 5 (* размер кадра меньше допустимого *)
THEN
Exception := EXC_TO; (* установить ошибку тайм-аута *)
ELSE (* кадр принят, контроль CRC *)
DataSize := DataSize - 2;
CrcReg := MB_CRC(ADR(DataBuf), DataSize);
IF DataBuf[DataSize] <> WORD_TO_BYTE(CrcReg) OR
DataBuf[DataSize + 1] <> WORD_TO_BYTE(SHR(CrcReg, 8)) THEN
Exception := EXC_TO; (* установить ошибку тайм-аута *)
ELSIF DataBuf[1].7 = TRUE
THEN (* исключение протокола MODBUS*)
Exception := DataBuf[2];
END_IF
END_IF
Complete := TRUE; (* признак завершения операции *)
END_IF

Собственно что происходит в первой строке??? Мои варианты:
1. Таймер работает с заранее заданными параметрами.
2. Если работает с заранее заданными параметрами то он начинает отсчет с нуля или продолжает отсчет если уже был включен выше.
3. Это дело рук ИНОПЛАНЕТЯН!!!111
4. Программа будет стоять на этой строке пока он не досчитает.

Вот собственно для начала хватит.

capzap
23.05.2017, 19:35
вариант номер один

ЗЫ раскрываете в окне объявлений данный таймер и наблюдаете его работу

aRRma99
23.05.2017, 19:52
Предположим я поверил. Он работает с заранее заданными параметрами. А когда он отсчет начал в моменте когда ему что-то присвоили или же в этом моменте tonTimer();. и вообще программа там будет стоять и чего-то ждать? и вообще в чем смысл этой записи?
Все тот-же пример из библиотеки modbus.lib


IF Mode = MB_RTU THEN (* прием кадра RTU *)
IF MB_RTU_RX(
ComHandle, (* дескриптор последовательного порта SysLibCom *)
DataBuf, (* буфер принимаемого кадра *)
DataSize, (* указатель буфера кадра *)
StartFrame) (* признак начала кадра *)
= RX_CONT THEN (* приемный буфер обновился *)
tonTimer(IN := FALSE); (* остановить таймер тайм-аута *)
tonTimer(IN := TRUE, (* запустить таймер на ожидание конца кадра *)
PT := T_FRTU);
END_IF
tonTimer(); (* отработать цикл таймера тайм-аута *)
IF tonTimer.Q = TRUE THEN (* стработал таймер любого тайм-аута *)


По сути в IF THEN таймер уже запустился и начал считать до значения T_FRTU и он досчитает до него. Либо таймер умирает как только мы выходим из условия и для этого он еще раз вызывается с параметрами заданными строкой выше. Верно ли я сужу?

capzap
23.05.2017, 19:59
tonTimer(IN := FALSE); - это возможно выполняется однократно из-за условия и означает сброс предыдущего запуска таймера
tonTimer(IN := TRUE,PT := T_FRTU); - это соответственно запуск таймера при наступлении события
tonTimer(); - это цикличное выполнение таймера, чтоб когда нибудь наступило событие tonTimer.Q = TRUE

aRRma99
23.05.2017, 21:28
По первым двум пунктам полностью согласен. А вот с третьим проблема в том что тут сложно понять с каким значением ЕТ он там выполняется. Там строкой ниже написано


IF tonTimer.Q = TRUE THEN (* стработал таймер любого тайм-аута *)

То есть как я понимаю без разницы сработал таймер с значением T_FRTU: TIME := T#3ms; или же с TimeOut: TIME; который мы передали в функцию. Да и вообще судя по мониторингу переменной, там то один записывается то другой...

capzap
23.05.2017, 21:56
заходим http://www.kipshop.ru/CoDeSys/steps/codesys_v23_ru.pdf на страницу 349, там показана работа таймера в виде эпюр, которые должны объяснить работу таймера, чтоб поднять выход Q

aRRma99
23.05.2017, 23:02
заходим http://www.kipshop.ru/CoDeSys/steps/codesys_v23_ru.pdf на страницу 349, там показана работа таймера в виде эпюр, которые должны объяснить работу таймера, чтоб поднять выход QСпасибо) но книгу я в голове держу, с пониманием проблемы нет. В целом к этому посту я уже разобрался что блок MB_UNI_IO держит строку tonTimer(); для двух случаев.
1. Это когда мы не принимаем данные, а только передаем. Тогда у нас таймер отработает с параметром TimeOut который мы передадим в ФБ. Т.к MB_RTU_RX вернет wait и DataSize будет больше 5 если все удачно передали. И по его выходу завершит работу ФБ.
2. И когда мы принимаем данные, он уже отработает с параметром T_FRTU как только функция MB_RTU_RX перестанем принимать байты из порта. И тогда через +-3мс закончится работа всего ФБ.

Собственно со всем этим ужасом я начал банально разбираться из-за 255 ошибки. И вывод тут один. Если вы читаете со слейва данные но получаете 255 и при этом 100% слейв работает адекватно и шлет все как надо(да и порт у нас RS485, на 232 проблемы не будет). Тут скорее всего проблема в том что слейв умудряется ответить быстрее чем за 5мс. Т.к. функция передачи в порт SysComWrite после передачи последнего байта еще гдето 5мс держит уровень на линии. И в этот момент ответ не возможен. В моем случае это помогло.
P.S. у ФБ SysComWrite , есть также таймаут который судя по документации определяет время которое ФБ шлет данные в порт. По факту меняй не меняй его ничего не меняется.

capzap
23.05.2017, 23:12
с каким периодом Вы отправляете запросы? надеюсь не в каждом цикле

ASo
24.05.2017, 06:45
aRRma99, что Вы хотите? Дайте почту, можно в личку - вышлю работающую программу, используйте соответствующий POU как образец.

aRRma99
24.05.2017, 10:37
Товарищи, давайте определимся что в этой теме идет речь о работе библиотеки modbus.lib а конкретно ФБ MB_UNI_IO, о моей программе можно поговорить позже. Для себя я на все вопросы уже ответил, хочу чтобы потомкам что нибудь осталось, а то ОВЕН у нас не умеют ни документацию писать ни примеры к сожалению.
Изначально всплыла проблема с ошибкой таймаута модбас в режиме RTU скорость 9600 RS485, код управляет частотником и опрашивает прибор который измеряет скорость воздуха, 4 поочередных запроса(пока один не выполнится следующий не запускается). Этот же самый код на 115200 работает отлично.
При изучении ФБ MB_UNI_IO выяснилось что функция отправки данных в порт SysComWrite(ComHandle, ADR(DataBuf),DataSize, 0) притягивает уровень на линии еще где-то 5мс после передачи всех данных(это типо интервал тишины, но если его правильно считать для 9600 он должен быть где-то 1,5мс). Что и видно на осциллограмме ниже.
31322
У частотника ПЧВ с завода стоит параметр "минимальное время на ответ 10мс" то есть ему норм. Но наш прибор отвечает чуть быстрее и из-за того что мастер то есть ПЛК еще держит линию ответ от прибора приходит искаженный, что тоже видно на осциллограмме ниже.
31323
Самое интересное что у ФБ SysComWrite тоже есть параметр таймаут, который как написано по документации определяет сколько будет работать блок. По дефолту он 0, по факту меняй не меняй его ничего не изменится.
Вот собственно и все. Если что-то не так пишите, обсудим.