如何解析来自nrf24缓冲区的JSON?

时间:2019-02-05 02:08:45

标签: node.js json arduino

我正在通过nrf24无线电链接向运行带有节点https://github.com/natevw/node-nrf的node.js的RaspberryPi发送由ArduinoJSON构造的有效JSON对象。 node.js服务器似乎没有问题地接收到数据。但是由于某种原因,我无法在没有获取SyntaxError: Unexpected token in JSON at position ...

的情况下对对象(或缓冲区?)进行JSON.parse()。

由于某种原因,node-nrf库向后接收数据,因此我需要使用Array.prototype.reverse.call(d),然后是console.log(d.toString())反转字节的顺序,一切似乎都很好。在这种情况下,控制台将获得Got data: [{"key":"a1","value":150}]。此时,缓冲区的内容如下:Buffer 5b 7b 22 6b 65 79 22 3a 22 61 31 22 2c 22 76 61 6c 75 65 22 3a 31 35 30 7d 5d 00 00 00 00 00 00。这些是我估计nrf24缓冲区实际包含的32个字节。

但是,当代码到达JSON.parse()调用时,我得到了SyntaxError: Unexpected token in JSON at position 26。这是我的对象数据实际上在缓冲区中结束的位置。

我还尝试了.toJSON()和JSON.stringify(),但实际上无法获得要使用的适当对象(即obj.key,obj.value)。它仅返回undefined属性。在我看来,解析到达对象末尾时会失败。我还尝试将缓冲区大小与消息的实际大小相匹配,以查看解析是否成功无济于事!

我可能对缓冲区,流,管道和对象的概念非常困惑……我做错了什么?

我需要想法(或解决方法!)

在node.js的接收端运行的代码:

var nrf = NRF24.connect(spiDev, cePin, irqPin);
nrf.printDetails();
   nrf.channel(0x4c).transmitPower('PA_MIN').dataRate('1Mbps').crcBytes(2).autoRetransmit({count:15, delay:4000}).begin(function () {
    var rx = nrf.openPipe('rx', pipes[0]);
    rx.on('data', d => {
        let obj = Array.prototype.reverse.call(d);
        try {

        console.log("Got data: ", d.toString());

        console.log(obj);
        obj = JSON.parse(obj);
        console.log(obj);

        } catch (err) {
            console.error(err)
        }
     });

});

我认为问题不在于形成JSON消息。但出于参考目的,这是在Arduino上运行的代码:

#include <SPI.h>
#include <nRF24L01.h>
#include <RF24.h>
#include <ArduinoJson.h>

const uint64_t addresses[5] = {0x65646f4e32LL,0x65646f4e31LL} ; 
RF24 radio(7,8);

char output[32];

void setup()
{
Serial.begin(115200);
radio.begin();
radio.setAutoAck(true);
radio.setDataRate(RF24_1MBPS);
radio.enableDynamicPayloads();
radio.setCRCLength(RF24_CRC_16);
radio.setChannel(0x4c);
radio.setPALevel(RF24_PA_MAX);
radio.openWritingPipe(addresses[0]);  
}

void loop()
{
const int capacity = JSON_ARRAY_SIZE(2) + 2*JSON_OBJECT_SIZE(2);
StaticJsonBuffer<capacity> jb;

JsonArray& arr = jb.createArray();
JsonObject& obj1 = jb.createObject();
obj1["key"] = "a1";
obj1["value"] = analogRead(A1);
arr.add(obj1);

arr.printTo(output);
bool ok = radio.write(&output, sizeof(output));

arr.printTo(Serial);
Serial.print(ok);

delay(1000);
}

2 个答案:

答案 0 :(得分:1)

很可能在字符串末尾有NUL个字符。 JSON.parse将拒绝对其进行解析。

let obj = '[{"key":"a1","value":150}]\x00\x00\x00\x00\x00\x00';
JSON.parse(obj);
  

未捕获到的SyntaxError:意外令牌-JSON中的位置26

如果删除NUL字符,则解析成功:

let obj = '[{"key":"a1","value":150}]\x00\x00\x00\x00\x00\x00';
obj = obj.replace(/\0/g, "");
JSON.parse(obj);

答案 1 :(得分:0)

将“缓冲区数据”解析为“字符串”,例如:

rx.on('data', d => {
    try {
        let obj = d.toString();
        console.log(obj);
        obj = JSON.parse(obj);
        console.log(obj);
    } catch (err) {
        console.error(err)
    }
});