跳转至

多传感器采集


概述

采集一个水位计和一个温湿度传感器的数据,并定时通过MQTT上报服务器。用两个定时器来实现两个线程,一条线定时采集数据,保存到变量中;另一条定时上报,直接使用保存的数据。


代码


var server = "iot.easelive.cn";
var port = 1883;
var username = "username";
var password = "password";
var clientid = Box.sn();

var report_period = 5 * 60 * 1000;  //上报周期
var ping_period = 60 * 1000;                //心跳周期
var read_period = 30 * 1000;                //读传感器周期,

var cur_device = 1; //设备序号,默认从1开始,设备地址不需要与序号相同
var NUM_DEVICE = 2; //设备最大个数

var read_fail = 0;
var device = {
    temperature: 0.0,
    humidity: 0.0,
    depth:0.0
};

var pkt_id = 1;
function report(value)
{
    var data = {
        temperature:device.temperature,
        depth:device.depth
    };
    print("report", JSON.stringify(data));
    Net.send(1, Packet.MQTT.publish("your subject", JSON.stringify(data), 1, pkt_id));
    pkt_id++;
}

function handleMQTTData(data)
{
    //print(JSON.stringify(data));
    switch(data.type)
    {
        case Packet.MQTT.CONNACK:
            Timer.start(3, 2000);
            break;
        case Packet.MQTT.PUBLISH:
            if(data.qos == 1)
                Net.send(1, Packet.MQTT.puback(data.id));
            print(data.topic);
            break;
    }
}
var mqtt = Packet.MQTT.Parser.create(handleMQTTData);
function netCB(m)
{
    switch(m.event)
    {
        case Net.READY:
            print("csq:", Net.csq());
            print("syncTime:", Net.syncTime());
            Net.tcp(1, server, port);
            break;
        case Net.CONN_OK:
            Net.send(1, Packet.MQTT.connect(clientid, 60, 1, username, password));
            Timer.start(1, ping_period);
            break;
        case Net.CONN_FAIL:
            print("connect failed");
            break;
        case Net.CONN_CLOSE:
            print("connect closed");
            break;
        case Net.RECV:
            //print(m.data.hex());
            mqtt.parse(m.data);
            break;
    }
}

function readDevice()
{   //读取设备数据,设备序号默认从1开始,设备地址不需要与序号相同
    switch(cur_device)
    {
        case 1: 
            UART.send(2, Packet.Modbus.packet(1, 3, 1, 2));
            break;
        case 2:
            UART.send(2, Packet.Modbus.packet(2, 4, 1, 1));
            break;
    }   
    Timer.start(5, 5000);
}

function modbusCB(data)
{
    print(data.addr, data.cmd, data.data.hex());
    read_fail = 0;
    Timer.stop(5);

    switch(cur_device)  //根据当前设备获取数据
    {
        case 1: 
            device.depth = data.data.geti(1, "fb");
            break;
        case 2: 
            device.temperature = data.data.geti(1, "2b") / 10;
            device.humidity = data.data.geti(3, "2b") / 10;
            break;
    }
    //读取设备成功,读取下一个设备
    cur_device++;
    if(cur_device > NUM_DEVICE) cur_device = 1;
    Timer.start(4, read_period);
}
var pm = Packet.Modbus.Parser.create(modbusCB);
function uartCB(port, data)
{
    if(port == 1)
    {
        var params = data.gets().split(" ");

      if(params[0] == "test")   //测试传感器,比如在串口工具发送test 1 3 1 2
        {
          print("test");
            UART.send(2, Packet.Modbus.packet(parseInt(params[1]), parseInt(params[2]), parseInt(params[3]), parseInt(params[4])));
        }
        else
        {
            print("unknown cmd");
        }
    }
    if(port == 2)
    {
      print(data.hex());
        pm.parse(data);
    }
}
function timerCB(id)
{
    switch(id)
    {
        case 1: //send heartbeat packet
            Net.send(1, Packet.MQTT.ping());
            Timer.start(1, ping_period);
            break;
        case 3: //send report packet
            report();
            Timer.start(3, report_period);
            break;
        case 4: //read modbus
            readDevice();
            break;
        case 5: //read timeout
            read_fail++;
            if(read_fail > 3)
            {
                device.temperature = 0.0;
                //当前设备读取3次失败,读取下一个设备
                cur_device++;
                if(cur_device > NUM_DEVICE) cur_device = 1;
                Timer.start(4, read_period);
            }
            else
            {
                //读取失败继续读取当前设备
                Timer.start(4, 5000);               
            }
            break;
    }
}

GPIO.set(GPIO.POWER, 1);
GPIO.listen(GPIO.IN1);
Net.init();
UART.open(2, 9600);
Timer.start(4, 2000);

while(true)
{
    var m = Event.get();
    switch(m.msg)
    {
        case Event.NET_EVENT:
            netCB(m);
            break;
        case Event.TIMER_OUT:
            timerCB(m.id);
            break;
        case Event.UART_RECV:
            uartCB(m.port, m.data);
            break;
    }
}


下载代码(右键另存为):multidevice.js