Проблемы с pymodbus

Я новичок в pymodbus, и я пытаюсь прочитать регистры хранения совместного робота с pymodbus, чтобы получить значение текущей координаты z. Такая информация есть по адресу 7053. Я посмотрел на старые вопросы, но не смог заставить работать свой код:

from pymodbus.client.sync import ModbusTcpClient

host = '192.168.250.201' # Robot IP address
port = 502 # port

client = ModbusTcpClient(host, port)
client.connect()
request = client.read_holding_registers(
    address=0x03, # The starting address to read from 
    count=4, # The number of registers to read
    unit=1) # The slave unit this request is targeting
response = client.execute(request)
print(response.bits[0]) 
client.close()

Я все время получаю это сообщение об ошибке:

ConnectionException: Ошибка Modbus: [Соединение] Не удалось подключиться [ModbusTcpClient (192.168.250.201:502)]

Я предполагаю, что в моем коде что-то не так, или, может быть, что-то еще мешает мне установить соединение. Какие-либо предложения? Спасибо


person Federico    schedule 13.11.2019    source источник
comment
Действительно ли IP-адрес, указанный в коде, находится в вашей сети? Можете ли вы ping получить возврат? У этой машины (я полагаю, у робота) действительно открыт порт 502?   -  person KDecker    schedule 13.11.2019
comment
Я только что узнал, что путаю ip-адрес робота со своим собственным в сети. Я изменил свой код, указав правильный IP-адрес, и теперь соединение работает, но я не понимаю, что я получаю в ответ на свой запрос: ReadRegisterResponse (0)   -  person Federico    schedule 13.11.2019


Ответы (2)


У вас есть пара мелких проблем:

1) Адрес регистра, который вы запрашиваете, кажется неправильным, дважды проверьте руководство своего устройства, чтобы убедиться, что вы читаете правильный адрес, скорее всего, вам нужно будет запросить address=7053.

2) Вы читаете регистры временного хранения, но затем пытаетесь распечатать значение в катушках (битах). Проверьте, действительно ли они хранят регистры, и используйте print(response.registers[0])

person Marcos G.    schedule 14.11.2019

Я исправил свой код, как было предложено выше, и я также добавил 2 строки, чтобы попытаться декодировать то, что я получил (координата Z моего робота):

from pymodbus.client.sync import ModbusTcpClient
from pymodbus.constants import Endian
from pymodbus.payload import BinaryPayloadDecoder

host = '192.168.250.2' # Robot IP address
port = 502 # Modbus port on the robot

client = ModbusTcpClient(host, port)
client.connect()
request = client.read_holding_registers(
    address=7053, # The starting address to read from 
    count=4, # The number of registers to read
    unit=1) # The slave unit this request is targeting (slave ID)
#response = client.execute(request)
print(request.registers)
decoder = BinaryPayloadDecoder.fromRegisters(request.registers, Endian.Big, Endian.Little)
print(decoder.decode_32bit_float())
client.close()

Выход:

[0, 0, 0, 0]
0.0

Что означает этот вывод? Я знаю, что координата Z робота составляет 400 мм, но похоже, что я получаю 0 независимо от того, какой адрес я использую в запросе. Это результат отладки:

DEBUG:pymodbus.transaction:Current transaction state - IDLE
DEBUG:pymodbus.transaction:Running transaction 1
DEBUG:pymodbus.transaction:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x1 0x3 0x1b 0x8d 0x0 0x4
DEBUG:pymodbus.client.sync:New Transaction state 'SENDING'
DEBUG:pymodbus.transaction:Changing transaction state from 'SENDING' to 'WAITING FOR REPLY'
DEBUG:pymodbus.transaction:Changing transaction state from 'WAITING FOR REPLY' to 'PROCESSING REPLY'
DEBUG:pymodbus.transaction:RECV: 0x0 0x1 0x0 0x0 0x0 0xb 0x1 0x3 0x8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
DEBUG:pymodbus.framer.socket_framer:Processing: 0x0 0x1 0x0 0x0 0x0 0xb 0x1 0x3 0x8 0x0 0x0 0x0 0x0 0x0 0x0 0x0 0x0
DEBUG:pymodbus.factory:Factory Response[ReadHoldingRegistersResponse: 3]
DEBUG:pymodbus.transaction:Adding transaction 1
DEBUG:pymodbus.transaction:Getting transaction 1
DEBUG:pymodbus.transaction:Changing transaction state from 'PROCESSING REPLY' to 'TRANSACTION_COMPLETE'
DEBUG:pymodbus.payload:[0, 0, 0, 0]
DEBUG:pymodbus.payload:[b'\x00\x00', b'\x00\x00']

Я получаю материал в SEND, но не совсем тот, который находится в RECV, это не то, что я ожидал.

person Federico    schedule 14.11.2019
comment
Единственное, что я могу сказать наверняка, - это то, что регистры, которые вы читаете, возвращаются с нулями. У вас есть ссылка на мануал вашего робота? Мне нужно больше подробностей, чтобы помочь вам ... - person Marcos G.; 16.11.2019
comment
Я выяснил, в чем была проблема: я думал, что мне нужно читать из регистров временного хранения (код функции 03), но я ошибался, информация, которую я хотел, находится во входных регистрах (код функции 04). Изменением: request = client.read_holding_registers(...) на request = client.read_input_registers(...) проблема решена. count должно быть 2, потому что информация, которую я хочу, находится в регистрах 7053-7054. byteorder и wordorder в декодере должны быть оба Endian.Big. Я отправлю исправленный код, когда буду на работе. Спасибо за помощь! - person Federico; 18.11.2019