yaacov / node-modbus-serial

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

Sending data is wrong #443

Open mStirner opened 2 years ago

mStirner commented 2 years ago

Im trying to query my smart meter, with a USB/RS485 adapter. (Datasheet with modbus documentation)

The data that is sended via this package looks wrong compared to the manufacturer software: 153709176-e3e34143-86ce-4230-8c22-52f4045b5828

As you can see in the image, the output data should be: [01][04][00][00][00][02][71][CB], but modbus-serial writes: 01 04 00 00 00 01 31 ca, i wonder whats wrong. Is it my code or a problem internal?

Code i put together to query the first input register:

process.env.DEBUG = "modbus-serial";

var ModbusRTU = require("modbus-serial");
var client = new ModbusRTU();

// open connection to a serial port
client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600 }, async () => {

    console.log("Ready to do some nasty shit");

    client.setID(1);

    // read the 1 registers starting at address 0 (first register)
    let val = await client.readInputRegisters(0, 1);

    console.log(val.data);

});

The returned value, looks also not even close to what i expected:

Ready to do some nasty shit
  modbus-serial {
  modbus-serial   action: 'send serial rtu buffered',
  modbus-serial   data: <Buffer 01 04 00 00 00 01 31 ca>,
  modbus-serial   unitid: 1,
  modbus-serial   functionCode: 4,
  modbus-serial   length: 7
  modbus-serial } +0ms
  modbus-serial {
  modbus-serial   action: 'receive serial rtu buffered port',
  modbus-serial   data: <Buffer 01 04 02 43 6d 49 ed>,
  modbus-serial   buffer: <Buffer 01 04 02 43 6d 49 ed>
  modbus-serial } +34ms
  modbus-serial {
  modbus-serial   action: 'emit data serial rtu buffered port',
  modbus-serial   buffer: <Buffer 01 04 02 43 6d 49 ed>
  modbus-serial } +1ms
[ 17261 ]

Im thankful for every hint/help. Thanks in advance.

Xsandor commented 2 years ago

The reason is that the manufacturer's software reads 2 registers and in with your modbus-serial request you are only reading 1.

You need to modify your request to read 2 registers, then you will receive 2 pieces of 16-bit registers from the device. Combine these and read them as a 32-bit float (hint: DataView - getFloat32)

mStirner commented 2 years ago

@Xsandor Thank you very much, i completely overseen this.

Working example for L1 voltage:

client.connectRTUBuffered("/dev/ttyUSB0", { baudRate: 9600 }, async () => {

    console.log("Ready to do some nasty shit");

    client.setID(1);

    // read the 1 registers starting at address 0 (first register)
    let val = await client.readInputRegisters(0, 2);

    console.log(val.buffer.readFloatBE(0));

});

What confused me even more, was the value array with strange values, but now reading 2 registers and working with the returned buffer, its working.

Thank you very much for pointing this out.

Xsandor commented 2 years ago

Fantastic. Good luck with your project! :)