Skip to content

Instantly share code, notes, and snippets.

@nixator
Created May 28, 2021 12:41
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nixator/28e9e10c72a9d00f438ec1150734c7a9 to your computer and use it in GitHub Desktop.
Save nixator/28e9e10c72a9d00f438ec1150734c7a9 to your computer and use it in GitHub Desktop.
CRC16 modbus rtu

Funtion block that adds CRC 16 checksum to modbus rtu command. Example:

input: 010600010100 output: 010600010100D99A

[{"id":"e6126f89.fbab88","type":"tab","label":"modbus rtu crc","disabled":false,"info":""},{"id":"7812b725.54f17","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":660,"y":380,"wires":[["da260a66.2e0fb"]]},{"id":"265c58e5.dc37a","type":"inject","z":"e6126f89.fbab88","name":"","props":[{"p":"payload"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"010600010100","payloadType":"str","x":400,"y":380,"wires":[["7812b725.54f17"]]},{"id":"da260a66.2e0fb","type":"debug","z":"e6126f89.fbab88","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","statusVal":"","statusType":"auto","x":900,"y":380,"wires":[]}]
@jean-luc1203
Copy link

I'm interested in your node, do you thing it's possible to start from a string, let's say QPIGS, convert it to hexa, which gives 5150494753 and then calculate the CRC16 on this hexa value, which makes B7A9, so a buffer in hexa of 5150494753B7A9 or in decimal for the node change [81,80,73,71,83,183,169,13] ?
Thanks for your answer

@nixator
Copy link
Author

nixator commented May 31, 2021

I'm interested in your node, do you thing it's possible to start from a string, let's say QPIGS, convert it to hexa, which gives 5150494753 and then calculate the CRC16 on this hexa value, which makes B7A9, so a buffer in hexa of 5150494753B7A9 or in decimal for the node change [81,80,73,71,83,183,169,13] ?
Thanks for your answer

Hi, I don't know, what is QPIGS.

@jean-luc1203
Copy link

QPIGS is a word an inverter can understand.
There are many others in the protocol used by these machines.
It must be sent by the Serial node of NR via the serial port in rs232.
But you have to calculate its CRC and add it to the end of the buffer.
For the moment, I have calculated this statically by hand. Is it possible to pass this QPIGS string or another ;-) to your CRC16-modbus function node so that this CRC is created on demand and not statically and therefore added at the end of the buffer (in my example the CRC gave B7A9)
Here is an example of what I need to be able to send in NR.

image

image

@SunvidWong
Copy link

SunvidWong commented Aug 3, 2021

The check code obtained is:2DC1 ,How can I get this result:2D C1 ?Thx!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment