From b28340bc1e4d35e1c384537852deda91fd5eaa81 Mon Sep 17 00:00:00 2001 From: Braden Ehrat Date: Thu, 6 Jun 2013 00:36:28 -0500 Subject: [PATCH 1/4] Implemented function code 16 (Write Multiple Registers) --- client.js | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/client.js b/client.js index be63b56..89c6e8f 100644 --- a/client.js +++ b/client.js @@ -54,6 +54,22 @@ Client.REQUESTS = { 5: function(address, value) { if (typeof value !== 'boolean') throw new Error('"Write Single Coil" expects a \'boolean\' value'); return putTwoWord16be(address, value ? 0xff00 : 0x0000); + }, + 16: function(address, values) { + if(1 > values.length || values.length > 123) { + throw new Error('"Write Multipe Registers" expects 1 to 123 registers'); + } + + request = Put() + .word16be(address) + .word16be(values.length) + .word8(values.length*2); + + for(var i=0; i Date: Sat, 8 Jun 2013 22:05:18 -0500 Subject: [PATCH 2/4] Client request/responses 1-6,15,16 are now fully implemented --- client.js | 115 +++++++++++++++++++++++++++++++++++++++------------ package.json | 5 ++- server.js | 1 + 3 files changed, 93 insertions(+), 28 deletions(-) diff --git a/client.js b/client.js index 89c6e8f..66f51c5 100644 --- a/client.js +++ b/client.js @@ -4,6 +4,7 @@ var Binary = require('bufferlist/binary').Binary; var modbus = require('./modbus-stack'); var netStream = require('net').Stream; var FUNCTION_CODES = modbus.FUNCTION_CODES; +var BitArray = require('node-bitarray'); /* TCP MODBUS Client interface, as it's the most usual use-case. */ function Client () { @@ -55,9 +56,35 @@ Client.REQUESTS = { if (typeof value !== 'boolean') throw new Error('"Write Single Coil" expects a \'boolean\' value'); return putTwoWord16be(address, value ? 0xff00 : 0x0000); }, + // WRITE_SINGLE_REGISTER + 6: putTwoWord16be, + + // WRITE_MULTIPLE_COILS + 15: function(adress, values) { + if(values.length < 1 || values.length > 1968) { + throw new Error('"Write Multiple Coils" expects 1 to 1968 registers'); + } + + values.map( + function(val) { + if (typeof val !== 'boolean') throw new Error('"Write Multiple Coils" expects \'boolean\' values'); + return val ? 1 : 0; + } + ) + + request = Put() + .word16be(address) + .word16be(values.length) + .word8(Math.ceil(values.length/8)) + .put(BitArray.toBuffer(values)); + + return request.buffer(); + }, + + // WRITE_MULTIPLE_REGISTERS 16: function(address, values) { - if(1 > values.length || values.length > 123) { - throw new Error('"Write Multipe Registers" expects 1 to 123 registers'); + if(values.length < 1 || values.length > 123) { + throw new Error('"Write Multiple Registers" expects 1 to 123 registers'); } request = Put() @@ -73,38 +100,74 @@ Client.REQUESTS = { } }; -Client.RESPONSES = { - // READ_INPUT_REGISTERS - 4: function(bufferlist) { - var rtn = []; +function readBitArray(bufferlist) { + var binary = Binary(bufferlist) + .getWord8('byteCount') + .end(); + + var rtn = []; + for(var i=0, l=binary.vars.byteCount; i= 1.0.1", "bufferlist": ">= 0.0.6", - "put": "*" + "put": "*", + "node-bitarray": ">= 0.0.2", }, "devDependencies": { "colors": ">= 0.3.0", @@ -28,4 +29,4 @@ "files": [ "" ] -} \ No newline at end of file +} diff --git a/server.js b/server.js index 69845e1..389a99f 100644 --- a/server.js +++ b/server.js @@ -5,6 +5,7 @@ var Binary = require('bufferlist/binary').Binary; var modbus = require('./modbus-stack'); var FUNCTION_CODES = modbus.FUNCTION_CODES; + /* Streamlined TCP MODBUS server class. Can be used to respond to MODBUS requests * from TCP clients. `handlers` can be a function which is invoked for every * "request" event, or an Object with keys being the Function Codes your server From 7601c62a03aeecf68c6f863422481657119db9bd Mon Sep 17 00:00:00 2001 From: Braden Ehrat Date: Sat, 8 Jun 2013 22:33:43 -0500 Subject: [PATCH 3/4] Fixed package.json syntax --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index c9974c3..fcbe74f 100644 --- a/package.json +++ b/package.json @@ -12,7 +12,7 @@ "stream-stack": ">= 1.0.1", "bufferlist": ">= 0.0.6", "put": "*", - "node-bitarray": ">= 0.0.2", + "node-bitarray": ">= 0.0.2" }, "devDependencies": { "colors": ">= 0.3.0", From d887b311e02d0e0dbab11ffb377a12f2268d2ab1 Mon Sep 17 00:00:00 2001 From: Braden Ehrat Date: Sat, 8 Jun 2013 23:06:23 -0500 Subject: [PATCH 4/4] Fixed WRITE_MULTIPLE_COILS request bit order --- client.js | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/client.js b/client.js index 66f51c5..e169b5e 100644 --- a/client.js +++ b/client.js @@ -60,7 +60,7 @@ Client.REQUESTS = { 6: putTwoWord16be, // WRITE_MULTIPLE_COILS - 15: function(adress, values) { + 15: function(address, values) { if(values.length < 1 || values.length > 1968) { throw new Error('"Write Multiple Coils" expects 1 to 1968 registers'); } @@ -75,8 +75,15 @@ Client.REQUESTS = { request = Put() .word16be(address) .word16be(values.length) - .word8(Math.ceil(values.length/8)) - .put(BitArray.toBuffer(values)); + .word8(Math.ceil(values.length/8)); + + // We have to reverse each 8 bits + while(values.length > 0) { + request.put(BitArray.toBuffer( + values.splice(0,8) + .reverse() // The LSB of the first data byte contains the output addressed in the query. + )); + } return request.buffer(); },