2

I can send 4 bytes data to my javascript,

var data = new Uint8Array(data);

console.log('Data received: [ (data[0]) +', ' + (data[1]) +', ' + (data[2]) + ', ' + (data[3]) +  ']');

console.log('Data received: [ d2h(data[0]) +', ' + d2h(data[1]) +', ' + d2h(data[2]) + ', ' + d2h(data[3]) +  ']');

var hexvalue = ((d2h(data[4]) << 24) | (d2h(data[3]) << 16) | (d2h(data[2]) << 8) | d2h(data[1]));

value = parseFloat(hexvalue);
console.log(value);

In my LOG, I see this

LOG: Data received: [77, 249, 144, 66]
LOG: Data received: [4d, f9, 90, 42]
LOG: 710541312

I expected to get 72.49.. What did I do wrong?

5
  • 1
    parseFloat() is for parsing a string representation of a floating-point value. Also why does your log message show 6 values in the square brackets when you only have 4 in the code? Commented Feb 21, 2016 at 0:57
  • oh. the "ad" is a marker for an another Array. 0x4290f94d is 72.49. I thought d2h will convert decimal to hex in string format... I just took out the parseFloat(), I get the same 710541312 result... Commented Feb 21, 2016 at 1:01
  • without the a2h, I will get LOG: Data received: [50, 140, 147, 66]. The numbers are now in dec. Commented Feb 21, 2016 at 1:13
  • What is data before you start? NB: It is strange to see var there, when you already use it as argument. Commented Feb 21, 2016 at 1:18
  • The data came from a function: app.receivedData = function(data) { Commented Feb 21, 2016 at 2:42

1 Answer 1

2

This isn't a parsing problem, and there's no need to perform any hex conversions. Hex (like decimal) is just a representation. The values in your Uint8Array are already numbers.

To force those bytes to be interpreted as a 32-bit floating-point value, you just have to use the same buffer as the basis of a Float32Array instance:

var data = new Uint8Array(data);
var f32 = new Float32Array(data.buffer);
var f32value = f32[0];

edit — more explicitly:

var data = new Uint8Array(4);
data[0] = 0x4d;
data[1] = 0xf9;
data[2] = 0x90;
data[3] = 0x42;
var f32 = new Float32Array(data.buffer);
var f32value = f32[0];
console.log(f32value); // 72.4869155883789
Sign up to request clarification or add additional context in comments.

11 Comments

I tried to console.log(f32value) and got this error... LOG: [ERR] RangeError: ArrayBuffer length minus the byteOffset is not a multiple of the element size [hyper/063e2092-9377-44b0-b364-15116340f171/fa13c7fb-73a9-4a3f-8af6-04489f75eaf4/cordova.js: 314]
The code I posted works if the "data" buffer contains only the 4 bytes of the value (4290f94d). If you've got extra garbage in the data buffer then it won't work.
Yeah, I took out the first marker. var f32data = [data[4], data[3], data[2], data[1]]; var f32 = new Float32Array(f32data.buffer); var f32value = f32[0]; Can I do this?
No, you can't. In that example, f32data is a plain array, and that's radically different from a typed array.
var f32data = new Uint8Array(4); f32data[0] = d2h(data[1]); f32data[1] = d2h(data[2]); f32data[2] = d2h(data[3]); f32data[3] = d2h(data[4]); var f32 = new Float32Array(f32data.buffer); var f32value = f32[0]; console.log('Data received: [' + data[0] +', ' + d2h(data[1]) +', ' + d2h(data[2]) + ', ' + d2h(data[3]) + ', ' + d2h(data[4]) + ']'); console.log(f32value); LOG: Data received: [173, 42, 9c, f2, 8b] LOG: 5.885453550164232e-44
|

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.