Minimalmodbus, случайным образом генерирует неверный crc

#python #modbus #minimalmodbus #modbus-tk

Вопрос:

В настоящее время я работаю над проектом сбора данных с помощью RaspberryPi. Когда я запускаю сценарий запроса, иногда (редко, но слишком часто) мой подчиненный (компьютер) обнаруживает ошибку CRC или недопустимую длину. Я предполагаю, что ошибка может быть вызвана тем фактом, что, поскольку мой скрипт быстр и запрашивает сотни регистраций за несколько секунд, иногда сообщение неполное, и мои подчиненные распознают его как неправильное сообщение. Я хотел знать, возможно ли, что minimalmodbus неправильно рассчитан по времени и иногда отправляет неправильный или неполный запрос (неполный).

Ошибка, возвращенная на ведомом устройстве:

 invalid request: Invalid CRC in request
 

Это типичная ошибка, которую я получаю от своего хозяина, когда подчиненный не знает, что ответить:

   error = SLAVE_ERRORS[str(e)]
KeyError: "Checksum error in rtu mode: '\x8aÿ' instead of '\x8fF' . The response is: '4ÿ\x07$Ê\x8aÿ' (plain response: '4ÿ\x07$Ê\x8aÿ')"**
 

Я использую modbus_tk на ведомом устройстве для эмуляции ведомого устройства modbus. И далее, как правило, часть моего кода, которая запрашивает значения у ведомого устройства, которые зависят от типа значения.

     try:
        try:
            var_register = file_var[i]['varRegister']
            var_type = file_var[i]['varType']
            var_use = file_var[i]["varUse"]
            var_name = file_var[i]["varName"].strip()

            if '#' in var_register:
                continue
            elif var_type=='U16' or var_type=='I16' or var_type=='S16':

                value = inst.read_register(
                    int(var_register),
                    0,
                    3, 
                    not bool(file_var[i]['varSigned'])
                ) 

            elif var_type=='U32' or var_type=='I32' or var_type=='S32':

                value = inst.read_long(
                    int(var_register),
                    3, 
                    not bool(file_var[i]['varSigned'])
                ) 
 

Поскольку моим первым предположением была проблема с синхронизацией, я случайно вставил «time.sleep», чтобы рассчитать время моих запросов, но ошибки все еще возникают. И это совершенно случайно, иногда это будет работать в течение 5 минут, а иногда всего за несколько секунд до моей первой ошибки CRC. У вас есть какие-нибудь идеи о том, куда мне следует заглянуть? Заранее спасибо за вашу помощь!

ПРАВКА: Мой компьютер действует как подчиненный с помощью скрипта modbus_tk, эмулирующего несколько подчиненных устройств. RPI-это мастер, запрашивающий регистры и их значения. все подчиненные устройства настроены так, чтобы иметь значения в этих конкретных регистрах, чтобы избежать ошибки незаконного адреса. Физическое соединение представляет собой преобразователь USB в RS485, RPI оснащен шляпой, управляющей входом/выходом RS485. Таким образом, на самом деле это связь по протоколу ModBus RTU. Ведомое устройство выполняет циклы и отправляет ответ при поступлении запроса.

EDIT2: Итак, я исследовал немного дальше и нашел кое-что интересное. Я получил ошибку (на этот раз на ведущем устройстве), подчиненный, по-видимому, отправил неправильную контрольную сумму… изучая его, я обнаружил, что контрольная сумма, сгенерированная modbus_tk, была в порядке, но ответ, полученный мастером, был другим. Похоже, что некоторые байты изменились на дороге, что странно. Откуда это могло взяться? Проблема с оборудованием? Эта ошибка возникает только при опросе нескольких регистров (более 2 одновременно). все остальные запросы в порядке, если количество запрашиваемых регистров равно 1 или 2.

Комментарии:

1. может быть, вы можете объяснить свою настройку немного лучше? Как вы подключаете ПК и RPi? Протокол TCP Modbus? Тогда куда же подходит Modbus RTU? Кто из них хозяин, а кто раб? Раб что-то читает или просто отправляет поддельные кадры? Обнаружены ли ошибки CRC в протоколе Modbus RTU или TCP? Слишком много открытых концов, чтобы быть в состоянии помочь.

Ответ №1:

Нет, это не странно, это, вероятно, шум или другая проблема с оборудованием.

Именно поэтому существует CRC, чтобы убедиться, что вы получаете на ведущем устройстве те же значения, которые отправляет ведомое устройство.

У вас, скорее всего, есть:

  1. не соединил ГНД вместе
  2. очень плохой источник питания
  3. очень перепутанные провода
  4. среда, в которой у вас есть большие электродвигатели или любой другой источник шума

Моя ставка 1: вы думали, что RS485 двухпроводный (у вас есть только эти соединения A и B или и -, верно?).

Я не собираюсь вдаваться здесь в подробности, потому что вы должны быть в состоянии найти тысячи, если не миллионы ссылок и сообщений, в которых эта конкретная война велась с начала времен. Достаточно сказать, что если у вас возникли проблемы с шиной всего с двумя проводами, вы, вероятно, решите проблему, добавив третий, соединяющий GNDS на обоих устройствах вместе. Это часто бывает, когда одно или оба устройства работают от батареи или имеют изолированный источник питания.

Если вы хотите узнать больше, вы можете прочитать этот документ. Некоторые особенно пикантные абзацы, касающиеся вашего вопроса:

Запуск RS-422/485 на расстоянии нескольких десятков футов по качественному кабелю с хорошей защитой и заземлением может быть практически безошибочным. Однако это не то, для чего люди используют RS-422/485. Любой электрический сигнал, проходящий по проводу длиной более 1000 м (например, антенна длиной более 3300 футов), будет улавливать шум. Дифференциальная витая пара RS-422/485 помогает уменьшить влияние этого шума, но вы должны предположить, что каждый день происходит несколько ошибок связи. Это означает, что длинные линии RS-422/485 подходят только для протоколов, которые включают правильное обнаружение ошибок (CRC или контрольную сумму блока).

и:

К сожалению, заземление для RS-422/485 является одним из наиболее неправильно понятых аспектов последовательной связи. Многие люди считают, что RS-422/485 не требует заземления. Один из мифов состоит в том, что сигналы плюс ( ) и минус (-) действуют как токовая петля и сами по себе завершают электрическую цепь. Другой миф заключается в том, что дифференциальный сигнал просто сравнивает два напряжения без привязки к общей земле. Но самым большим виновником является тот факт, что RS-422/485, подключенный без надлежащего заземления, кажется, работает.

Комментарии:

1. Эй, спасибо за эти объяснения, я думаю, что это единственное, что может объяснить мои случайные ошибки. Дело в том, что я думаю, что кабель, который у меня есть, не скручивает кабель A и B, который производит слишком много шума… проводка GND кажется дополнительной защитой от шума. Но я видел так много установок без какого-либо GND на проводке rs485. Я думаю, что скручивание делает его очень устойчивым. Я просто собираюсь сделать вывод, что моя телеграмма просто очень неправильная. Я буду просматривать эти документы на случай, если это произойдет с новыми проводами! Спасибо, что уделили мне время

2. Пожалуйста. Я думаю, что это действительно зависит от вашей среды и источника питания. Если вы находитесь в чистой среде, худший кабель может быть в порядке. Витая пара и GND должны помочь. Удачи.

Ответ №2:

Похоже, ваша проблема может заключаться в порядке байтов, используемом эмулируемым подчиненным устройством.