morkai / h5.modbus

Implementation of the MODBUS IP/ASCII/RTU master and slave over TCP/UDP/Serial for Node.js.
https://miracle.systems/p/h5.modbus
MIT License
28 stars 21 forks source link

Writing negative value to PLC register #9

Closed rtcimi closed 8 years ago

rtcimi commented 8 years ago

Hello. First of all, awesome library! Everything works really good! I have situation where i need to write negative value in to PLC register, but library throw me an error when i try to write any kind of negative value ...

throw new Error(util.format( ^ Error: Register value must be a number between 0 and 65535.

If i'm right, 0 to 65535, this is uint16 type. But i need to write int16 (-32,768 to 32,768)

Any suggestion how to solve this kind of situation?

morkai commented 8 years ago

Judging from the error message, you're using the old version and it expects the register value to be uint16: https://github.com/morkai/h5.modbus/blob/v0/lib/functions/util.js#L95

You can use the Buffer.writeInt16BE() and Buffer.readUInt16BE() to convert it to uint or, if the value is less than 0, add 0x10000 to it (that's what is done automatically in the new version).

rtcimi commented 8 years ago

It works, thank you very much.

rtcimi commented 8 years ago

One more question ... Can you tell me what is number of registers which can be read with one readHoldingRegisters request?

Best regards, Tomaž

2016-05-18 16:23 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

Judging from the error message, you're using the old version and it expects the register value to be uint16: https://github.com/morkai/h5.modbus/blob/v0/lib/functions/util.js#L95

You can use the Buffer.writeInt16BE() and Buffer.readUInt16BE() to convert it to uint or, if the value is less than 0, add 0x10000 to it (that's what is done automatically in the new version https://github.com/morkai/h5.modbus/blob/8eb063d6f00a07ba9b20076f037ed4cf1eea1d66/lib/helpers.js#L161 ).

— You are receiving this because you authored the thread. Reply to this email directly or view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-220041859

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

morkai commented 8 years ago

125 (as per spec), but various devices might have different, lower limits.

rtcimi commented 8 years ago

Thank you. Have a nice day.

2016-05-19 11:12 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

125 (as per spec http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf), but various devices might have different, lower limits.

— You are receiving this because you modified the open/close state. Reply to this email directly or view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-220269729

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

rtcimi commented 8 years ago

Sorry for bothering you again but i must ask... is there any existing example of serial rtu master or at least full rtu connection part for your lib?

Sunny regards from Slovenia.

2016-05-19 11:31 GMT+02:00 Tomaž Rems rems.tomaz@gmail.com:

Thank you. Have a nice day.

2016-05-19 11:12 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

125 (as per spec http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf), but various devices might have different, lower limits.

— You are receiving this because you modified the open/close state. Reply to this email directly or view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-220269729

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

rtcimi commented 8 years ago

... i forgot to tell you... for last version

2016-06-05 16:25 GMT+02:00 Tomaž Rems rems.tomaz@gmail.com:

Sorry for bothering you again but i must ask... is there any existing example of serial rtu master or at least full rtu connection part for your lib?

Sunny regards from Slovenia.

2016-05-19 11:31 GMT+02:00 Tomaž Rems rems.tomaz@gmail.com:

Thank you. Have a nice day.

2016-05-19 11:12 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

125 (as per spec http://www.modbus.org/docs/Modbus_Application_Protocol_V1_1b.pdf), but various devices might have different, lower limits.

— You are receiving this because you modified the open/close state. Reply to this email directly or view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-220269729

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

morkai commented 8 years ago
var master = modbus.createMaster({
  transport: {
    type: 'rtu',
    // End of frame timeout.
    eofTimeout: 50
  },
  connection: {
    type: 'serial',
    // Whether to automatically open the serial port in the constructor.
    // If false, one must manually call the `open()` method.
    autoOpen: true,
    // Whether to call the `close()` method on the underlying SerialPort
    // when the connection is destroyed.
    closeOnDestroy: true,
    // Whether to attach an empty listener for the `error` events after
    // the connection is destroyed, so the possible stray error events
    // don't crash the process.
    suppressErrorsAfterDestroy: true,
    // Optional instance of SerialPort from the serialport npm package.
    serialPort: serialPort,
    // Optional options passed to a dynamically created instance of SerialPort
    // from the serialport npm package.
    serialPortOptions: {
      baudRate: 9600,
      dataBits: 8,
      stopBits: 1,
      parity: 'even'
    }
  }
});

For all serialPortOptions see the serialport package docs.

rtcimi commented 8 years ago

Thank you very much it is working.

2016-06-05 16:49 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

var master = modbus.createMaster({ transport: { type: 'rtu', // End of frame timeout. eofTimeout: 50 }, connection: { type: 'serial', // Whether to automatically open the serial port in the constructor. // If false, one must manually call the open() method. autoOpen: true, // Whether to call the close() method on the underlying SerialPort // when the connection is destroyed. closeOnDestroy: true, // Whether to attach an empty listener for the error events after // the connection is destroyed, so the possible stray error events // don't crash the process. suppressErrorsAfterDestroy: true, // Optional instance of SerialPort from the serialport npm package. serialPort: serialPort, // Optional options passed to a dynamically created instance of SerialPort // from the serialport npm package. serialPortOptions: { baudRate: 9600, dataBits: 8, stopBits: 1, parity: 'even' } } });

For all serialPortOptions see the serialport package docs https://github.com/EmergingTechnologyAdvisors/node-serialport/blob/3.1.2/README.md#serialport-path-options-openimmediately-callback .

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-223817206, or mute the thread https://github.com/notifications/unsubscribe/AQLJ1bx6I2h9HJk1IG9SINHYSEdIHJjvks5qIuHngaJpZM4IhUoW .

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

rtcimi commented 8 years ago

AAaaa, not completely ...

Master is conneced and sending request ...but no matter what i do, there always is negative response "No response was received from the slave in the specified time."

For start i would like to read for example reg on address 606 with function readholdingregisters which is number 5 if i understand right and with quantity 1 ...

My current confguration based on your example:

var serialPort = new SerialPort('/dev/ttyUSB0', {}); var master = modbus.createMaster({ transport: { type: 'rtu', eofTimeout: 10, }, connection: { type: 'serial', autoOpen: true, closeOnDestroy: true, serialPort: serialPort, serialPortOptions: {baudRate: 9600, dataBits: 8, parity: 'none', stopBits: 1, flowControl: ['RTSCTS']} }, maxConcurrentTransactions: 1, defaultTimeout: 1200, defaultUnit: 2, defaultMaxRetries: 0, }); ...................................calling startTransaction for n times............................................... function startTransaction(id, reg, functionCode, quantity, interval){ var t = master.execute({ id: id, // i number from looping request: { functionCode: functionCode, // 5 address: reg, // 606 quantity: quantity, // 1 }, interval: interval // 0 });

t.on('error', onError); t.on('request', onRequest); t.on('response', onResponse); }

_My configuration with previous library (which worked ok) was:_var serialPort = new SerialPort('/dev/ttyUSB0', { baudRate: 9600, dataBits: 8, parity: 'none', stopBits: 1, flowControl: ['RTSCTS'], }); var modbus_options = { transport: { type: 'rtu', eofTimeout: 50, connection: { type: 'serial', serialPort: serialPort} }, suppressTransactionErrors: true, retryOnException: true, maxConcurrentRequests: 1, defaultUnit: 2, defaultMaxRetries: 1, defaultTimeout: 1100 } var master = modbus.createMaster(modbus_options); ...............................calling loopBus for n times................................ function loopBus(){ var loopModbus = master.readHoldingRegisters(reg, n, {maxRetries: 2,timeout: loopDelay}); loopModbus.on('response', function(response){..} }

Any suggestions? Can you tell me in short if there was any major changes on RTU side of the library?

2016-06-06 1:08 GMT+02:00 Tomaž Rems rems.tomaz@gmail.com:

Thank you very much it is working.

2016-06-05 16:49 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

var master = modbus.createMaster({ transport: { type: 'rtu', // End of frame timeout. eofTimeout: 50 }, connection: { type: 'serial', // Whether to automatically open the serial port in the constructor. // If false, one must manually call the open() method. autoOpen: true, // Whether to call the close() method on the underlying SerialPort // when the connection is destroyed. closeOnDestroy: true, // Whether to attach an empty listener for the error events after // the connection is destroyed, so the possible stray error events // don't crash the process. suppressErrorsAfterDestroy: true, // Optional instance of SerialPort from the serialport npm package. serialPort: serialPort, // Optional options passed to a dynamically created instance of SerialPort // from the serialport npm package. serialPortOptions: { baudRate: 9600, dataBits: 8, stopBits: 1, parity: 'even' } } });

For all serialPortOptions see the serialport package docs https://github.com/EmergingTechnologyAdvisors/node-serialport/blob/3.1.2/README.md#serialport-path-options-openimmediately-callback .

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-223817206, or mute the thread https://github.com/notifications/unsubscribe/AQLJ1bx6I2h9HJk1IG9SINHYSEdIHJjvks5qIuHngaJpZM4IhUoW .

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

morkai commented 8 years ago

If you're going to specify connection.serialPort option then the connection.serialPortOptions is ignored (you should use serialPort OR serialPortOptions - if you're using serialPort then stick the serialPortOptions into new SerialPort()).

You can always listen for write and data events on the connection to see what is being sent and received:

master.connection.on('write', b => console.log('TX:', b));
master.connection.on('data', b => console.log('RX:', b));
rtcimi commented 8 years ago

still no response ... .......................... [master] opened 0: No response was received from the slave in the specified time. [tx] <Buffer 02 05 02 5d 00 00 5d 93> 1: No response was received from the slave in the specified time. [tx] <Buffer 02 05 02 5d 00 00 5d 93> 2: No response was received from the slave in the specified time. [tx] <Buffer 02 05 02 5d 00 00 5d 93> ......................... I think that the problem is in serialport (2.14.7) version or maybe just configurations .... there is no modbus rx neither serialport.on('data') response ... but i don't want to upgrade serialport to see what will happen, because i could jeopardize previous working version :S

2016-06-06 19:05 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

If you're going to specify connection.serialPort option then the connection.serialPortOptions is ignored (you should use serialPort OR serialPortOptions - if you're using serialPort then stick the serialPortOptions to new SerialPort()).

You can always listen for write and data events on the connection to see what is being sent and received:

master.connection.on('write', b => console.log('TX:', b));master.connection.on('data', b => console.log('RX:', b));

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-224022028, or mute the thread https://github.com/notifications/unsubscribe/AQLJ1edA46O34sGvIDEDFotX3RTGsPf-ks5qJFN0gaJpZM4IhUoW .

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

morkai commented 8 years ago

If there are no data events then the cable is not properly connected or the device doesn't understand the request, i.e. wrong serial port options.

There is no version 2.14.7 of the serialport package (npm view serialport versions).

Does it work with the previous version of h5.modbus?

Did you try the simplest possible test case?

var SerialPort = require('serialport');

var serialPort = new SerialPort('/dev/ttyUSB0', {
  baudRate: 9600,
  dataBits: 8,
  stopBits: 1,
  parity: 'none'
});

serialPort.on('data', function(d) { console.log('RX:', d); });

serialPort.on('error', function(err) { console.error(err.message); });

serialPort.on('open', function()
{
  var frame = new Buffer([
    0x02, // Unit
    0x05, // Function code (write single coil)
    0x02, 0x5d, // Coil address
    0x00, 0x00, // Coil state (OFF)
    0x5d, 0x93 // Checksum
  ]);

  console.log('TX:', frame);

  serialPort.write(frame);
});
rtcimi commented 8 years ago

Test successful... rx is here ...

TX: <Buffer 02 03 02 5d 00 00 5d 93> RX: <Buffer 02 83 08 b0 f6>


var SerialPort = require('serialport').SerialPort;;

var serialPort = new SerialPort('/dev/ttyUSB0', { baudRate: 9600, dataBits: 8, stopBits: 1, parity: 'none', flowControl: ['RTSCTS'] });

serialPort.on('data', function(d) { console.log('RX:', d); });

serialPort.on('error', function(err) { console.error(err.message); });

serialPort.on('open', function(){ var frame = new Buffer([ 0x02, // Unit 0x03, // Function code (read holding registers) 0x02, 0x5d, // reg address 0x00, 0x00, // count 0x5d, 0x93 // Checksum ]); console.log('TX:', frame); serialPort.write(frame); });

2016-06-06 20:34 GMT+02:00 Łukasz Walukiewicz notifications@github.com:

If there are no data events then the cable is not properly connected or the device doesn't understand the request, i.e. wrong serial port options.

There is no version 2.14.7 of the serialport package (npm view serialport versions).

Does it work with the previous version of h5.modbus?

Did you try the simplest possible test case?

var SerialPort = require('serialport'); var serialPort = new SerialPort('/dev/ttyUSB0', { baudRate: 9600, dataBits: 8, stopBits: 1, parity: 'none' }); serialPort.on('data', function(d) { console.log('RX:', d); }); serialPort.on('error', function(err) { console.error(err.message); }); serialPort.on('open', function() { var frame = new Buffer([ 0x02, // Unit 0x05, // Function code (write single coil) 0x02, 0x5d, // Coil address 0x00, 0x00, // Coil state (OFF) 0x5d, 0x93 // Checksum ]);

console.log('TX:', frame);

serialPort.write(frame); });

— You are receiving this because you modified the open/close state. Reply to this email directly, view it on GitHub https://github.com/morkai/h5.modbus/issues/9#issuecomment-224047494, or mute the thread https://github.com/notifications/unsubscribe/AQLJ1Sry75wzzCAGdUXj4_nx6MjzTnGsks5qJGg2gaJpZM4IhUoW .

Lep pozdrav, Tomaž Rems

Izdelava spletnih strani, spletno in grafično oblikovanje

www.tomaz-rems.si http://www.tomaz-rems.si

morkai commented 8 years ago

Then try using the same serial port settings with h5.modbus:

var modbus = require('h5.modbus');

var master = modbus.createMaster({
  transport: {
    type: 'rtu',
    eofTimeout: 50 // Lower might work too
  },
  connection: {
    type: 'serial',
    serialPortOptions: {
      baudRate: 9600,
      dataBits: 8,
      stopBits: 1,
      parity: 'none'
    }
  },
  defaultUnit: 2,
  defaultTimeout: 1000,
  defaultMaxRetries: 0
});

master.once('open', function()
{
  var t = master.writeSingleCoil(605, false);

  t.on('error', function(err)
  {
    console.error('ERR: %s', err.message);
  });

  t.on('request', function(requestId)
  {
    console.log('REQ %d: %s', requestId, this.request);
  });

  t.on('response', function(res)
  {
    console.log(res.toString());
  });
});

Also, you wrote that the functionCode passed to the startTransaction() is 5, which is WRITE single coil, but you're passing quantity (that request expects state and if it's not present then OFF is assumed (because state === undefined and then !!state === false).