乐趣区

关于物联网:PM空气质量检测仪

在日常工作中,咱们常常会对接一些奇奇怪怪的小设施,他们既没采纳大型设施厂家的通信协定,也没有通用的统计数值的办法。这时候就得须要用到咱们的自定义逻辑代码去实现这些设施数据的采集以及数值转换,明天咱们将通过济南参谋通信技术有限公司生产的 pm2.5/pm10 激光传感器(USB 版本)解说自定义逻辑代码实现数据采集

一、产品

明天须要用到的产品有:
海创 Box 智能采集网关
pm2.5/pm10 激光传感器(USB 版本)应用说明书

如上图所示将 pm2.5/pm10 激光传感器(USB 版本)的 USB 插口连贯到海创 Box 智能采集网关的 USB 口上

二、通信协定

通过厂家给的说明书里的通信协定咱们可得悉设施默认参数:
串口通信协定:9600 8N1(速率 9600, 数据位 8,校验位无,进行位 1)
串口主动上报通信周期:1+0.5 秒
数据帧(10 字节):报文头 + 指令号 + 数据 (6 字节)+ 校验和 + 报文尾
示例报文为
AA C0 71 01 CA 01 B9 93 89 AB
具体含意:
AA—- 报文头
C0—- 指令号,客户开发产品时,看到接管到有 CO,即示意是由 PM2.5 传感器输入的信号
71—-PM2.5 低字节
01—-PM2.5 高字节
CA—-PM10 低字
01—-PM10 高字节
B9—- 传感器的 ID
93—- 传感器的 ID
89—- 校验和,即 71+01+CA+01+B9+93=289 即 0x0289,这里咱们舍弃了高字节 02,只保留了低字节 89
AB—- 报文尾
因为输入的是,16 进制数据,请转换成 10 进制数进行计算。
PM2.5 值的计算:71 01
低字节 71: 7*16+1=113
高字节 01: 016+1=1 ((PM2.5 高字节 256) + PM2.5 低字节)/10(1*256+113)/10=36.9ug/m3
PM10 值的计算:CA 01
低字节 CA: C*16+A=202
高字节 01: 016+1=1 ((PM10 高字节 256) + PM10 低字节)/10 (1*256+202)/10=45.8ug/m3
校验和:
89 71+01+CA+01+B9+93=289,舍弃高字节 02,留低字节 89。

三、节点流

在桌面关上海创 Box 智能采集网关可视化开发平台进入可视化编辑器。本次教程须要用到如下节点,在左侧节点栏中拖拽出应用
serial 在输出栏目,用于读取串口二进制流

提早在性能栏目,用于提早音讯速率

function 在性能栏目,用于配置逻辑代码

调试在输入栏目,用于调试输入

配置界面详情(疾速复用请导航到文章末端)

接下来咱们来配置如上图的节点流,首先将左侧节点栏的 serial、提早、function、调试节点别离拖拽到工作区,再点击相应的流节点的端口顺次按配置界面所示连接起来,再双击相应流节点进入配置界面配置相应属性

serial 是用于读取串口输入的节点工具。该工具须要配置串口名称 (Serial Port)、波特率(Baud Rate)9600、数据位(Data Bits)8、校验位(Parity)Node、进行位(Stop Bits)1。该 USB 转串口程序在奥迈智能网关中应用不须要下载任何驱动程序,即插即用。在插入智能网关的 USB 口后,会在零碎的驱动目录下 /dev 生成一个串口文件 ttyUSB0(没有其余 USB 转串口的工具插入下),咱们须要在配置串口名称(Serial Port) 配置 /dev/ttyUSB0。Windows 下须要装置官网驱动。因为 serial in 读取串口数据是间断的,所以咱们须要将 Split input(拆分输出)配置成 after a silence of(在没有新的二进制流输入后),默认工夫填写 50ms。详情配置如下图。

提早用于提早 serial 节点输入的信息速率。因为该设施自定义速率为 0.5 秒 / 信息,咱们理论采集的时候用不到这么频繁的数据,所以咱们抉择限度音讯速率,如下配置限度音讯 1 分钟 / 条。

function 是用于编写自定义代码的节点工具,该控件反对 nodejs 语法,能够实现您所有的业务逻辑。依据该设施的通信协定,咱们将分为两个逻辑块,别离寄存在两个 function 外面,用于数据校验以及获得咱们须要的数据。须要留神的是在咱们的框架内定义个别流的数据向下流动时都将数据存入 msg.payload 这个对象中。对于更多 Buffer 类的更多应用请参考 Buffer。详情配置如下图。

