# How to Decode 16 Bit signed Integer

**URL:** <https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112>\
**Category:** General\
**Created:** [18 February 2019 17:06 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112 "2019-02-18T17:06:38Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [18 February 2019 17:06 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/1 "2019-02-18T17:06:38Z")

</div>

Hi Guys, I working to get temperature from a smart thermometer and I need to decode bytes w/ 16 bit signed integer to ascii.  
somebody have a code or node that can decode that can share w/ me?

Could you see bellow the bytes from my flow:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/d/dedc994a62c9eaacb0e77c966540f3d81c90ec09.png)

the bytes 1C 17 stands for 30,95 as you can see below as get from protocol analyzer:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/5/56cf11fe213477b81e92b123e12fa2aad3cc5880.png)

thanks a lot  
Alex

---

<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:** [18 February 2019 17:37 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/2 "2019-02-18T17:37:01Z")

</div>

If you look carefully you will see that the values that represents 30.95 are 17 0c not 1c 17. Now 0x0c17 is 3095 decimal, so it appears the value is a sixteen bit integer in 1/100ths degree. So the first problem is that it appears you have not identified the right place in your buffer. Once you identify that then you need to convert it, I am not sure of the easiest way of doing that, hopefully someone will suggest the best method.

---

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [18 February 2019 18:31 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/3 "2019-02-18T18:31:54Z")

</div>

Hi Colin thanks you are right!  
But my buffer sent it in wrong position, as you can see in the log below:

 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/4/495c90767a72c5493745dec62f49593f1e05349b.png)

As the correctly value is 0x720b (29,30º) and not 0b72 (02 1b 72)!

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

I see that I have two challenges here 1st understanding wy the position ir wrong and 2st to decode 16bit signed integer to decimal/ascii.

Anybody have an idea to fix it?

Best Regards  
Alex

---

<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:** [18 February 2019 20:26 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/4 "2019-02-18T20:26:09Z")

</div>

I don't see any correlation between but payload buffer and the data from the protocol analyser.  
Once you work that out I think you can use `msg.payload.readInt16LE(offset)` to get it as an integer. It might be `BE` but I think it is `LE`.  
[https://www.w3schools.com/nodejs/ref\_buffer.asp](https://www.w3schools.com/nodejs/ref_buffer.asp)

---

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [19 February 2019 22:50 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/5 "2019-02-19T22:50:26Z")

</div>

Hi Colin, thanks!  
I already test the ReadIn16LE or BE and it´s not work! As you can see below:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/8/83f82d60689653ac85e9f32d62b0f4f23dc22124.png)

I included decode at Sliced according the code below:

![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/1/13ad54f1f565bed75744b14c66f682647de7a3a5.png)

I tried to include, part of bytes at position 29 or 30, on offset 29 or offset 29,32, but doesn´t work!

---

<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:** [20 February 2019 08:53 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/6 "2019-02-20T08:53:20Z")

</div>

`readInt16LE` only needs the start offset (it knows to pick up just two bytes). This simple example works for me. Try it and check it works for you then you could put the node.warn statements in for your offset in your code to see what is going wrong.

```auto
[{"id":"6f6689a6.6e9758","type":"debug","z":"514a90a5.c7bae8","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":630,"y":341,"wires":[]},{"id":"1e40f3d0.fa8e3c","type":"inject","z":"514a90a5.c7bae8","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":102.5,"y":340,"wires":[["c59edf46.f69bc"]]},{"id":"c59edf46.f69bc","type":"function","z":"514a90a5.c7bae8","name":"Create buffer","func":"msg.payload = new Buffer([0,0x72,0x0b,3,4])\nreturn msg;","outputs":1,"noerr":0,"x":275.5,"y":340,"wires":[["be665ce8.75a46"]]},{"id":"be665ce8.75a46","type":"function","z":"514a90a5.c7bae8","name":"Decode","func":"node.warn(\"Bytes are \" + msg.payload[1].toString(16) + \" \" + msg.payload[2].toString(16))\nmsg.payload = msg.payload.readInt16LE(1)\nreturn msg;","outputs":1,"noerr":0,"x":449.5,"y":341,"wires":[["6f6689a6.6e9758"]]}]

```

