# ASCII Convert Control Character

**URL:** <https://discourse.nodered.org/t/ascii-convert-control-character/26140>\
**Category:** General\
**Created:** [5 May 2020 16:56 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140 "2020-05-05T16:56:19Z")\
**Posts on this page:** 10\
**Page:** 1

<div class="post-metadata">

**Author:** ![New2Node](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@New2Node](https://discourse.nodered.org/u/New2Node)\
**Post date:** [5 May 2020 16:56 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/1 "2020-05-05T16:56:19Z")

</div>

Hi,  
I'm unable to decode a message from a serial device, if send buffer  
[2,69,12,202,170,194,66,192,100,232,255,255,75,70,225,9,181,20,159,51,174,82,69,65,68,69,82,0,112,153,3]  
I can see the raw data (Ascii) shows EÊªÂBÀdèÿÿKFá µ3®READERp

Now ["0x02"] is a Control Character (STX), however Node-Red shows it as   
I'm new to Node-Red so I'm trying to decode the message so it makes sense!

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [5 May 2020 17:47 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/2 "2020-05-05T17:47:56Z")

</div>

What is the device you're getting data from? That looks like there may be a protocol & perhaps a CRC at the end just before the ETX.

---

<div class="post-metadata">

**Author:** ![New2Node](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@New2Node](https://discourse.nodered.org/u/New2Node)\
**Post date:** [5 May 2020 18:21 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/3 "2020-05-05T18:21:47Z")

</div>

It’s an Electricity meter, it uses “Command line protocol“  
Chapter 4 Link =

[http://read.pudn.com/downloads156/doc/694628/JSGF/（英文）红相%20MK6表计规约EDMI%20MK6电表详细规约.pdf](http://read.pudn.com/downloads156/doc/694628/JSGF/%EF%BC%88%E8%8B%B1%E6%96%87%EF%BC%89%E7%BA%A2%E7%9B%B8%20MK6%E8%A1%A8%E8%AE%A1%E8%A7%84%E7%BA%A6EDMI%20MK6%E7%94%B5%E8%A1%A8%E8%AF%A6%E7%BB%86%E8%A7%84%E7%BA%A6.pdf)

Yes I believe there’s a CRC, if I want to send:

LBASIL,BRUSH\<0\>

How do I decode the return messages so it makes sense? I’m sure I have the answers in Chapter 4, just need some direction on Node-Red 🙂

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [5 May 2020 18:33 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/4 "2020-05-05T18:33:41Z")

</div>

Chapter 4-1 shows you need to send

`<STX><command><CRC><ETX> `

`<CRC>` is  
a 16 bit CRC-16 polynomial checksum defined by the CCITT standard, calculated over  
the entire message including the STX but not the CRC itself or the ETX character.

The meter replies to commands with a response message in the following format.  
`<STX><response><CRC><ETX>`

So, you need to wrap you command as stated above. The serial node can be set to send on ETX - do you know how to do that.

Additionally, you're gonna have to calculate the CRC. There is a calculation on page B-1

But...

There may be an easier way. There is a MODBUS Mode on page 3-40. If you are in a position to change to modbus mode, then there are modbus nodes available that will hugely simplify accessing the device registers.

---

<div class="post-metadata">

**Author:** ![New2Node](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@New2Node](https://discourse.nodered.org/u/New2Node)\
**Post date:** [5 May 2020 18:58 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/5 "2020-05-05T18:58:16Z")

</div>

Unfortunately this meter doesn’t support Modbus ☹

I have the meter software which I use to configure it, so I can monitor the data which is sent from the software to the meter.

For example if send the command

```auto
<STX>E(MeterNumber)(1)(1)LREADER,READER[00][C70A]<ETX>

```

I get:

```auto

<STX>E(1)(MeterNumber)(1)<ACK>[155C]<ETX>

```

So I can see it’s accepted, however if I try replicate this string using Node-Red I see:

```auto

EÊªÂBÀdèÿÿKFá	µ3®READERp

```

[2,69,12,202,170,194,66,192,100,232,255,255,75,70,225,9,181,20,159,51,174,82,69,65,68,69,82,0,112,153,3]

And the response:

```auto
EBÀdèÊªÂÿÿK-ÊÊªÂq 

```

[2,69,66,192,100,232,12,202,170,194,255,255,75,45,202,146,159,12,202,170,194,113,160,3]

I'm sure its accepted, can’t decode the response from the meter.

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [5 May 2020 19:18 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/6 "2020-05-05T19:18:57Z")

</div>

Shame about the modbus option.

All I can say is you're lucky to have an extensive manual, you're gonna have to throw test data at it and decipher the response.

All I can suggest to maybe simplify this is, if you only have one device, then avoid the extended call (like in your example above) - instead try to get the simpler "read register" command (pg 4-4) working

Luckily, there is a C example on pg B-4 You can easily translate to js for calculating the CRC. The code should also give you a clue as to how to format your requests.

---

<div class="post-metadata">

**Author:** ![New2Node](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@New2Node](https://discourse.nodered.org/u/New2Node)\
**Post date:** [10 May 2020 11:41 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/7 "2020-05-10T11:41:18Z")

</div>

Hi Steve, do you know any good online calculators for 16 bit CRC?

The example in the book is:

```auto

[02]R[F0][02]

```

The calculated CRC =

```auto

EE45

```

Can’t seem to find anything online which outputs the same CRC

---

<div class="post-metadata">

**Author:** ![Steve-Mcl](https://sea2.discourse-cdn.com/flex026/user_avatar/discourse.nodered.org/steve-mcl/32/4826_2.png) [@Steve-Mcl](https://discourse.nodered.org/u/Steve-Mcl)\
**Post date:** [10 May 2020 12:24 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/8 "2020-05-10T12:24:28Z")

</div>

CRC can be vendor specific (meaning CRC is not always calculated the same)

All the information to calculate the CRC is there in the manual.

You are lucky i was bored though 😉

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/3X/8/6/86c4196256226044ad731d5d568e683790c891d4.png)

function code...

```auto
const ccitt_16 = [
    0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,
    0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,
    0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,
    0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,
    0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,
    0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,
    0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,
    0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,
    0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,
    0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,
    0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,
    0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,
    0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,
    0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,
    0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,
    0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,
    0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,
    0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,
    0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,
    0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,
    0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,
    0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
    0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,
    0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,
    0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,
    0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,
    0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,
    0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,
    0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,
    0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,
    0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,
    0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0
];
function Hi(word){
    return (word >> 8) 
}
function Lo(word){
    return (word & 0x00ff) 
}
function CalculateCharacterCRC16(crc, byte){
    let shifted8_int16 = ((crc << 8) & 0xffff);
    let b = (Hi(crc) ^ byte);
    let newCRC = (shifted8_int16 ^ ccitt_16[b]);
    return newCRC;
}

var data = msg.payload;
var crc = 0;
for (let i=0; i < data.length; i++) {
    crc = CalculateCharacterCRC16(crc, data[i]);
} 
msg.crc = crc;
return msg;

```

Test flow...

```auto
[{"id":"7961163b.59a198","type":"function","z":"6ef1cfb5.30ff2","name":"calculate CRC","func":"const ccitt_16 = [\n 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50A5, 0x60C6, 0x70E7,\n 0x8108, 0x9129, 0xA14A, 0xB16B, 0xC18C, 0xD1AD, 0xE1CE, 0xF1EF,\n 0x1231, 0x0210, 0x3273, 0x2252, 0x52B5, 0x4294, 0x72F7, 0x62D6,\n 0x9339, 0x8318, 0xB37B, 0xA35A, 0xD3BD, 0xC39C, 0xF3FF, 0xE3DE,\n 0x2462, 0x3443, 0x0420, 0x1401, 0x64E6, 0x74C7, 0x44A4, 0x5485,\n 0xA56A, 0xB54B, 0x8528, 0x9509, 0xE5EE, 0xF5CF, 0xC5AC, 0xD58D,\n 0x3653, 0x2672, 0x1611, 0x0630, 0x76D7, 0x66F6, 0x5695, 0x46B4,\n 0xB75B, 0xA77A, 0x9719, 0x8738, 0xF7DF, 0xE7FE, 0xD79D, 0xC7BC,\n 0x48C4, 0x58E5, 0x6886, 0x78A7, 0x0840, 0x1861, 0x2802, 0x3823,\n 0xC9CC, 0xD9ED, 0xE98E, 0xF9AF, 0x8948, 0x9969, 0xA90A, 0xB92B,\n 0x5AF5, 0x4AD4, 0x7AB7, 0x6A96, 0x1A71, 0x0A50, 0x3A33, 0x2A12,\n 0xDBFD, 0xCBDC, 0xFBBF, 0xEB9E, 0x9B79, 0x8B58, 0xBB3B, 0xAB1A,\n 0x6CA6, 0x7C87, 0x4CE4, 0x5CC5, 0x2C22, 0x3C03, 0x0C60, 0x1C41,\n 0xEDAE, 0xFD8F, 0xCDEC, 0xDDCD, 0xAD2A, 0xBD0B, 0x8D68, 0x9D49,\n 0x7E97, 0x6EB6, 0x5ED5, 0x4EF4, 0x3E13, 0x2E32, 0x1E51, 0x0E70,\n 0xFF9F, 0xEFBE, 0xDFDD, 0xCFFC, 0xBF1B, 0xAF3A, 0x9F59, 0x8F78,\n 0x9188, 0x81A9, 0xB1CA, 0xA1EB, 0xD10C, 0xC12D, 0xF14E, 0xE16F,\n 0x1080, 0x00A1, 0x30C2, 0x20E3, 0x5004, 0x4025, 0x7046, 0x6067,\n 0x83B9, 0x9398, 0xA3FB, 0xB3DA, 0xC33D, 0xD31C, 0xE37F, 0xF35E,\n 0x02B1, 0x1290, 0x22F3, 0x32D2, 0x4235, 0x5214, 0x6277, 0x7256,\n 0xB5EA, 0xA5CB, 0x95A8, 0x8589, 0xF56E, 0xE54F, 0xD52C, 0xC50D,\n 0x34E2, 0x24C3, 0x14A0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,\n 0xA7DB, 0xB7FA, 0x8799, 0x97B8, 0xE75F, 0xF77E, 0xC71D, 0xD73C,\n 0x26D3, 0x36F2, 0x0691, 0x16B0, 0x6657, 0x7676, 0x4615, 0x5634,\n 0xD94C, 0xC96D, 0xF90E, 0xE92F, 0x99C8, 0x89E9, 0xB98A, 0xA9AB,\n 0x5844, 0x4865, 0x7806, 0x6827, 0x18C0, 0x08E1, 0x3882, 0x28A3,\n 0xCB7D, 0xDB5C, 0xEB3F, 0xFB1E, 0x8BF9, 0x9BD8, 0xABBB, 0xBB9A,\n 0x4A75, 0x5A54, 0x6A37, 0x7A16, 0x0AF1, 0x1AD0, 0x2AB3, 0x3A92,\n 0xFD2E, 0xED0F, 0xDD6C, 0xCD4D, 0xBDAA, 0xAD8B, 0x9DE8, 0x8DC9,\n 0x7C26, 0x6C07, 0x5C64, 0x4C45, 0x3CA2, 0x2C83, 0x1CE0, 0x0CC1,\n 0xEF1F, 0xFF3E, 0xCF5D, 0xDF7C, 0xAF9B, 0xBFBA, 0x8FD9, 0x9FF8,\n 0x6E17, 0x7E36, 0x4E55, 0x5E74, 0x2E93, 0x3EB2, 0x0ED1, 0x1EF0\n];\nfunction Hi(word){\n return (word >> 8) \n}\nfunction Lo(word){\n return (word & 0x00ff) \n}\nfunction CalculateCharacterCRC16(crc, byte){\n let shifted8_int16 = ((crc << 8) & 0xffff);\n let b = (Hi(crc) ^ byte);\n let newCRC = (shifted8_int16 ^ ccitt_16[b]);\n return newCRC;\n}\n\nvar data = msg.payload;\nvar crc = 0;\nfor (let i=0; i < data.length; i++) {\n crc = CalculateCharacterCRC16(crc, data[i]);\n} \nmsg.crc = crc;\nreturn msg;","outputs":1,"noerr":0,"x":820,"y":160,"wires":[["50de6eb4.f6461"]]},{"id":"1750ec24.337374","type":"inject","z":"6ef1cfb5.30ff2","name":"0x2, \"R\", 0xF0, 0x2","topic":"","payload":"[2,82,240,2]","payloadType":"bin","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":790,"y":80,"wires":[["7961163b.59a198"]]},{"id":"50de6eb4.f6461","type":"debug","z":"6ef1cfb5.30ff2","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","x":850,"y":240,"wires":[]}]

```

---

<div class="post-metadata">

**Author:** ![New2Node](https://avatars.discourse-cdn.com/v4/letter/n/f1d935/32.png) [@New2Node](https://discourse.nodered.org/u/New2Node)\
**Post date:** [10 May 2020 12:59 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/9 "2020-05-10T12:59:16Z")

</div>

Legend!!! Thanks for your expertise!!! 😁

---

<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:** [24 May 2020 12:59 UTC](https://discourse.nodered.org/t/ascii-convert-control-character/26140/10 "2020-05-24T12:59:20Z")

</div>

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