# Payload Format / Decode for TM-901 / N1C2 sensor from KCS TraceME

**URL:** <https://www.thethingsnetwork.org/forum/t/payload-format-decode-for-tm-901-n1c2-sensor-from-kcs-traceme/36313>\
**Category:** End Devices (Nodes)\
**Created:** [April 20, 2020, 1:57pm UTC](https://www.thethingsnetwork.org/forum/t/payload-format-decode-for-tm-901-n1c2-sensor-from-kcs-traceme/36313 "2020-04-20T13:57:30Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![arjanvanb](https://www.thethingsnetwork.org/forum/user_avatar/www.thethingsnetwork.org/arjanvanb/32/46626_2.png) [@arjanvanb](https://www.thethingsnetwork.org/forum/u/arjanvanb)\
**Post date:** [April 21, 2020, 11:06am UTC](https://www.thethingsnetwork.org/forum/t/payload-format-decode-for-tm-901-n1c2-sensor-from-kcs-traceme/36313/4 "2020-04-21T11:06:32Z")

</div>

> [@datasharkNL](#):
>
> Is the example of you valid to use?

We cannot tell. What’s the source of your quoted explanation above? Where did you find the indexes such as `bytes[19]`? (For future readers, please also provide the device brand and type.)

If the quote is taken from documentation for your sensor, and if you’ve got the byte indexes correct, and if the values are sent [MSB first](https://en.wikipedia.org/wiki/Bit_numbering#Most_significant_byte), and if the values are sent as signed integer numbers, and if they don’t need to be divided by some factor to get decimal numbers, then: yes. But we cannot tell from the information you’re providing.

Looking at the example payload (for which we still don’t know the expected values either!), it seems that `byte[19]` is (hexadecimal) 0xFF, and so is `byte[20]`. (Beware that JavaScript starts counting from zero, not from one, just like many programming languages do as well.) That’s _probably_ not a valid reading for `compass_x`?

It’s crucial you understand the shifting. Let’s decipher the next two bytes, those for `compass_y`: FD and 09, when displayed in the human readable hexadecimal notation. In binary notation, those are the bit sequences 11111101 and 00001001.

- A [left shift](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Left_shift) of 8 bits in `11111101 << 8` yields `11111101 00000000` (or, as it’s actually always 32 bits in JavaScript: `00000000 00000000 11111101 00000000`).
- Next, a [bitwise OR](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Bitwise_XOR) in `11111101 00000000 | 00001001` yields `11111101 00001001`.

Please follow the links above and read the documentation.

As we’re shifting 8 bits (which is a full byte) at a time, the above is much easier to read in hexadecimal:

- For the byte `FD`, the shifting `FD << 8` yields `00 00 FD 00`.
- Next, `00 00 FD 00 | 09` yields `00 00 FD 09`.

When doing bitwise operations, [JavaScript will interpret its operands as 32-bits signed integers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#Signed_32-bit_integers), so will interpret the above `00 00 FD 09` as [a large positive number, 64.777](https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=0000FD09). Instead, if it can indeed be negative, you’ll need the sign extension that I linked to above. That would result in:

- `FD << 24` yields `FD 00 00 00`.
- Next, `FD 00 00 00 >> 16` yields `FF FF FD 00` ([sign-propagating right shift](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Bitwise_Operators#%3E%3E_Sign-propagating_right_shift)).
- Next, `FF FF FD 00 | 09` yields `FF FF FD 09`, [which is a small negative number, -759](https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=FFFFFD09).

Note that the above applies to bitwise operators in JavaScript, as used in a TTN Console payload format. Other programming languages are unlikely to always assume 32-bits signed integers for bitwise operators.

Now, applying the above to `byte[19]` and `byte[20]` one would get 0xFFFFFFFF for `compass_x`, [which is _exactly_ -1](https://www.rapidtables.com/convert/number/hex-to-decimal.html?x=FFFFFFFF). That might be correct, but I cannot tell. Finally, for `compass_z` you would get 0x00000007 (here, no sign propagating applies).

Finally, even with the above shifting and sign extension, `Math.atan2(0xFFFFFD09, 0xFFFFFFFF) * 180 / Math.Pi` will still give you [`NaN`, Not-a-Number](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/NaN). So, JavaScript cannot do that math given these values. Maybe those are edge cases, maybe the formula is wrong, maybe you’re looking at the wrong bytes.

If those are expected edge cases, then you could use the following to suppress the `NaN` which TTN does not like:

```javascript
return {
  ...,
  heading: isNaN(heading) ? null : heading,
  ...
}

```

That’s the ternary operator already mentioned in [Decrypting messages for dummies - #4 by arjanvanb](https://www.thethingsnetwork.org/forum/t/decrypting-messages-for-dummies/4894/4) as well.

In your case, the formula is wrong. Debugging will show that `Math.atan2(-759, -1) * 180` yields -282.98 just fine. However, `Math.Pi` is `undefined`, and `-282.98 / undefined` is NaN. You’ll need the uppercase `Math.PI` instead. (And you still might want to check all of the above.)

Bonus, to limit the number of decimals, use:

```javascript
// Unary plus operator to cast string result of toFixed to number
heading: isNaN(heading) ? null : +heading.toFixed(1)

```

---

_[View the full topic](https://www.thethingsnetwork.org/forum/t/payload-format-decode-for-tm-901-n1c2-sensor-from-kcs-traceme/36313)._
