Closed paulmccarthy closed 4 years ago
Can you post the code where you call the readInputRegisters method.
Thanks for replying. My code is below:
const modbus = require('jsmodbus');
const SerialPort = require('serialport');
const socket = new SerialPort('/dev/ttyUSB4', {
baudRate: 19200
});
const client = new modbus.client.RTU(socket, 1);
socket.on('open', function () {
console.log('socket open');
client.readInputRegisters(19456, 32)
.then((resp) => {
console.log(resp.response.body.valuesAsArray);
socket.end();
process.exit();
}).catch(function () {
console.error('readInputRegisters error', arguments);
socket.end();
process.exit(1);
});
});
socket.on('socket error', function() {
console.error('socket error', arguments);
process.exit(1);
});
Thanks for the code.
Changing the writeUint8 into a writeUint16 does not do any good and doesn't make sense. It seems like the payload buffer is not initiated with the right size. Can you add a log message for the byteCount like below and try again?
createPayload () {
console.log('BYTE_COUNT:', this.byteCount)
const payload = Buffer.alloc(this.byteCount)
payload.writeUInt8(this._fc, 0)
payload.writeUInt8(this.length, 1)
this._values.forEach(function (value, i) {
payload.writeUInt8(value, 2 + i)
})
return payload
}
Any progress?
I had a similar issue with reading a 16 bit ModbusRTU register, but with read-holding-registers. The values when createPayload ran were:
this._values = [2019, 4] this._valuesAsBuffer = [7, 227, 0, 4] this.byteCount = 6
Since 2019 > 255, it gives an error. It works when I change this._values to this._valuesAsBuffer in the createPayload function.
createPayload () {
if (this._values instanceof Buffer) {
let payload = Buffer.alloc(2)
payload.writeUInt8(this._fc, 0)
payload.writeUInt8(this._byteCount, 1)
payload = Buffer.concat([payload, this._values])
return payload
}
if (this._values instanceof Array) {
const payload = Buffer.alloc(this.byteCount)
payload.writeUInt8(this._fc, 0)
payload.writeUInt8(this._byteCount, 1)
this._valuesAsBuffer.forEach(function (value, i) {
payload.writeUInt8(value, 2 + i)
})
return payload
}
}
So the createPayload function in read-input-registers would be
createPayload () {
const payload = Buffer.alloc(this.byteCount)
payload.writeUInt8(this._fc, 0)
payload.writeUInt8(this.length, 1)
this._valuesAsBuffer.forEach(function (value, i) {
payload.writeUInt8(value, 2 + i)
})
return payload
}
I also ran into this in read-holding-registers when the register value exceeded max UInt8. The suggestion provided by @dpham314 indeed resolved the problem.
@dvankuren Should be resolved in the lates version. Can you check that? Version 3.1.4
I'm trying to read data from a NDMeter Rail 350 power meter via Modbus RTU. I'm using a Raspberry Pi Compute Model based system, with the following:
Node JS Version: 8.15.0 NPM Version: 6.4.1 OS Version (uname -a): Linux 13001 4.4.45-v7+ #19 SMP Fri Feb 10 12:54:17 CET 2017 armv7l GNU/Linux OS Version (/etc/os-release): PRETTY_NAME="Raspbian GNU/Linux 8 (jessie)" NAME="Raspbian GNU/Linux" VERSION_ID="8" VERSION="8 (jessie)" ID=raspbian ID_LIKE=debian HOME_URL="http://www.raspbian.org/" SUPPORT_URL="http://www.raspbian.org/RaspbianForums" BUG_REPORT_URL="http://www.raspbian.org/RaspbianBugs"
The command is sent via over modbus, and data is returned, but I get the following error:
The issue is caused by the following code starting on line 84 in
src/response/read-input-registers.js
:This power meter returns 16 bit values, so the
payload.writeUint8
function throws the error when it encounters a value > 255.I've tried changing the code to:
which does return the expected values, but the then I get another error:
This error is thrown on line 53 of
src/rtu-client-request-handler.js
.DEBUG output with unchanged code:
DEBUG output with
writeUint8
changed towriteUint16BE
: