# How to calculate CRC-16 (Modbus)?

**URL:** https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955
**Category:** General
**Created:** [27 July 2021 08:43 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955 "2021-07-27T08:43:26Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![quemf](https://avatars.discourse-cdn.com/v4/letter/q/97f17d/32.png) [@quemf](https://discourse.nodered.org/u/quemf)
#### Post date: [27 July 2021 08:43 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/1 "2021-07-27T08:43:27Z")

</div>

Hi everyone,

I am trying to calculate CRC with a function I got from Node-RED forum, but when there is a 0 at the end or at the beginning of the CRC, it does not identify it, and I just get three bytes.

The fact is that I do not want to download any node, only a function for the CRC-16 (Modbus) like a frame like this: 010600000001 + CRC

Could anyone help me please?

Thank you very much,

Q.

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [27 July 2021 09:10 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/2 "2021-07-27T09:10:50Z")

</div>

Please post a flow using the function you have which works except in the leading/trailing zero case so we can see what you are have. Include inject nodes with test data that works and test data that doesn't, and tell us what output you expect.

---

<div class="post-metadata">

### Author: ![quemf](https://avatars.discourse-cdn.com/v4/letter/q/97f17d/32.png) [@quemf](https://discourse.nodered.org/u/quemf)
#### Post date: [27 July 2021 09:19 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/3 "2021-07-27T09:19:54Z")

</div>

This is my flow, and I attach the function node with the CRC-16 calculation I got from somewhere in Node-RED forum

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/e/c/ec5f40455f586e773d44ebb0cd640625c1303550.png)

```auto
[{"id":"60f6223737445c93","type":"function","z":"e6126f89.fbab88","name":"CRC16-modbus","func":"var CRCMaster = {\n StringToCheck: \"\",\n CleanedString: \"\",\n CRCTableDNP: [],\n init: function() {\n this.CRCDNPInit();\n },\n CleanString: function(inputType) {\n if (inputType == \"ASCII\") {\n this.CleanedString = this.StringToCheck;\n } else {\n if (this.StringToCheck.match(/^[0-9A-F \\t]+$/gi) !== null) {\n this.CleanedString = this._hexStringToString(this.StringToCheck.toUpperCase().replace(/[\\t]/g, ''));\n } else {\n window.alert(\"String doesn't seem to be a valid Hex input.\");\n return false;\n }\n }\n return true;\n },\n CRCDNPInit: function() {\n var i, j, crc, c;\n for (i = 0; i < 256; i++) {\n crc = 0;\n c = i;\n for (j = 0; j < 8; j++) {\n if ((crc ^ c) & 0x0001) crc = (crc >> 1) ^ 0xA6BC;\n else crc = crc >> 1;\n c = c >> 1;\n }\n this.CRCTableDNP[i] = crc;\n }\n },\n CRC16Modbus: function() {\n var crc = 0xFFFF;\n var str = this.CleanedString;\n for (var pos = 0; pos < str.length; pos++) {\n crc ^= str.charCodeAt(pos);\n for (var i = 8; i !== 0; i--) {\n if ((crc & 0x0001) !== 0) {\n crc >>= 1;\n crc ^= 0xA001;\n } else\n crc >>= 1;\n }\n }\n return crc;\n },\n _stringToBytes: function(str) {\n var ch, st, re = [];\n for (var i = 0; i < str.length; i++) {\n ch = str.charCodeAt(i); // get char\n st = []; // set up \"stack\"\n do {\n st.push(ch & 0xFF); // push byte to stack\n ch = ch >> 8; // shift value down by 1 byte\n }\n while (ch);\n // add stack contents to result\n // done because chars have \"wrong\" endianness\n re = re.concat(st.reverse());\n }\n // return an array of bytes\n return re;\n },\n _hexStringToString: function(inputstr) {\n var hex = inputstr.toString(); //force conversion\n var str = '';\n for (var i = 0; i < hex.length; i += 2)\n str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));\n return str;\n },\n Calculate: function(str, inputType) {\n this.StringToCheck = str;\n if (this.CleanString(inputType)) {\n crcinputcrc16modbus=this.CRC16Modbus().toString(16).toUpperCase();\n crcinputcrc16modbus=crcinputcrc16modbus.substr(2) + crcinputcrc16modbus.substr(0, 2); //swap bytes\n \n }\n }\n};\n\nCRCMaster.init();\n\nvar inputType = \"HEX\";\nvar crcinputcrc16modbus;\nvar crcinput = msg.payload;\n\nCRCMaster.Calculate(crcinput, inputType);\n\nmsg.payload = crcinput + crcinputcrc16modbus;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":1140,"y":300,"wires":[["6dd18cb44dba730b","e51d8658ec920d84","d3f9521b3ad8ac69"]]}]

```

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [27 July 2021 09:26 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/4 "2021-07-27T09:26:53Z")

</div>

You have only posted the function node. We need a flow that we can test.

---

<div class="post-metadata">

### Author: ![quemf](https://avatars.discourse-cdn.com/v4/letter/q/97f17d/32.png) [@quemf](https://discourse.nodered.org/u/quemf)
#### Post date: [27 July 2021 09:32 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/5 "2021-07-27T09:32:34Z")

</div>

