多传感器采集
概述
采集一个水位计和一个温湿度传感器的数据,并定时通过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