yaacov / node-modbus-serial

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

Problem with Modbus Ascii Protocol #235

Open behi88 opened 5 years ago

behi88 commented 5 years ago

Hello @yaacov i find a problem to read Modbus ASCII. actually all of of FC1 - FC2 - FC3 and FC4 have problem reading received data (not sending request). my program is simple:

var Modbus = require("modbus-serial"); var client = new Modbus(); client.setTimeout(5000); client.setID(1); client.connectAsciiSerial("/dev/ttyUSB0", { baudRate: 9600, databits: 7, }).then(function () { client.readHoldingRegisters(0, 10) .then(function(data) { console.log(data.data); }) .catch (function(err) { console.log('SID:('+client.getID()+") " + err.message); }) });

and here is the Debug dump:

modbus-serial { action: 'send serial ascii port', modbus-serial data: <Buffer 3a 30 31 30 33 30 30 30 30 30 30 30 41 46 32 0d 0a>, modbus-serial unitid: 1, modbus-serial functionCode: 3 } +0ms modbus-serial {"action":"send serial ascii port","data":{"type":"Buffer","data":[58,48,49,48,51,48,48,48,48,48,48,48,65,70,50,13,10]},"unitid":1,"functionCode":3} +15ms SID:(1) Timed out ^C root@DietPi:/home# node test.js modbus-serial { action: 'send serial ascii port', modbus-serial data: <Buffer 3a 30 31 30 33 30 30 30 30 30 30 30 41 46 32 0d 0a>, modbus-serial unitid: 1, modbus-serial functionCode: 3 } +0ms modbus-serial {"action":"send serial ascii port","data":{"type":"Buffer","data":[58,48,49,48,51,48,48,48,48,48,48,48,65,70,50,13,10]},"unitid":1,"functionCode":3} +14ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 3a>, modbus-serial buffer: <Buffer 3a> } +30ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[58]},"buffer":{"type":"Buffer","data":[58]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 31 30 33 32 38 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30> } +4ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,49,48,51,50,56,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48]}} +0ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 31 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[49,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48]}} +0ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30> } +0ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +0ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +0ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +2ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 30>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,48]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48]}} +2ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 30 44 33>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 44 33> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[48,68,51]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,68,51]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 0d>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 44 33 0d> } +1ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[13]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,68,51,13]}} +1ms modbus-serial { action: 'receive serial ascii port', modbus-serial data: <Buffer 0a>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 44 33 0d ... > } +0ms modbus-serial {"action":"receive serial ascii port strings","data":{"type":"Buffer","data":[10]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,68,51,13,10]}} +1ms modbus-serial { action: 'got EOM', modbus-serial data: modbus-serial <Buffer 01 03 28 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 67 a4>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 44 33 0d ... > } +2ms modbus-serial { action: 'emit data serial ascii port', modbus-serial data: <Buffer 0a>, modbus-serial buffer: modbus-serial <Buffer 3a 30 31 30 33 32 38 30 30 30 31 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 30 44 33 0d ... > } +1ms modbus-serial {"action":"emit data serial ascii port strings","data":{"type":"Buffer","data":[10]},"buffer":{"type":"Buffer","data":[58,48,49,48,51,50,56,48,48,48,49,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,48,68,51,13,10]}} +1ms (node:2885) UnhandledPromiseRejectionWarning: RangeError [ERR_OUT_OF_RANGE]: The value of "offset" is out of range. It must be >= 0 and <= 23. Received 25 at boundsError (internal/buffer.js:53:9) at Buffer.readUInt16BE (internal/buffer.js:219:5) at _readFC4 (/home/node_modules/modbus-serial/index.js:89:24) at AsciiPort. (/home/node_modules/modbus-serial/index.js:321:25) at AsciiPort.emit (events.js:182:13) at SerialPort. (/home/node_modules/modbus-serial/ports/asciiport.js:162:28) at SerialPort.emit (events.js:182:13) at addChunk (_stream_readable.js:283:12) at readableAddChunk (_stream_readable.js:264:11) at SerialPort.Readable.push (_stream_readable.js:219:10) (node:2885) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 1) (node:2885) [DEP0018] DeprecationWarning: Unhandled promise rejections are deprecated. In the future, promise rejections that are not handled will terminate the Node.js process with a non-zero exit code.

the problem is not the same for bit request (FC1- FC2) and register request (FC3 - FC4). in bit request we actuality have an answer but instead of 10 bits we get 32 wrong bits! my Hardware is Raspberry pi3 and my Linux version is Debian. Thank for you help

yaacov commented 5 years ago

Thanks :+1:

I will look at it, but I will not have lots of time in the next few weeks, If you find more info, or have a fix, please comment here.

behi88 commented 5 years ago

I find the Problem is from https://github.com/yaacov/node-modbus-serial/blob/master/ports/asciiport.js

line 162 : modbus.emit("data", _data);

could you help me? where this ".emit" referred to?

if I commented this line there will be no answer from client modbus

yaacov commented 5 years ago

could you help me? where this ".emit" referred to?

When "data" event is emitted in line 162 it calls this function with _data as the parameter: https://github.com/yaacov/node-modbus-serial/blob/master/index.js#L235

behi88 commented 5 years ago

thanks @yaacov I think I found it! there is a mix-up in read buffers, I think you should mix 2 ASCII registers in to one binary for decode Let me be sure then I will post the result here.

yaacov commented 5 years ago

@behi88 Thanks, when you get it to work, please make a pull request with the fix :+1:

behi88 commented 5 years ago

@yaacov I found the problem. in ASCII mode because the byes are transfer in ASCII codes so every 2 ASCII character represent one byte in Hex so finally after changing ASCII to binary at the end you should divide byte count (Buffer[2]) by 2. first I assume you forget to convert ASCII array to binary buffer so i implant a code in https://github.com/yaacov/node-modbus-serial/blob/master/ports/asciiport.js before line 162 I assumed the buffer name was "modbus._buffer" so i transfer my buffer to that. but after running i understand there is no change. and i find you converted ASCII code to binary buffer somewhere in code ( that i could not find) and all need to do is to Halve the Buffer[2] (received byte count). any ideas?

yaacov commented 5 years ago

Thanks !

converted ASCII code to binary buffer somewhere in code ( that i could not find)

a. the function that translate ASCII to RTU is here: https://github.com/yaacov/node-modbus-serial/blob/master/ports/asciiport.js#L50

b. it is called here: https://github.com/yaacov/node-modbus-serial/blob/master/ports/asciiport.js#L153

all need to do is to Halve the Buffer[2] (received byte count).

c. The buffer size should be halved here: https://github.com/yaacov/node-modbus-serial/blob/master/ports/asciiport.js#L53