yaacov / node-modbus-serial

A pure JavaScript implemetation of MODBUS-RTU (and TCP) for NodeJS
ISC License
627 stars 239 forks source link

Error reading Modbus TCP/IP on a network #428

Open MiguelSeixas opened 2 years ago

MiguelSeixas commented 2 years ago

Hi,

When I try to read a value of a modbus TCP/IP device directly connected to it with a ethernet cable with the following code i receive the values correctly:

// create an empty modbus client
var ModbusRTU = require("modbus-serial");
var client = new ModbusRTU();

// open connection to a tcp line
client.connectTCP("172.29.20.136", { port: 502 });
client.setID(1);

// read the values of the register 41658 on device number 1. and log the values to the console.
setInterval(function() {
    client.readHoldingRegisters(41658, 1, function(err, data) {
        console.log(data.data);
    });
}, 100000);

But when I try to read the same device on the network, with multiple hops on different routers i receive the following error:

(node:1556) UnhandledPromiseRejectionWarning: Unhandled promise rejection (rejection id: 1): Error: connect ETIMEDOUT 17 2.29.20.136:502 console.log(data.data); TypeError: Cannot read property 'data' of undefined

Does it mean that the program is terminated before a value is given to the data variable, or is the program unable to read data in diferent routers? I tested the connection with TRACERT and i found that the packages take about 45 ms from my router to the destination router.

yaacov commented 2 years ago

Hi, thank you for the question, can you try this example in your setup ? https://github.com/yaacov/node-modbus-serial/blob/master/examples/buffertcp.js

MiguelSeixas commented 2 years ago

Hi,

I tried that version as well and I increased the client.setTimeout(); to 100.000 ms, but I wasn't sucessfull. The output was:

connect ETIMEDOUT

Strange that the program terminates in about 20s, although I placed a timeout for 100s...

dyllan-to-you commented 2 years ago

I like to use the modpoll utility for testing/debugging network-related issues.

Can you confirm that, when using modpoll on your local machine, you can poll the modbus device on your network? If you can't then it's likely a problem with the network. If you can then that points to an error with implementation

amidiot commented 2 years ago

I'm also having the same problem.

Hi, thank you for the question, can you try this example in your setup ? https://github.com/yaacov/node-modbus-serial/blob/master/examples/buffertcp.js

I've tried with the example code and I also got the error:

TransactionTimedOutError {
  name: 'TransactionTimedOutError',
  message: 'Timed out',
  errno: 'ETIMEDOUT'
}

i'm using node v16.13.0, modbus-serial v8.0.5

below is the client object before reading registers

{ _port: { openFlag: true, callback: null, _transactionIdWrite: 1, _externalSocket: null, connectOptions: { host: "192.168.1.223", port: 502, family: 0 }, _buffer: { type: "Buffer", data: [ ] }, _client: { connecting: false, _hadError: false, _parent: null, _host: null, _readableState: { objectMode: false, highWaterMark: 16384, buffer: { head: null, tail: null, length: 0 }, length: 0, pipes: [ ], flowing: true, ended: false, endEmitted: false, reading: true, constructed: true, sync: false, needReadable: true, emittedReadable: false, readableListening: false, resumeScheduled: false, errorEmitted: false, emitClose: false, autoDestroy: true, destroyed: false, errored: null, closed: false, closeEmitted: false, defaultEncoding: "utf8", awaitDrainWriters: null, multiAwaitDrain: false, readingMore: false, dataEmitted: false, decoder: null, encoding: null }, _events: { }, _eventsCount: 6, _writableState: { objectMode: false, highWaterMark: 16384, finalCalled: false, needDrain: false, ending: false, ended: false, finished: false, destroyed: false, decodeStrings: false, defaultEncoding: "utf8", length: 0, writing: false, corked: 0, sync: true, bufferProcessing: false, writecb: null, writelen: 0, afterWriteTickInfo: null, buffered: [ ], bufferedIndex: 0, allBuffers: true, allNoop: true, pendingcb: 0, constructed: true, prefinished: false, errorEmitted: false, emitClose: false, autoDestroy: true, errored: null, closed: false, closeEmitted: false }, allowHalfOpen: false, _sockname: null, _pendingData: null, _pendingEncoding: "", server: null, _server: null }, isOpen: true, _events: { }, _eventsCount: 3, _transactionIdRead: 1 }, _transactions: { }, _timeout: 1000, _unitID: 1, _debugEnabled: false, _events: { }, _eventsCount: 0 }

martinroehder commented 1 year ago

Hi, I'm debugging right now why my values read from a SMA Inverter via Modbus are sometimes cut off. Sometimes the last byte is simply cut off and replaced by 0. Debugging it, I did a packet capture with wireshark and saw that the TCP PDU is split over two packets. Exactly the last byte of my data was in the second packet. I have the suspicion that somehow the TCP PDUs are not reassambled correct. Maybe this helps to find the bug.