0

Background: I'm using node.js to get the volume setting from a device via serial connection. I need to obtain this data as an integer value.

I have the data in a buffer ('buf'), and am using readInt16BE() to convert to an int, as follows:

console.log( buf )
console.log( buf.readInt16BE(0) )

Which gives me the following output as I adjust the external device:

<Buffer 00 7e>
126
<Buffer 00 7f>
127
<Buffer 01 00>
256
<Buffer 01 01>
257
<Buffer 01 02>
258

Problem: All looks well until we reach 127, then we take a jump to 256. Maybe it's something to do with signed and unsigned integers - I don't know!

Unfortunately I have very limited documentation about the external device, I'm having to reverse engineer it! Is it possible it only sends a 7-bit value? Hopefully there is a way around this?

Regarding a solution - I must also be able to convert back from int to this format!

Question: How can I create a sequential range of integers when 7F seems to be the largest value my device sends, which causes a big jump in my integer scale?

Thanks :)

1
  • Does it make sense for your device to return a negative number? It does look like the device is using that bit as a sign, in which case reading the buffer as a 16 bit value is incorrect. Commented Jan 24, 2016 at 12:47

2 Answers 2

1

127 is the maximum value of a signed 8-bit integer. If the integer is overflowing into the next byte at 128 it would be safe to assume you are not being sent a 16 bit value, but rather 2 signed 8-bit values, and reading the value as a 16-bit integer would be incorrect.

I would start by using the first byte as a multiplier of 128 and add the second byte, this will give the series you are seeking.

buf = Buffer([0,127]) //<Buffer 00 7f>
buf.readInt8(0) * 128 + buf.readInt8(1)
>127

buf = Buffer([1,0]) //<Buffer 01 00>
buf.readInt8(0) * 128 + buf.readInt8(1)
>128

buf = Buffer([1,1]) //<Buffer 01 01>
buf.readInt8(0) * 128 + buf.readInt8(1)
>129 

The way to get back is to divide by 128, round it down to the nearest integer for the first byte, and the second byte contains the remainder.

i = 129
buf = Buffer([Math.floor(i / 128), i % 128])
<Buffer 01 01>
Sign up to request clarification or add additional context in comments.

2 Comments

Thanks so much - This perfectly solved the issue for me. Is there a way to do the same in reverse, so 132 == 0x00 and 0x04 ?
I see you got it sorted, I edited my post when I had more time to be more clear. Good to see you got it going :)
0

Needed to treat the data as two signed 8-bit values. As per @forrestj the solution is to do:

valueInt = buf.readInt8(0) * 128 + buf.readInt8(1)

We can also convert the int value into the original format by doing the following:

byte1 = Math.floor(valueInt / 128)
byte2 = valueInt % 128

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.