[update]Need help with CRC16

Hi all

Again I need your help :crazy_face:

I need to establish communication with some strange device, all I know that is communicating by TCP protocol. I already know that device react on this string: "GET 02210100F101D9D9\n"
It responds: "RSP 0E02210100F10101E83B\n"

BUT, command "GET" is used when you want to ask for some data. Command "RSP" is send back from device with data you wanted to ask.

And this is fine :slight_smile:
The problem is when I want to set data in device. Then I must to send this: "SET 02210100F101022B4A\n".

There is starting the most important part of fun :wink:
4 last characters in SET command are the CRC code (in GET and RSP also). In this case there is "2B4A". In "SET" request the most important part are two digits before CRC part.

I using this page to calculate CRC in different cases. On this website I had to select CRC width as CRC-16, CRC parametrization as CRC16_MODBUS and CRC Input Data as String. When I copied "SET 02210100F10102" this page calculate appriopriate CRC code (which is 2B4A).

I've already read some of threads, but none of them provided an answer to my problem. Particularly interesting was the thread on the use of XMODEM method, but it's not working properly with my data...

I hope I have described my problem in sufficient detail. Thanks in advance for your help

:slight_smile:

There are some examples for testing:
GET 0221010F2201, CRC should be E2FB
GET 022101008001, CRC should be 3190
SET 02210100F10101, CRC should be 2A0A
SET 02210100F10100, CRC should be EACB

Adapted from here: Modbus crc16 calculation function error syntax - #6 by Steve-Mcl

Function...

 function crc16(str) {
    const buf = Buffer.from(str)
    let crc = 0xFFFF;
    for (let i = 0; i < buf.length; i++) {
        crc = crc ^ buf[i];
        for (let j = 0; j < 8; j++) {
            const temp = crc & 0x01;
            crc >>= 0x01;
            if (temp == 0x01) {
                crc ^= 0xA001;
            }
        }
    }
    return crc;
}

Proof...
image

1 Like

Thanks for your help.

As always something must be wrong with me :stuck_out_tongue:
It looks like CRC is mixed and it mess up whole communication :upside_down_face:

Screenshot for proof

[
    {
        "id": "f38b5335daffe055",
        "type": "tab",
        "label": "CRC",
        "disabled": false,
        "info": "",
        "env": []
    },
    {
        "id": "dc764c435b2997a6",
        "type": "function",
        "z": "f38b5335daffe055",
        "name": "function 1",
        "func": "function crc16(str) {\n    const buf = Buffer.from(str)\n    let crc = 0xFFFF;\n    for (let i = 0; i < buf.length; i++) {\n        crc = crc ^ buf[i];\n        for (let j = 0; j < 8; j++) {\n            const temp = crc & 0x01;\n            crc >>= 0x01;\n            if (temp == 0x01) {\n                crc ^= 0xA001;\n            }\n        }\n    }\n    return crc;\n}\n\nconst crc = crc16(msg.payload)\nconst arr = crc.toString(16).toUpperCase().substring(-4).split(\"\")\nmsg.payload = msg.payload + arr.splice(-2).concat(arr).join(\"\");\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "initialize": "",
        "finalize": "",
        "libs": [],
        "x": 720,
        "y": 260,
        "wires": [
            [
                "b2a0bf11961ef871"
            ]
        ]
    },
    {
        "id": "9487dfaaa461bdfa",
        "type": "inject",
        "z": "f38b5335daffe055",
        "name": "",
        "props": [
            {
                "p": "payload"
            }
        ],
        "repeat": "",
        "crontab": "",
        "once": false,
        "onceDelay": 0.1,
        "topic": "",
        "payload": "SET 02210100F10100",
        "payloadType": "str",
        "x": 400,
        "y": 260,
        "wires": [
            [
                "dc764c435b2997a6"
            ]
        ]
    },
    {
        "id": "b2a0bf11961ef871",
        "type": "debug",
        "z": "f38b5335daffe055",
        "name": "debug 1",
        "active": true,
        "tosidebar": true,
        "console": false,
        "tostatus": false,
        "complete": "false",
        "statusVal": "",
        "statusType": "auto",
        "x": 980,
        "y": 260,
        "wires": []
    }
]

CRC should be EACB

Okay, I've tried myself to fix this and finally it works!

I do not know why, but it was enough to put a dot in line 18 after split, like:

const arr = crc.toString(16).toUpperCase().substring(-4).split(".")

So all function looks that:

function crc16(str) {
    const buf = Buffer.from(str)
    let crc = 0xFFFF;
    for (let i = 0; i < buf.length; i++) {
        crc = crc ^ buf[i];
        for (let j = 0; j < 8; j++) {
            const temp = crc & 0x01;
            crc >>= 0x01;
            if (temp == 0x01) {
                crc ^= 0xA001;
            }
        }
    }
    return crc;
}

const crc = crc16(msg.payload)
const arr = crc.toString(16).toUpperCase().substring(-4).split(".")
msg.payload = msg.payload + arr.splice(-2).concat(arr).join("") + "\n";


return msg;

And it works well for me! :grinning:

Thanks @Steve-Mcl for your help ! :slight_smile:

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