【问题标题】:Reading signed 16 bit data in Javascript在 Javascript 中读取带符号的 16 位数据
【发布时间】:2020-11-03 10:42:27
【问题描述】:

我一直在努力解决这个问题:

我收到了来自嵌入式设备的原始数据。从文档来看,将其读入单个值的方法是:

每两个字节的数据可以组合成一个原始波形值。它的值是一个有符号的16位整数,范围从-32768到32767。Value的第一个字节代表二进制的高位字节-compliment 值,而第二个字节表示低位字节。要重建完整的原始波形值,只需将第一个字节左移 8 位,然后按位或 第二个字节。

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

我收到的 2 个字节之一是“ef”。当我使用上面的按位运算时,结果似乎不正确,因为我注意到我从来没有得到一个负值(它的 ECG 数据,负值是正常的)。我相信使用 Javascript 来做到这一点并不简单。 我的做法是这样的:

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)

请指教。谢谢!

编辑:

我也是这样做的:

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];  
}

但仍然是积极的结果。没有负面的。有人可以验证我是否正确执行此操作,以防万一这些值实际上都是正数:p

【问题讨论】:

  • 为了清楚起见,你知道'ef'应该是什么值吗?如果是十六进制值,那么'ef'是一个字节。
  • 我的意思是,您正试图将唯一字节的前半部分与同一字节的后半部分混淆。这似乎不是你应该在这里做的。
  • 这就是文档所缺少的。不知道数据类型是什么。所以我认为它不是十六进制的。
  • ef 当您尝试“解码”时是 0110010101100110 这是正数...所有负值都将具有“特殊”字符作为对中的第一个(我的意思是,像 @987654326 @ 或 È 等)但实际上,如果这是一个二进制数据流,它是如何“转换”为字符串的?这是重要的考虑因素
  • charCodeAt 显然比 charAt 更正确。

标签: javascript


【解决方案1】:

补码:检查高字节的最高位-byte[high]>>7。如果为 0,则执行 byte[top]https://en.wikipedia.org/wiki/Two%27s_complement 以获得解释。

还可以查看https://developer.mozilla.org/en-US/docs/Web/JavaScript/Typed_arrays。它有你想要的 Int16 数组。它可能会快一吨。

【讨论】:

    【解决方案2】:

    您可以使用字符串已经是 16 位的属性,然后对其进行签名。
    也不是一次读取 8 位,而是使用 charCodeAt 读取一个无符号的 16 位。

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

    【讨论】:

      【解决方案3】:

      对于第一个字节,先取二进制补码,然后移位 8 位

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

      然后翻转 x 为 1 的补码并添加 +1 为 2 的补码,最后这样做

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

      【讨论】:

        【解决方案4】:

        这是一个关于raw wave data coming from a Neurosky Mindwave Mobile EEG headset的问题。

        当您从设备读取数据时,您应该在缓冲区中找到三个值。对后两个执行此操作以获得正确的读数:

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

        【讨论】:

        • 你从哪里知道Neurosky Mindwave Mobile EEG的数据源?在这个问题中,只提到了医疗设备ECG。源设备重要吗?
        • 此人从这里获取了short raw = ... 公式:developer.neurosky.com/docs/…
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-03-15
        • 1970-01-01
        • 2015-04-16
        • 2023-03-19
        相关资源
        最近更新 更多