h5.modbus icon indicating copy to clipboard operation
h5.modbus copied to clipboard

Documentation

Open goranach opened this issue 12 years ago • 24 comments

I am very interested in your project, as it only meets my requirements. Could you write a small documentation for me. Thanks in advance.

goranach avatar Apr 29 '13 06:04 goranach

Hey!

I've added a few examples to the example/ directory. Check out the verbose-init-tcp-ip.js especially, as it also has some comments.

The automated tests are not finished, so there may be bugs. Some features (like functions for handling of repeatable transactions) are not yet present.

As I was writing the code, I've tested it against Modbus PLC Simulator (can be used to quickly run the examples), some Delta PLC (Serial+ASCII, Serial+RTU, TCP+IP), Array APB PLC and Delta+Moxa NPort (TCP+ASCII -> Serial+ASCII, UDP+ASCII -> Serial+ASCII...).

The proper readme and documentation will be done after 100% test code coverage, which in turn may be done if I'll have to do another application that requires MODBUS.

Until then, feel free to ask any questions here ;)

morkai avatar Apr 29 '13 18:04 morkai

Do you have any examples using Serial RTU? The project looks pretty solid however I am struggling with reading and writing holding registers over serial RTU. Any small example using your project would be wonderful.

rlemon avatar Jan 10 '14 20:01 rlemon

You'll need node-serialport:

npm install serialport

Then, create the master like so:

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

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

var master = modbus.createMaster({
  transport: {
    type: 'rtu',
    eofTimeout: 10, // End of frame timeout
    connection: {
      type: 'serial',
      serialPort: serialPort
    }
  }
});

// ...

morkai avatar Jan 10 '14 20:01 morkai

Thanks for the quick reply. I will fiddle about and let you know how everything goes.

rlemon avatar Jan 10 '14 21:01 rlemon

Thanks again for the help. One more question (then I think I am good to get this rolling on my own).

I am attempting to connect to my device and just read a single holding register, however immediately after running master.readHoldingRegisters(1,1,opts) i'm receiving a timeout error (no delay is waited) - shortly after the retries and stuff happen.

events.js:72
        throw er; // Unhandled 'error' event
              ^
ResponseTimeoutError: No response was received from the slave in the specified time.
    at Transaction.handleTimeout (/home/rlemon/dryermaster/modbus/lib/Transaction.js:452:20)
    at Timer.listOnTimeout [as ontimeout] (timers.js:110:15)

Have you ever seen this while working with the library? What was the general cause of it to not want to communicate? I have tested that the device does communicate properly on windows with other software via modbus RTU.

I appreciate your time.

Thanks, rlemon.

rlemon avatar Jan 13 '14 21:01 rlemon

You have to listen for the error events on the transaction object returned by the readHoldingRegisters() or set the master's supressTransactionErrors to true (master and transaction objects are node.js EventEmitters and they throw an exception if an error event was emitted, buy there is no listeners):

// ...

var master = modbus.createMaster({
  suppressTransactionErrors: true, // automatically adds a listener for the `error` events to every transaction
  transport: {
    // ...
  }
});

var req = master.readHoldingRegisters(1, 1, opts);

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

If you have a lot of timeout errors, then try to increase the timeout options until they are gone (master's defaultTimeout option or transaction's timeout option).

morkai avatar Jan 13 '14 21:01 morkai

Sorry to continue to bother you. We're having some real issues - I presumed to change the slaveID I would change the unit in the Transaction Options.. but reading the stream on the other end I'm seeing the slave as 00 ?? How do I set the slave ID?

rlemon avatar Jan 22 '14 15:01 rlemon

master.readHoldingRegisters(0, 1, {unit: 1})

What Connection and Transport are you using? Serial RTU?

morkai avatar Jan 22 '14 15:01 morkai

Sorry false alarm. I have another gentleman working on this with me and he hard coded the unit in the Transaction file to 13 (and tera term makes D and 0 look incredibly alike) - So we were actually seeing 0D (13) - reverted the file and it works as expected. Sorry for jumping the gun.

rlemon avatar Jan 22 '14 15:01 rlemon

Sorry, to bother you. I'm working along side rlemon on this code. Unfortunately, as it stands the modbus library defaults to START_LOW_COIL = 1, but we want it to start at 0. Here's my calling procedure:

    var transactionOptions = {
        timeout: 10000,
        unit: 1
    };

    var req = master.readHoldingRegisters( 1 , 1 , transactionOptions);

Is there a default variable, analogous to 'timeout' or 'unit' in the code sample above, that we can specify to force it to start at 0?

The frame data it currently outputs is: "01 03 00 01 00 01 D5 CA".

Thanks

paradigminversion avatar Jan 22 '14 16:01 paradigminversion

Why don't you pass 0 as the first argument?

// readHoldingRegisters(address, quantity, options)
master.readHoldingRegisters(1, 1, {unit: 1})
// results in frame
// 01 - unit
// 03 - function code
// 00 01 - address
// 00 01 - quantity
// D5 CA - checksum

