Closed FrancoTampieri closed 1 year ago
Hi,
In the MBAP header, bytes 2-3 are "protocol identifier" and it must be equal to 0 for modbus/TCP. In your debug trace, server return 6C-63 at this place.
Also, if your convert your RAW MBAP data to string it give you 'Welcome' string:
# return 'Welcome'
print(b'\x57\x65\x6c\x63\x6f\x6d\x65'.decode())
Are you sure you connect to a modbus TCP server socket ?
more at: https://en.wikipedia.org/wiki/Modbus#Modbus_TCP_frame_format
Hi, the producer of the machine told me this... of course I think is a custom modbus server and not developed to be full protocol compliant. I tried with nodes and the modus-serial libs that support both rtu and tcp server and I get the integer value of the register that is 3. Thank you to giving me the frame format. Is possible to create a custom frame format to handle this case? The only things that I know is the that the server is a .net server on windows 7 I can use Wireshark for that, today or tomorrow I will try to get all the communications frame.
I get using pymodbus as debugger this:
DEBUG:pymodbus.logging:Connection to Modbus server established. Socket ('192.168.1.125', 46270)
DEBUG:pymodbus.logging:Current transaction state - IDLE
DEBUG:pymodbus.logging:Running transaction 1
DEBUG:pymodbus.logging:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x4 0x0 0x1 0x0 0x1
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Incomplete message received, Expected 28531 bytes Received 19 bytes !!!!
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20 0x74 0x6f 0x20 0x54 0x63 0x70 0x53 0x72 0x76 0xd 0xa
DEBUG:pymodbus.logging:Processing: 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20 0x74 0x6f 0x20 0x54 0x63 0x70 0x53 0x72 0x76 0xd 0xa
DEBUG:pymodbus.logging:Frame check failed, ignoring!!
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer - 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20 0x74 0x6f 0x20 0x54 0x63 0x70 0x53 0x72 0x76 0xd 0xa
DEBUG:pymodbus.logging:Getting transaction 1
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Modbus Error: [Input/Output] No Response received from the remote slave/Unable to decode response
And the complete response look like say:
print(b'\x57\x65\x6c\x63\x6f\x6d\x65\x20\x74\x6f\x20\x54\x63\x70\x53\x72\x76'.decode())
Welcome to TcpSrv
the last two "0xd 0xa" give me an error on decoding
There is no way to deal with badly formatted MBAP header in pyModbusTCP. You can only create a custom PDU frame (part after MBAP header) with custom_request method, but that's useless here.
Perhaps you can try to change pyModbusTCP code for create a custom version to deal with this specific server but it can be very time-consuming. Another way could be to write a python TCP proxy for remove/reformat data in front of client.
Yeah I solved developing a program with nodes 18 and the modus-serial libs.
But I will share the tests that I made, because can be useful for someone that face of the same problem with some custom modbus server that was developed without follow the standards :/
Python is the standard of Debian 11 and is versione 3.9.2
I activated the debug for both libs:
from pyModbusTCP.client import ModbusClient
c = ModbusClient(host="192.168.1.134", port=1024, unit_id=10, debug=True)
c.open()
if c.is_open == False:
print('not connected')
else:
print('connected')
print(c.unit_id)
c.read_input_registers(1,1)
c.close()
from pymodbus.client import ModbusTcpClient
from pymodbus.transaction import ModbusSocketFramer as ModbusFramer
import logging
logging.basicConfig()
log = logging.getLogger()
log.setLevel(logging.DEBUG)
ip = "192.168.1.134"
port_num = 1024
unit_num = 10
client = ModbusTcpClient(ip, port=port_num, framer=ModbusFramer)
client.connect()
rr = client.read_input_registers(1,1, unit=unit_num)
print(rr)
The output of the two libs are that:
connected
10
Tx
[DD 02 00 00 00 06 0A] 04 00 01 00 01
Rx
[57 65 6C 63 6F 6D 65]
MBAP checking error
DEBUG:pymodbus.logging:Connection to Modbus server established. Socket ('192.168.1.125', 46270)
DEBUG:pymodbus.logging:Current transaction state - IDLE
DEBUG:pymodbus.logging:Running transaction 1
DEBUG:pymodbus.logging:SEND: 0x0 0x1 0x0 0x0 0x0 0x6 0x0 0x4 0x0 0x1 0x0 0x1
DEBUG:pymodbus.logging:New Transaction state "SENDING"
DEBUG:pymodbus.logging:Changing transaction state from "SENDING" to "WAITING FOR REPLY"
DEBUG:pymodbus.logging:Incomplete message received, Expected 28531 bytes Received 19 bytes !!!!
DEBUG:pymodbus.logging:Changing transaction state from "WAITING FOR REPLY" to "PROCESSING REPLY"
DEBUG:pymodbus.logging:RECV: 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20 0x74 0x6f 0x20 0x54 0x63 0x70 0x53 0x72 0x76 0xd 0xa
DEBUG:pymodbus.logging:Processing: 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20 0x74 0x6f 0x20 0x54 0x63 0x70 0x53 0x72 0x76 0xd 0xa
DEBUG:pymodbus.logging:Frame check failed, ignoring!!
DEBUG:pymodbus.logging:Resetting frame - Current Frame in buffer - 0x57 0x65 0x6c 0x63 0x6f 0x6d 0x65 0x20 0x74 0x6f 0x20 0x54 0x63 0x70 0x53 0x72 0x76 0xd 0xa
DEBUG:pymodbus.logging:Getting transaction 1
DEBUG:pymodbus.logging:Changing transaction state from "PROCESSING REPLY" to "TRANSACTION_COMPLETE"
Modbus Error: [Input/Output] No Response received from the remote slave/Unable to decode response
Does someone have face off the same error with some software modbus server from some machine producers? All suggestions are welcome :)
Edit:
Hi! I try a session with mbpoll as u suggest and this is what I got:
mbpoll 192.168.1.134 -a 10 -p 1024 -t 3 -r 1
mbpoll 1.5-2 - ModBus(R) Master Simulator
Copyright (c) 2015-2023 Pascal JEAN, https://github.com/epsilonrt/mbpoll
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'mbpoll -w' for details.
Protocol configuration: ModBus TCP
Slave configuration...: address = [10]
start reference = 1, count = 1
Communication.........: 192.168.1.134, port 1024, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
-- Polling slave 10... Ctrl-C to stop)
Read input register failed: Invalid data
^C--- 192.168.1.134 poll statistics ---
12 frames transmitted, 0 received, 12 errors, 100.0% frame loss
everything was closed.
Have a nice day !
with modpoll (with tcp and try rtu encapsulated in tcp):
./modpoll -m enc -a 10 -p 1024 -t 3 -r 1 192.168.1.134
modpoll 3.10 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2021 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
Protocol configuration: Encapsulated RTU over TCP, FC4
Slave configuration...: address = 10, start reference = 1, count = 1
Communication.........: 192.168.1.134, port 1024, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table
-- Polling slave... (Ctrl-C to stop)
Checksum error!
-- Polling slave... (Ctrl-C to stop)
Reply time-out!
-- Polling slave... (Ctrl-C to stop)
Checksum error!
^C
./modpoll -m tcp -a 10 -p 1024 -t 3 -r 1 192.168.1.134
modpoll 3.10 - FieldTalk(tm) Modbus(R) Master Simulator
Copyright (c) 2002-2021 proconX Pty Ltd
Visit https://www.modbusdriver.com for Modbus libraries and tools.
Protocol configuration: MODBUS/TCP, FC4
Slave configuration...: address = 10, start reference = 1, count = 1
Communication.........: 192.168.1.134, port 1024, t/o 1.00 s, poll rate 1000 ms
Data type.............: 16-bit register, input register table
-- Polling slave... (Ctrl-C to stop)
Invalid MPAB identifier!
-- Polling slave... (Ctrl-C to stop)
Reply time-out!
-- Polling slave... (Ctrl-C to stop)
Invalid MPAB identifier!
-- Polling slave... (Ctrl-C to stop)
Reply time-out!
^C
This is the simple code of the nodes program that I try and works:
// create an empty modbus client
const ModbusRTU = require("modbus-serial");
const client = new ModbusRTU();
// open connection to a tcp line
client.connectTCP("192.168.1.134", { port: 1024 });
client.setID(10);
// read the values of 10 registers starting at address 0
// on device number 1. and log the values to the console.
setInterval(function() {
client.readInputRegisters(0, 10, function(err, data) {
console.log(data.data);
});
}, 1000);
and this is the result:
node modbus.js
[
3, 53, 2, 0, 0,
0, 0, 0, 0, 0
]
[
3, 53, 2, 0, 0,
0, 0, 0, 0, 0
]
[
3, 53, 2, 0, 0,
0, 0, 0, 0, 0
]
[
3, 53, 2, 0, 0,
0, 0, 0, 0, 0
]
[
3, 53, 2, 0, 0,
0, 0, 0, 0, 0
]
[
3, 53, 2, 0, 0,
0, 0, 0, 0, 0
]
^C
Probably the nodes lib don't make some checks on the server and get the data rightly but probably is out of modbus standard standard.
Hi I have this sample code:
pyModbusTCP == 0.2.0 python 3.9.2
when I try to connect and read the input register 1 (300001) I get this error:
I used a GUI modbus client and I read the register correctly is 3, why I got this error? Someone can help me? Because of course if I try to print the register I get a None response that is not true.