Показать сообщение отдельно
Старый 26.03.2018, 19:40   #13
tuxnsk
Новичок
 
Регистрация: Jun 2017
Сообщения: 19
Благодарил(а): 0 раз(а)
Поблагодарили: 0 раз(а) в 0 сообщениях
По умолчанию Ответ: Случайные значения регистра аварий

Таки отловил проблему, в общем неверный ответ присылал все же контроллер, но он был в этом не виновен
В общем дело было так, сегодня подключали еще один объект с очень хреновой линией связи (менее 50% запросов проходило) и на нем свистопляска в показаниях куда чаще начала проявляться. Залез в библиотечку модбаса (которой опрашивал контроллеры), сделал вывод всех данных в лог и поймал такую пачку сообщений:

325638 < [251]
325679 < [255]
325697 < [183]

325709 > [1,3,160,33,0,2,182,1]
325721 < [1,3,4,27,210,190,228,45,5]
325733 > [1,3,160,33,0,2,182,1]
325734 < [254]
325745 > [1,3,160,39,0,2,86,0]
325746 < [1,3,4,27,210,190,228,45,5]

325754 < [254]
325757 > [1,3,160,41,0,2,55,195]

(первая колонка - время в миллисекундах, дальше данные, зеленый запрос, красный - ответ)

Жирным выделил момент, когда произошла описанная мною ситуация, для тех кто не понял, поясню... По логу видно что прилетают иногда одиночные байты данных - которые на самом деле не являются данными, а просто помеха. В выделенном куске кода эта помеха и внесла смуту. По порядку:
[1,3,160,33,0,2,182,1] - тут мы запрашиваем данные с некоего регистра (ПЛК 1, функция чтения 3, адрес 160,33, 2 регистра, CRC)
[254] - тут прилетела помеха и библиотека решила что вот и ответ пришел, само собой такой пакет распознался как корявые данные и библиотека сообщила программе что данные пришли криво, у меня в коде при таких ситуациях делаются повторно несколько попыток, и это как раз была последняя. Данные мы не получили, да и хрен с ними, чтобы не застревать на одном месте, запрашиваем следующей строкой следующие регистры:
[1,3,160,39,0,2,86,0] - адреса следующих регистров 160,39 (какраз мой регистр аварии). Вот тут и возникла ситуация, когда контроллер предыдущий запрос нормально принял, начал доставать из себя данные и готовиться выдать их на линию, и что там какие-то помехи были, он и не в курсе (и что следующий запрос прилетел уже). И само собой далее контроллер отвечает этими данными:
[1,3,4,27,210,190,228,45,5], но так как по логике программы опроса уже запрос улетел на следущую порцию данных, то программа и ожидает их, а в реальности данные прилетают из предыдущего регистра. В результате и получаем достоверные по CRC данные, но не в том регистре где ожидали.

А теперь кто в этом виноват и как таких ситуаций избежать. Само собой в первую очередь жопу монтажникам и проектировщикам напинать надо, за такую линию, но не об этом сейчас.
Проблема 1: в библиотеке выставляется таймаут ожидания запроса, но он работает только при отсутствии данных на линии, в случае ошибки он игнорируется и возвращается управление программе. По моему было бы логичнее при возникновении ошибки все же дожидаться окончания таймаута, тогда бы может быть и потеряли вместе с помехой ответ, но не возникло бы каши... в общем решать тут автору, как лучше делать, закину ему для примера тоже этот лог.
Проблема 2: в моем коде после всех попыток получить значение регистра сразу же запрашивался следующий (таймаут делал только между попытками), и мой код успевал отправить запрос целиком еще до ответа контроллера. На данный момент добавление таймаута при ошибке между запросами исправило проблему.

Последний раз редактировалось tuxnsk, 26.03.2018 в 19:55
tuxnsk вне форума   Ответить с цитированием