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" is0110010101100110
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
5 Answers
Reset to default 2You 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