Есть газоанализатор СТГ 3 с rs485 я пытаюсь считать с него текущие измеренное значение концентрации , а так же установленные пороги 1 и 2 .
Пример запроса данных:
01; 03; 00; 00; 00; 02; sum 0; sum 1,
где N номер сигнализатора в сети. Устанавливается пользователем в
диапазоне от 1 до 31;
sum 0; sum 1 контрольная сумма (CRC), рассчитывается в соответствии
с протоколом «MODBUS-RTU».
Вот мой код
from pymodbus.client.sync import ModbusSerialClient as ModbusClient import time # Параметры подключения port = 'COM6' baudrate = 9600 client = ModbusClient( method='rtu', port=port, baudrate=baudrate, stopbits=1, parity='N', timeout=1 ) def read_modbus_data(client, unit_id, address, count): # Подключение к клиенту if not client.connect(): print("Не удалось подключиться к Modbus серверу") return None # Чтение данных result = client.read_holding_registers(address, count, unit=unit_id) if result.isError(): print("Ошибка чтения данных: ", result) return None # Закрытие соединения client.close() return result def interpret_data(registers): if len(registers) < 2: print("Недостаточно данных для интерпретации") return # Извлечение данных из регистров reg0 = registers[0] reg1 = registers[1] # Разбиение регистров на байты byte1 = (reg0 >> 8) & 0xFF byte2 = reg0 & 0xFF byte3 = (reg1 >> 8) & 0xFF byte4 = reg1 & 0xFF # Извлечение состояния сигнализации и знака sign_bit = (byte1 >> 7) & 0x01 comma_position = (byte1 & 0x07) # Определение знака sign = '-' if sign_bit else '+' # Чтение значений integer_part = byte2 * 10000 + byte3 * 10 + (byte4 >> 4) decimal_part = (byte4 & 0x0F) * 100 # Формирование значения value = integer_part + decimal_part / 10000 if sign_bit: value = -value # Сдвиг запятой value /= 10 ** comma_position # Форматирование результата с округлением до 2 знаков после запятой value = round(value, 2) print(f"Значение: {value:.2f}") return value def main(): # Параметры запроса unit_id = 1 address = 0x00 # Начальный адрес для измеренного значения count = 2 # Количество регистров для измеренного значения threshold1_address = 0x02 # Адрес порога 1 threshold2_address = 0x04 # Адрес порога 2 while True: # Чтение данных измеренного значения data = read_modbus_data(client, unit_id, address, count) if data: print("Текущее значение концентрации:") interpret_data(data.registers) # Чтение порога 1 p1_data = read_modbus_data(client, unit_id, threshold1_address, count) if p1_data: print("Установленное значение порога 1:") interpret_data(p1_data.registers) # Чтение порога 2 p2_data = read_modbus_data(client, unit_id, threshold2_address, count) if p2_data: print("Установленное значение порога 2:") interpret_data(p2_data.registers) # Задержка 1 секунда time.sleep(1) if __name__ == "__main__": main()
А получаю какую то ерунду с порогами, сейчас у меня установлен первый порог 20 , а второй 40 , а код выдает первый 32 , а второй 64. Так же текущее значение тоже не совсем точное , есть какая то погрешность. Если в официальной программе такие значения
А мой код выдает
Текущее значение концентрации: -0.34
Установленное значение порога 1: 32.00
Установленное значение порога 2: 64.00
Текущее значение концентрации: -0.33
Установленное значение порога 1: 32.00
Установленное значение порога 2: 64.00
Что я делаю не так? Спасибо.