CRC 校验代码如下:

var count=0;
    let buf=0;
    // 以 0 开始取第 2 位字节点到第 7 字节的数据
    for(var i=2;i<msg.payload.length-2;i++)
    {buf+=msg.payload.readUInt8(i);
    }
    // 创立一个 2 字节的 buff 将 buf 转成 16 进制并取低字节
    var bufTemp=Buffer.alloc(2);
    bufTemp.writeUInt16BE(buf);
    // 删除高字节
    bufTemp=bufTemp.slice(bufTemp.length-1);
    if(bufTemp.compare(msg.payload.slice(8,9))==0)
    {
        msg._crc=true;
        return msg
    }
    else
    {
        msg._crc=false;
        node.error('数据位校验失败',msg);
    }

pm2.5/pm10 取值代码如下:

let PM25Value= msg.payload.readUInt16LE(2)/10;
    let PM10= msg.payload.readUInt16LE(4)/10;
    msg.payload={PM25Value:PM25Value,PM10:PM10}
    return msg;

调试用于界面调试输入后果。咱们须要将下面的程序输入后果打印在界面右侧的调试窗口,按配置界面图链接即可。

四、部署调试

通过下面所有步骤后,即可部署程序,部署后能够在右侧的调试窗口看到输入,如下图。

五、示例

以上教程能够通过拷贝上面代码实现疾速复用,在新建的流程中点击界面右侧菜单栏 - 导入 - 剪贴板,在文本框中粘贴上面代码后点击确定,即可疾速复用。

[
    {
        "id": "e2618b1e.c557f8",
        "type": "delay",
        "z": "7fce5a14.7da9c4",
        "name": "","pauseType":"rate","timeout":"5","timeoutUnits":"seconds","rate":"1","nbRateUnits":"1","rateUnits":"minute","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop": true,"x": 335,"y": 260,"wires": [
            ["be9d7a30.0c43c8"]
        ]
    },
    {
        "id": "47ea0be9.2ffb14",
        "type": "serial in",
        "z": "7fce5a14.7da9c4",
        "name": "","serial":"f8003df1.9aa5c","x": 215,"y": 260,"wires": [
            ["e2618b1e.c557f8"]
        ]
    },
    {
        "id": "be9d7a30.0c43c8",
        "type": "function",
        "z": "7fce5a14.7da9c4",
        "name": "CRC 测验",
        "func": "var count=0;\nlet buf=0;\n// 以 0 开始取第 2 位字节点到第 7 字节的数据 \nfor(var i=2;i<msg.payload.length-2;i++)\n{\n\tbuf+=msg.payload.readUInt8(i);\n}\n// 创立一个 2 字节的 buff 将 buf 转成 16 进制并取低字节 \nvar bufTemp=Buffer.alloc(2);\nbufTemp.writeUInt16BE(buf);\n// 删除高字节 \nbufTemp=bufTemp.slice(bufTemp.length-1);\nif(bufTemp.compare(msg.payload.slice(8,9))==0)\n{\n    msg._crc=true;\n    return msg\n}\nelse\n{\n    msg._crc=false;\n    node.error(' 数据位校验失败 ',msg);\n}\n",
        "outputs": 1,
        "noerr": 0,
        "x": 475,
        "y": 260,
        "wires": [
            ["5625f516.97a3dc"]
        ]
    },
    {
        "id": "5625f516.97a3dc",
        "type": "function",
        "z": "7fce5a14.7da9c4",
        "name": "pm2.5/pm10 取值",
        "func": "let PM25Value= msg.payload.readUInt16LE(2)/10;\nlet PM10= msg.payload.readUInt16LE(4)/10;\nmsg.payload={PM25Value:PM25Value,PM10:PM10}\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 615,
        "y": 260,
        "wires": [
            ["e65320dc.562b5"]
        ]
    },
    {
        "id": "e65320dc.562b5",
        "type": "debug",
        "z": "7fce5a14.7da9c4",
        "name": "","active": true,"tosidebar": true,"console": false,"tostatus": false,"complete":"false","x": 735,"y": 260,"wires": []},
    {
        "id": "f8003df1.9aa5c",
        "type": "serial-port",
        "z": "","serialport":"/dev/ttyUSB0","serialbaud":"9600","databits":"8","parity":"none","stopbits":"1","newline":"50","bin":"bin","out":"interbyte","addchar": false,"responsetimeout":"10000"
    }
]
退出移动版