---

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [22 February 2019 23:26 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/7 "2019-02-22T23:26:25Z")

</div>

Hi Colin, thanks I got success partially.  
As you see in my first post, I have two bytes that represent temperature, but the 2st byte I need to decode to real byte because the serial transmission method (for ex. 02 1b represents 0x0b)

to extract a real byte, in the 2st temperature byte, I using the code below:

```auto
let a = msg.payload[30];
let temp2stByte = (a^0x10).toString(16).padStart(2,"0");

```

in the example below I have tried to using the temp2stByte,readInt16LE, but doesn´t work!

```auto
let a = msg.payload[30]; let temp2stByte = (a^0x10).toString(16).padStart(2,"0"); node.warn("Bytes are " + msg.payload[31].toString(16) + " " + temp2stByte )
msg.payload = msg.payload.readInt16LE(31) + **temp2stByte.readInt16LE** 
return msg;

```

Note: the 1st byte (msg.payload.readInt16LE(31)) is running well!  
Please, do you can advise me how to make a working around to fix the 2st Byte?

---

<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:** [23 February 2019 01:19 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/8 "2019-02-23T01:19:19Z")

</div>

> [@aargollo](#):
>
> Note: the 1st byte (msg.payload.readInt16LE(31)) is running well!  
> Please, do you can advise me how to make a working around to fix the 2st Byte?

Hi. You do realise that readInt16LE means read a 16 bit integer Little Endian and thus will read 2 bytes? (16 = 2x8 bits per byte).

If you experiment with the read functions you will figure this out.

Hint: there are read int, read float, 8 bit, 16 bit, 32 bit variations etc. Just check the documentation for nodejs buffer you'll figure it out & you'll learn/remember if you manage to do this yourself

Best of luck.

---

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [23 February 2019 10:19 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/9 "2019-02-23T10:19:06Z")

</div>

Hi Steve, You are right. But to read 16 bits I need before to convert the serial sequence bytes to real byte ( 0x02 0x10 0x1c -\> 0x0c) and after that I can read the 2 bytes (0x0c 0x17).

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

I had success to read line using offset (0x17) using msg.payload.readInt16LE(31) but the 2st byte i lost the offset reference, after I have used the code below:

```auto
let temp2stByte = (a^0x10).toString(16).padStart(2,"0"); 

```

if I using temp2stByte.readline(), but I have this error:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/0/0945499e35ec6ccc222cca68ab7863bc502ddbea.png)

I can´t find reference how to use readInt16LE in the 2 byte.  
Do you can advise me how to fix it?

---

<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:** [23 February 2019 15:00 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/10 "2019-02-23T15:00:38Z")

</div>