master.readHoldingRegisters(0, 1, {unit: 1})
// should result in frame
// 01 - unit
// 03 - function code
// 00 00 - address
// 00 01 - quantity
// xx xx - checksum

morkai avatar Jan 22 '14 16:01 morkai

Awesome!!! It works!!! Thanks a bunch.

paradigminversion avatar Jan 22 '14 16:01 paradigminversion

I have a terminal monitoring packets sent and received and I am finally getting a response packet from the slave of: 01 03 02 00 00 B8 44 which looks perfect and the CRC checks out, but the modbus code doesn't receive anything. It just times out with the message: 'ERR [ { name: 'ResponseTimeoutError', message: 'No response was received from the slave in the specified time.' }, undefined, undefined ] ' Again the code is,

var SerialPort = require('serialport').SerialPort,
    modbus = require('./lib');

var portOptions = {
    baudRate: 19200,
    dataBits: 8,
    stopBits: 1,
    parity: 'none',
    flowControl: false
};

var serialPort = new SerialPort('/dev/ttyO2', portOptions, true, startScan);

function startScan() {
    var master = modbus.createMaster({
        suppressTransactionErrors: true,
        transport: {
            type: 'rtu',
            eofTimeout: 100000,
            connection: {
                type: 'serial',
                serialPort: serialPort
            }
        }
    });

    var transactionOptions = {
        timeout: 10000,
        unit: 1
    };

    var req = master.readHoldingRegisters( 0 , 5 , transactionOptions);

    req.on('response', function(a,b,c) {
        console.log('RESP', [a,b,c]);
    }).on('complete', function(a,b,c) {
        console.log('COMPL', [a,b,c]);
    }).on('error', function(a,b,c) {
        console.log('ERR', [a,b,c]);
    });

}

Is there anyway that I can dump or check if data is received? Thanks in advance.

paradigminversion avatar Jan 23 '14 17:01 paradigminversion

Modbus RTU separates frames by not sending anything for a specific amount of time ("at least 3 1⁄2 character times of silence between frames", see Wikipedia). I don't think you can wait 3 1/2 character times in Node.js so I've introduced the eofTimeout option. After the data is received, the RTU transport waits eofTimeout milliseconds, and if no more data is received, then an end of frame is assumed. If more data arrives before the eofTimeout ms, then the end of frame timer is restarted.

You have set the eofTimeout to 100 seconds, so the RTU transport will parse the frame after 100s. BUT You have also set the timeout to 10 seconds, which is less than eofTimeout and finishes first. There's your ResponseTimeoutError.

Try setting the timeout option to 200 and the eofTimeout to 20. If you'll receive a lot of ResponseTimeoutErrors, then slowly increase the timeout option. If you'll receive a lot of IncompleteResponseFrameErrors or InvalidChecksumErrors, then slowly increase the eofTimeout option.

morkai avatar Jan 23 '14 17:01 morkai

That did it!!! Thanks again.

paradigminversion avatar Jan 23 '14 18:01 paradigminversion

Hey, do you have any examples of using ascii?

I have been successfully using your rtu example but switching over to ascii I keep getting a "ResponseTimeoutError". I connected a network analyzer and my device is getting everything correct, I just can't figure out how to tell the listener that there is a response waiting.

tvthatsme avatar Aug 06 '14 18:08 tvthatsme

Hey! Try increasing the master's defaultTimeout option or transaction's timeout option. See https://gist.github.com/morkai/f7b11f971682fc8e5598

morkai avatar Aug 06 '14 18:08 morkai

Thanks for the quick response! Did a complete wipe of my source and that fixed it. I must have tried modifying something in the h5.modbus source. Responses are coming through in ~50 ms now so the defaultTimeout wasn't the issue (I was...).

tvthatsme avatar Aug 06 '14 19:08 tvthatsme

Should 'eofTimeout' be a function of the baud rate?...

zachheine avatar Feb 09 '15 07:02 zachheine

It should, but it won't work in node.js. For baud rates >= 19200 it should be 1.75 ms, for 9600 - 3.65 ms. Node isn't reliable with such small timers, so you should just test what is the smallest value that works for you.

morkai avatar Feb 09 '15 07:02 morkai

Hey, I try to make scada app in node.js ,i need modbus-tcp but i haven't find any example that explain modbus with node.js , i have installed modbus-tcp module but i don't find an example and modbus simulator ?? Please i need your help

lamyra avatar Apr 13 '15 13:04 lamyra

I am interested in this project. but the node version is too high. is V0.10.X will be possible?

AllenBird avatar May 10 '16 03:05 AllenBird

The one from the master branch won't work (unless you transpile it using something like Babel).

The old version will work: https://github.com/morkai/h5.modbus/tree/v0

morkai avatar May 10 '16 10:05 morkai