最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

Reading signed 16 bit data in Javascript - Stack Overflow

programmeradmin4浏览0评论

I have been banging my head to solve this:

I received a raw data from an embeded device. From the documentation, the way to read it into a single value is:

Every two bytes of data can be bined to a single raw wave value.Its value is a signed 16-bit integer that ranges from -32768 to 32767. The first byte of the Value represents the high-order byte of the twos-pliment value, while the second byte represents the low-order byte. To reconstruct the full raw wave value, simply shift the first byte left by 8 bits, and bitwise-or with the second byte.

short raw = (Value[0]<<8) | Value[1];

One of the 2 bytes that I received is "ef". When I used the bitwise operation above the result does not seems right as I noticed I never get a single negative value (its ECG data, negative values are normal). I believe using Javascript to do this is not straight forward. The way I did it was like this:

var raw = "ef"; // just to show one. Actual one is an array of this 2 bytes but in string.
var value = raw.charAt(0) << 8 | raw.charAt(1)

Please Advice. Thanks!

EDIT:

I also did like this:

let first = new Int8Array(len); // len is the length of the raw data array
let second = new Int8Array(len);
let values = new Int16Array(len) // to hold the converted value

for(var i=0; i<len ; i++)
{
   //arr is the array that contains the every two "characters"
   first[i] = arr[i].charAt(0);
   second[i] = arr[i].charAt(1);
   values[i] = first[i] << 8 | second[i];  
}

But still all is positive result. no negative. Can someone verify if I am doing this correctly, just in case maybe the values are actually all positive :p

I have been banging my head to solve this:

I received a raw data from an embeded device. From the documentation, the way to read it into a single value is:

Every two bytes of data can be bined to a single raw wave value.Its value is a signed 16-bit integer that ranges from -32768 to 32767. The first byte of the Value represents the high-order byte of the twos-pliment value, while the second byte represents the low-order byte. To reconstruct the full raw wave value, simply shift the first byte left by 8 bits, and bitwise-or with the second byte.

short raw = (Value[0]<<8) | Value[1];

One of the 2 bytes that I received is "ef". When I used the bitwise operation above the result does not seems right as I noticed I never get a single negative value (its ECG data, negative values are normal). I believe using Javascript to do this is not straight forward. The way I did it was like this:

var raw = "ef"; // just to show one. Actual one is an array of this 2 bytes but in string.
var value = raw.charAt(0) << 8 | raw.charAt(1)

Please Advice. Thanks!

EDIT:

I also did like this:

let first = new Int8Array(len); // len is the length of the raw data array
let second = new Int8Array(len);
let values = new Int16Array(len) // to hold the converted value

for(var i=0; i<len ; i++)
{
   //arr is the array that contains the every two "characters"
   first[i] = arr[i].charAt(0);
   second[i] = arr[i].charAt(1);
   values[i] = first[i] << 8 | second[i];  
}

But still all is positive result. no negative. Can someone verify if I am doing this correctly, just in case maybe the values are actually all positive :p

Share Improve this question edited Sep 13, 2017 at 4:42 Binbo asked Sep 13, 2017 at 4:14 BinboBinbo 3003 silver badges18 bronze badges 12
  • Just to make things clear, do you know what value 'ef' is supposed to be ? If it is hexadecimal value, then 'ef' is one byte. – Pac0 Commented Sep 13, 2017 at 4:30
  • I mean, you are trying to mangle the first half of the only byte with the second half of the same byte. Doesn't seem what you are supposed to do here. – Pac0 Commented Sep 13, 2017 at 4:32
  • thats what the documentation lacking of. No idea whats the data type. So I assume that its not hex. – Binbo Commented Sep 13, 2017 at 4:35
  • 1 ef as you attempted to "decode" is 0110010101100110 which is positive ... all negative values would have "special" characters as the first of the pair (I mean, like À or È etc) but really, if that's a binary data stream, how is it being "converted" to a string? that's the important consideration – Jaromanda X Commented Sep 13, 2017 at 5:03
  • 1 charCodeAt is clearly more correct than charAt. – Jaromanda X Commented Sep 13, 2017 at 5:10
 |  Show 7 more ments

5 Answers 5

Reset to default 2

You can use property that the string is already 16 bit and then make it signed.
Also instead of reading 8bit at time just read one unsigned 16bit using charCodeAt.

var raw = "\u00ef"; //original example
var buf = new Int16Array(1);
buf[0] = raw.charCodeAt(0); //now in the buf[0] is typed 16 bit integer
//returns 239, for \uffef returns -17

var raw = "\uffef"; //original example
var buf = new Int16Array(1);
buf[0] = raw.charCodeAt(0); //now in the buf[0] is typed 16 bit integer
console.log(buf[0])
 

It's two's plement: Check the top bit of the high byte - byte[high]>>7. If it's 0, do byte[top]<<8 | byte[low]. If it is one, do -((byte[top]^0xff)<<8 | byte[low]^0xff) - 1. See https://en.wikipedia/wiki/Two%27s_plement for an explanation.

Also check out https://developer.mozilla/en-US/docs/Web/JavaScript/Typed_arrays. It has Int16 arrays which is what you want. It might be a ton faster.

For first byte take two's plement first then shift by 8 bit

let x = raw.charCodeAt(0); //ASCII value of first character

then flip x for 1's plement and add +1 for 2's plement and finally do

var value = x << 8 | bytevalueof(raw.charCodeAt(1))

This is a question about the raw wave data ing from a Neurosky Mindwave Mobile EEG headset.

You should find three values in the buffer when you read from the device. Perform this operation on the second two to get a correct reading:

    var b = reader.buffer(3);
    var raw = b[1]*256 + b[2];
    if(raw >= 32768) {
      raw = raw - 65536;
    }

Use TypedArray.from().

In your case the array is Int16Array. You will need to provide the optional mapFn argument and use charCodeAt to convert each 16-bit element to an unsigned number, which is then recast as a signed number by Int16Array.

var bytes = "\u0001\uffff";
var array = Int16Array.from(bytes, c => c.charCodeAt(0));

var bytes = "\u0001\uffff";
var array = Int16Array.from(bytes, c => c.charCodeAt(0));
console.log(array[0], array[1]);
// should output 1, -1
 

发布评论

评论列表(0)

  1. 暂无评论