gef
gef

Reputation: 13

Converting hex values in buffer to integer

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 :)

Upvotes: 0

Views: 6062

Answers (2)

forrestj
forrestj

Reputation: 777

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>

Upvotes: 1

gef
gef

Reputation: 13

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

Upvotes: 0

Related Questions