scouting-modbus-reader
v0.0.2
Published
Routine to communicate with Modbus-TCP including symbol lookup, etc, for PLCs
Downloads
1
Readme
modbusReader
modbusReader is a library that provides communication with PLCs and controllers using MODBUS/TCP or MODBUS RTU over TCP. It supports various tag formats for reading and writing data, including coils, input status, input register, holding register, etc. It supports the default slave ID of 1, but you can specify a different slave ID if necessary. modbusReader can be installed via npm by running npm install modbusReader. To use it, you can require the library and use it to initiate a connection, set a translation callback, add items to be read or written, and write values to those items.
Tag format supports the following:
TAG1=00001SLAVE2 // Leading zeros optional, 1-based "coils". Read/write. Always writes with "force multiple coils" FC15, never uses the single.
TAG1=00001,100 // Array of coils from slave 1 (formerly 255). Read/write.
TAG1=10001 // Input status. Read-only.
TAG1=10001,100 // Input status array. Read-only.
TAG1=30001 // Input register. Read-only.
TAG1=30001,100 // Input register array. Read-only.
TAG1=30001:REAL,100 // Input register array as REAL. Read-only. Assumes skip registers, like first is 30001, next is 30003, etc.
TAG1=30001:WSREAL,100 // Input register array as word-swapped REAL. Read-only. Assumes skip registers, like first is 30001, next is 30003,etc.
TAG1=30001:DINT // Input register as DINT
TAG1=30001:WSDINT // Input register as word-swapped DINT
TAG1=30001:DWORD // Input register as unsigned DINT
TAG1=30001:WSDWORD // Input register as word-swapped unsigned DINT
TAG1=30001.0,15 // First Input register split into bits (read-only)
TAG1=40001 // Holding register. Read-only.
TAG1=40001,100 // Holding register array. Read-only.
TAG1=40001:REAL,100 // Holding register array as REAL. Assumes skip registers, like first is 40001, next is 40003, etc.
TAG1=40001:WSREAL,100 // Holding register array as word-swapped REAL. Assumes skip registers, like first is 40001, next is 40003, etc.
TAG1=40001:DINTSLAVE2 // Holding register as DINT, from slave 1
TAG1=40001:WSDINTSLAVE2 // Holding register as word-swapped DINT, from slave 1
TAG1=40001:DWORD // Holding register as unsigned DINT
TAG1=40001:WSDWORD // Holding register as word-swapped unsigned DINT
TAG1=40001.3 // Holding register bit (IMPORTANT NOTE: read-only - can't write individual bits of 4000x registers)
TAG1=RD90 // Holding register 40091 as double integer
TAG1=R190 // Holding register 40191 as integer
Installation:
npm install modbusReader
Example usage:
var modbusReader = require('modbusReader');
var conn = new modbusReader();
var doneReading = false;
var doneWriting = false;
conn.initiateConnection({port: 502, host: '192.168.8.199', defaultID: 1, RTU: false}, connected); // defaultID defaults to 1 and RTU defaults to false but shown here for illustration
function connected(err) {
if (typeof(err) !== "undefined") {
// We have an error. Maybe the PLC is not reachable.
console.log(err);
process.exit();
}
conn.setTranslationCB(tagLookup);
conn.addItems(['TEST1']);
// conn.addItems(['TEST1', 'TEST4']);
// conn.removeItems(['TEST2', 'TEST3']); // Demo.
// conn.writeItems(['TEST5', 'TEST6'], [ 867.5309, 9 ], valuesWritten); // You can write an array of items.
// conn.writeItems('TEST7', [ 666, 777 ], valuesWritten); // You can write a single array item too.
conn.readAllItems(valuesReady);
}
function valuesReady(anythingBad) {
if (anythingBad) { console.log("SOMETHING WENT WRONG READING VALUES!!!!"); }
console.log("Value is " + conn.findItem('TEST1').value + " quality is " + conn.findItem('TEST1').quality);
doneReading = true;
if (doneWriting) { process.exit(); }
}
function valuesWritten(anythingBad) {
if (anythingBad) { console.log("SOMETHING WENT WRONG WRITING VALUES!!!!"); }
console.log("Done writing.");
doneWriting = true;
if (doneReading) { process.exit(); }
}
// This is a very simple "tag lookup" callback function that would eventually be replaced with either a database findOne(), or a large array in memory.
// Note that the return value is a controller absolute address and datatype specifier.
// If you want to use absolute addresses only, you can do that too.
function tagLookup(tag) {
switch (tag) {
case 'TEST1':
return "030SLAVE1";
case 'TEST2':
return '40100.0SLAVE1';
case 'TEST3':
return '40101.1SLAVE1';
case 'TEST4':
return '30001.1SLAVE1';
case 'TEST5':
return '00008SLAVE1';
case 'TEST6':
return '00003,20SLAVE1';
case 'TEST7':
return '00001,3000SLAVE1';
case 'TEST8':
return '40001:DINTSLAVE1';
case 'TEST9':
return '40001:DINT,400SLAVE1';
case 'TEST10':
return '30001.0,16SLAVE1';
default:
return undefined;
}
}