```auto
[{"id":"55c99f3d9881b6a1","type":"tab","label":"Flow 4","disabled":false,"info":""},{"id":"42b2ad79813b38ca","type":"inject","z":"55c99f3d9881b6a1","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"010600000000","payloadType":"str","x":380,"y":140,"wires":[["6613dfcd1aaa2010"]]},{"id":"6613dfcd1aaa2010","type":"function","z":"55c99f3d9881b6a1","name":"CRC16-modbus","func":"var CRCMaster = {\n StringToCheck: \"\",\n CleanedString: \"\",\n CRCTableDNP: [],\n init: function() {\n this.CRCDNPInit();\n },\n CleanString: function(inputType) {\n if (inputType == \"ASCII\") {\n this.CleanedString = this.StringToCheck;\n } else {\n if (this.StringToCheck.match(/^[0-9A-F \\t]+$/gi) !== null) {\n this.CleanedString = this._hexStringToString(this.StringToCheck.toUpperCase().replace(/[\\t]/g, ''));\n } else {\n window.alert(\"String doesn't seem to be a valid Hex input.\");\n return false;\n }\n }\n return true;\n },\n CRCDNPInit: function() {\n var i, j, crc, c;\n for (i = 0; i < 256; i++) {\n crc = 0;\n c = i;\n for (j = 0; j < 8; j++) {\n if ((crc ^ c) & 0x0001) crc = (crc >> 1) ^ 0xA6BC;\n else crc = crc >> 1;\n c = c >> 1;\n }\n this.CRCTableDNP[i] = crc;\n }\n },\n CRC16Modbus: function() {\n var crc = 0xFFFF;\n var str = this.CleanedString;\n for (var pos = 0; pos < str.length; pos++) {\n crc ^= str.charCodeAt(pos);\n for (var i = 8; i !== 0; i--) {\n if ((crc & 0x0001) !== 0) {\n crc >>= 1;\n crc ^= 0xA001;\n } else\n crc >>= 1;\n }\n }\n return crc;\n },\n _stringToBytes: function(str) {\n var ch, st, re = [];\n for (var i = 0; i < str.length; i++) {\n ch = str.charCodeAt(i); // get char\n st = []; // set up \"stack\"\n do {\n st.push(ch & 0xFF); // push byte to stack\n ch = ch >> 8; // shift value down by 1 byte\n }\n while (ch);\n // add stack contents to result\n // done because chars have \"wrong\" endianness\n re = re.concat(st.reverse());\n }\n // return an array of bytes\n return re;\n },\n _hexStringToString: function(inputstr) {\n var hex = inputstr.toString(); //force conversion\n var str = '';\n for (var i = 0; i < hex.length; i += 2)\n str += String.fromCharCode(parseInt(hex.substr(i, 2), 16));\n return str;\n },\n Calculate: function(str, inputType) {\n this.StringToCheck = str;\n if (this.CleanString(inputType)) {\n crcinputcrc16modbus=this.CRC16Modbus().toString(16).toUpperCase();\n crcinputcrc16modbus=crcinputcrc16modbus.substr(2) + crcinputcrc16modbus.substr(0, 2); //swap bytes\n \n }\n }\n};\n\nCRCMaster.init();\n\nvar inputType = \"HEX\";\nvar crcinputcrc16modbus;\nvar crcinput = msg.payload;\n\nCRCMaster.Calculate(crcinput, inputType);\n\nmsg.payload = crcinput + crcinputcrc16modbus;\n\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","x":700,"y":240,"wires":[["40b3a69e5f8c5291","98d620ed386faf37"]]},{"id":"40b3a69e5f8c5291","type":"debug","z":"55c99f3d9881b6a1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":930,"y":240,"wires":[]},{"id":"2892e85f9e5d2a87","type":"debug","z":"55c99f3d9881b6a1","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"payload","targetType":"msg","statusVal":"","statusType":"auto","x":1090,"y":120,"wires":[]},{"id":"98d620ed386faf37","type":"function","z":"55c99f3d9881b6a1","name":"get length","func":"msg.payload = msg.payload.length;\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":920,"y":120,"wires":[["2892e85f9e5d2a87"]]},{"id":"71a4a81b240a5701","type":"inject","z":"55c99f3d9881b6a1","name":"","props":[{"p":"payload"},{"p":"topic","vt":"str"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"010600000001","payloadType":"str","x":380,"y":380,"wires":[["6613dfcd1aaa2010"]]},{"id":"c3abe52f59e42bd0","type":"comment","z":"55c99f3d9881b6a1","name":"CRC: CA89. Little Endian: 89CA","info":"","x":350,"y":180,"wires":[]},{"id":"353580a5edab4c4f","type":"comment","z":"55c99f3d9881b6a1","name":"CRC: 0A48. Little Endian: 480A","info":"","x":330,"y":420,"wires":[]}]

```

Admin edit: Corrected trailing backticks (need to be on new line).

---

<div class="post-metadata">

### Author: ![Colin](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/colin/32/17040_2.png) [@Colin](https://discourse.nodered.org/u/Colin)
#### Post date: [27 July 2021 10:24 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/6 "2021-07-27T10:24:18Z")

</div>

Change the line  
` crcinputcrc16modbus=this.CRC16Modbus().toString(16).toUpperCase();`  
to  
`crcinputcrc16modbus=this.CRC16Modbus().toString(16).toUpperCase().padStart(4,"0");`

---

<div class="post-metadata">

### Author: ![quemf](https://avatars.discourse-cdn.com/v4/letter/q/97f17d/32.png) [@quemf](https://discourse.nodered.org/u/quemf)
#### Post date: [27 July 2021 10:54 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/7 "2021-07-27T10:54:06Z")

</div>

Thank you very much! It works now! 🙂

---

<div class="post-metadata">

### Author: ![system](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/1X/d073cd938eafa2e558d7c2cd59003b3ef4963033.png) [@system](https://discourse.nodered.org/u/system)
#### Post date: [10 August 2021 10:54 UTC](https://discourse.nodered.org/t/how-to-calculate-crc-16-modbus/48955/8 "2021-08-10T10:54:56Z")

</div>

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.