> [@aargollo](#):
>
> I can´t find reference how to use readInt16LE in the 2 byte.  
> Do you can advise me how to fix it?

not really sure where your going with this???

So, in an effort to put you on the right track I will try to explain what I think you are attempting to do.

If i'm not mistaken, the data you see in the payload is a [NodeJS Buffer](https://nodejs.org/api/buffer.html).

Looking at the decoded image you attached in your first message, the data is formatted like a protocol (I don't know what protocol) however, the picture gives some clues to the end part of the message.

Based on what I can see, you should really decode the whole msp.payload reply (since the parts of data before the "measured value" are probably important)

That said, the below should get you started....

**testcode...**

```javascript
//fake the msg.payload (simulate serial reply)
var msg = {};
msg.payload = new Buffer.from([0x40, 0x1, 0x2, 0x4, 0x4, 0x1, 0xa, 0xa6, 0x18, 0x7e, 0x1, 0x0, 0x0, 0x0, 0x29, 0x17, 0x0c]);

//decode the status record
var statusRecord = {};
statusRecord.attribute = msg.payload.readInt16LE(11);
statusRecord.success = msg.payload.readInt8(13);
statusRecord.dataType = msg.payload.readInt8(14);
statusRecord.measuredValue = msg.payload.readInt16LE(15);

//todo: Check the success flag is 0
//todo: Check dataType before calling the next buffer.readXXXX
// e.g if dataType is byte then call readInt8() to get measuredValue

if(statusRecord.success === 0){
    console.log(`Read was successful :)`);
    console.log(statusRecord);
    console.log(`Measured Value: ${statusRecord.measuredValue / 100.0} [*C]`);
} else {
    console.log(`Read was unsuccessful! :(`);
}

```

**output...**

```console
Read was successful :)
{ attribute: 0, success: 0, dataType: 41, measuredValue: 3095 }
Measured Value: 30.95 [*C]

```

You can play with it here \>\> [Compile and Execute C++0x Onlinej](http://tpcg.io/McQH1S)

Hope that helps

---

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [25 February 2019 11:13 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/11 "2019-02-25T11:13:48Z")

</div>

Hi Steve, firstly I would like to say thanks a lot!  
Your code is perfect, but as you see bellow the bytes that represent temperature in buffer array is [1c 17], this is happen because serial transition method that always to encode 0x0c on serial transmission represents 0x2 10 1c, according rules below:  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/1/1164a170378d9a185cb6cd284d648430cdfaf526.png)

In my first example (buffer bytes) I have: 29: 0x2, 30: 0x1c, 31: 0x17

To get temperature I´m using the array position at 30 (0x1c) and 30 (0x17)  
Before to convert bytes above in 16 bits LE, I need to get real byte at position 30, to have a real temperature measurement (0x0c 0x17) that corresponding 3095  
 ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/3/307de3d84a9a303467e9e691228f52ad954af558.png)

but I cant to use readInt16LE at position 30 before I have real byte (0x0c).  
To convert to real byte at position 30 (from 0x1c to 0x0c) I using this code:

```auto
let a = msg.payload[30];
let temp2stByte = (a^0x10).toString(16).padStart(2,"0");

```

After It I cant use readInt16LE in a real byte temperature 0x0c storage in the variable temp2stByte.  
That is my problem Steve!  
Do you can advise me how to fix it?

---

<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:** [26 February 2019 14:27 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/12 "2019-02-26T14:27:34Z")

</div>

Hello again @aargollo

I am guessing english is not your 1st language & that may be the reason for some confusion here.

At first you say "working to **get** temperature from a smart thermometer"  
Then you say "But **my buffer**  **sent** it in wrong position, as you can see in the log below"

It is my guess that you need to read values from a `Buffer` object that arrives in `msg.payload`

And only now you post a relevant piece of the puzzle...

> [@aargollo](#):
>
> x2 10 1c, according rules below:  
> ![image](https://us1.discourse-cdn.com/flex026/uploads/nodered/original/2X/1/1164a170378d9a185cb6cd284d648430cdfaf526.png)
> 
> In my first example (buffer bytes) I have: 29: 0x2, 30: 0x1c, 31: 0x17

it is my suspicion, the protocol is fully documented & its where where you got that piece ☝ of info is from.

OK, so I will invent/guess the 1st 28 bytes of your reply and I will attempt to show you something that _SHOULD_ get you moving towards a solution.

**IMPORTANT**  
Many assumptions have been made! As I don't have the full protocol specification, many assumptions have been made. The below code is an attempt to help you help yourself...  
I strongly recommend you understand what all the other values mean. For example, I am certain byte[0] (0x1) is SOH and the last byte (0x3) is ETX [REF](https://www.cs.cmu.edu/~pattis/15-1XX/common/handouts/ascii.html). Many of the other BYTEs and INTs in the Buffer **will** be relevant but since I dont have that information, I will work backwards from the last byte as your examples indicate the temperature is in the last 2 bytes (minus the ETX)

**Playtime (guesswork)...**

```javascript
//fake the msg.payload (simulate serial reply)
var msg = {};
/* 0 1 2 3 4 5 6 7 8 9 */
var serialData = [ 0x01, 0x81, 0x02, 0x12, 0x02, 0x10, 0x02, 0x1f, 0xde, 0x92,
                  0xd5, 0x72, 0x02, 0x1a, 0x02, 0x14, 0x02, 0x12, 0x02, 0x10,
                  0x02, 0x10, 0x02, 0x10, 0x29, 0x02, 0x10, 0x02, 0x12, 0x02,
                  0x1b, 0x72, 0x39, 0x3]
msg.payload = new Buffer.from(serialData);

//Loop through and decode any encoded values...
var decodeNext = false;
var decodedData = [];
for (var i = 0; i < msg.payload.length; i++) {
  //get this byte
  let b = msg.payload[i];
  //if last was 0x2, deduct 0x10 and store it
  if (decodeNext && b >= 0x10) {
    decodedData.push(b - 0x10);
    decodeNext = false;//reset flag
    continue;//next loop
  }
  if (b === 0x2) {
    decodeNext = true;//set flag & continue (dont store this one)
    continue;//next loop
  }
  //if we reach here - simply store it
  decodedData.push(b);
}
console.log(decodedData);

//make a buffer from new decoded data (not necessary but the read functions work nicely)
var decodedBuffer = new Buffer.from(decodedData);

//decode the status record
var statusRecord = {};
var lastByte = decodedBuffer.length - 1;
statusRecord.attribute = decodedBuffer.readInt16BE(lastByte - 7);
statusRecord.success = decodedBuffer.readInt8(lastByte - 5);
statusRecord.dataType = decodedBuffer.readInt8(lastByte - 4);
statusRecord.measuredValue = decodedBuffer.readInt16BE(lastByte - 3);

//todo: Check the success flag is 0
//todo: Check dataType before calling the next buffer.readXXXX
// e.g if dataType is byte then call readInt8() to get measuredValue

if (statusRecord.success === 0) {
  console.log(`Read was successful :)`);
  console.log(statusRecord);
  console.log(`Measured Value: ${statusRecord.measuredValue / 100.0} [°C]`);
} else {
  console.log(`Read was unsuccessful! :(`);
}

```

**output...**

```auto
[1, 129, 2, 0, 15, 222, 146, 213, 114, 10, 4, 2, 0, 0, 0, 41, 0, 2, 11, 114, 57, 3]
Read was successful :) 
{attribute: 41, success: 0, dataType: 2, measuredValue: 2930}
Measured Value: 29.3 [°C] 

```

play with it here...  
[![Edit decoding guesswork](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/81y48yqp8j?expanddevtools=1&fontsize=14)

---

<div class="post-metadata">

**Author:** ![aargollo](https://avatars.discourse-cdn.com/v4/letter/a/58f4c7/32.png) [@aargollo](https://discourse.nodered.org/u/aargollo)\
**Post date:** [27 February 2019 10:34 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/13 "2019-02-27T10:34:07Z")

</div>

Hi Steve, sorry for my mistake in describing the challenge!  
Thanks a lot your code is wonderful!!!!

Your are the best!!!!

Best Regards,  
Alex

---

<div class="post-metadata">

**Author:** ![farcry](https://avatars.discourse-cdn.com/v4/letter/f/9de053/32.png) [@farcry](https://discourse.nodered.org/u/farcry)\
**Post date:** [23 April 2020 13:27 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/14 "2020-04-23T13:27:09Z")

</div>

I've got error:  
TypeError: msg.payload.readInt16LE is not a function

---

<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:** [23 April 2020 13:46 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/15 "2020-04-23T13:46:02Z")

</div>

@farcry this thread is very old. Please start a new thread and detail what exactly is your issue. Include screenshots and debug output messages to assist us.

Thread closed

---

<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:** [23 April 2020 13:46 UTC](https://discourse.nodered.org/t/how-to-decode-16-bit-signed-integer/8112/16 "2020-04-23T13:46:08Z")

</div>


