水文水利超省电上报
概述
本项目使用锂电池供电,每小时开机上报一次,传感器电源由继电器控制,上报完成后进入待机,待机电流只有200微安。
代码
var SERVER_ADDR = "xx.xx.xx.xx";
var SERVER_PORT = 1080;
var msg_head = 0xaaff;
var msg_serNum = 0; //流水号
var msg_gID = 2; //RTU的群ID号
var msg_rID = 8; //RTU的ID号
var msg_mID = 1; //用户的ID号,正常时为0
var msg_Code = 0; //默认为0
var report_period = 60 * 60 * 1000; //发送周期
var ss = "10";
var f = File.open("2");
var l = File.len(f);
if(l > 0)
{
ss = File.read(f, l).gets();
msg_serNum = parseInt(ss);
if(isNaN(msg_serNum))msg_serNum = 0;
msg_serNum++;
}
File.seek(f, 0);
File.write(f, "" + msg_serNum);
File.close(f);
function checkSum(data)
{
var num = 0;
var i = 0;
for(i=0; i<data.length; i++)
{
num = (num + data[i]) % (256*256);
}
return num;
}
function readModbus(addr, cmd, reg, count)
{
var d = Bytes.create(8);
d.seti(addr, 0);
d.seti(cmd, 1);
d.seti(reg, 2, "2b");
d.seti(count, 4, "2b");
d.seti(Coder.crc16(d.sub(0, 6), "modbus"), 6, "2l");
print(d.hex());
dlen = 0;
UART.send(2, d);
//print("ssss")
}
function getReportData(waterTemp, waterline, voltage)
{
var a = Bytes.create(24);
a.seti(3, 0 , "4l"); //水温
a.seti(waterTemp, 4 , "4l");
a.seti(57, 8 , "4l"); //水位
a.seti(waterline, 12 , "4l");
a.seti(56, 16 , "4l"); //电压
a.seti(voltage, 20 , "4l");
return a;
}
function packetMsgData(cmd, code, data)
{
var len = data.length + 30;
var time = Box.getTime().timestamp + 8 * 3600;
var a = Bytes.create(len);
a.seti(msg_head, 0 , "2l");
a.seti(len, 2 , "2l");
a.seti(cmd, 4 , "2l");
a.seti(msg_serNum, 6 , "2l");
a.seti(msg_gID, 8 , "2l");
a.seti(msg_rID, 12 , "4l");
a.seti(msg_mID, 16 , "4l");
a.seti(time, 20 , "4l");
a.seti(code, 24 , "4l");
a.copy(data, 28, data.length, 0);
a.seti(checkSum(a.sub(0, len - 2)), len - 2, "2b");
msg_serNum++;
if(msg_serNum > 256*256) msg_serNum = 0;
return a;
}
var dbuf = Bytes.create(9);
var dlen = 0;
function processData(port, data)
{
if(port == 2)
{
if (dlen != 0 || data.geti(0) < 200)
{
dbuf.copy(data, dlen);
dlen += data.length;
}
if(dlen >= 9)
{
print(dbuf.hex(), dlen);
if(Coder.crc16(dbuf, "modbus") == 0)
{
var addr = dbuf.geti(0);
var cmd = dbuf.geti(1);
var count = dbuf.geti(2) / 2;
var s = "SMR003";
var i = dbuf.geti(3, "2b");
var f = dbuf.geti(5, "2b");
print("data:", i, f);
var dc_value = ADC.getv(ADC.DC) * 100;
print("sendMsg:", packetMsgData(51, 0, getReportData(i, f, dc_value)).hex());
Net.send(1, packetMsgData(51, 0, getReportData(i, f, dc_value)));
}
dlen = 0;
}
}
}
function handleNetEvent(m)
{
switch(m.event)
{
case Net.READY:
print("Net.READY");
Net.syncTime();
Net.connect(1, SERVER_ADDR, SERVER_PORT, "udp");
Timer.start(2, 20000);
break;
case Net.CONN_OK:
print("Net.CONN_OK");
readModbus(1, 3, 4, 2);
break;
case Net.CONN_FAIL:
print("connect failed");
Timer.start(2, 2000);
break;
case Net.CONN_CLOSE:
print("connect closed");
break;
case Net.RECV:
print("rec_hex:", m.data.hex());
if(m.data.geti(0, "2l") == msg_head)
{
if(m.data.geti(4, "2l") == 52)
{
Timer.start(2, 500);
}
}
break;
case Net.SEND_OK:
case Net.SEND_FAIL:
Timer.start(2, 4000); //4s后执行Event.TIMER_OUT事件
break;
default:
print('default')
}
}
function handleTimerOut(id)
{
switch(id)
{
case 1:
readModbus(1, 4, 4, 4);
break;
case 2:
Box.standby(report_period);
break;
}
}
UART.open(2, 9600);
Net.init();
GPIO.set(GPIO.POWER, 1);
GPIO.set(GPIO.OUT1, 1); //打开传感器电源
GPIO.listen(GPIO.IN1);
Timer.start(2, 30000);
while(true)
{
var m = Event.get();
switch(m["msg"])
{
case Event.UART_RECV:
processData(m["port"], m["data"]);
break;
case Event.TIMER_OUT:
handleTimerOut(m.id);
break;
case Event.NET_EVENT:
handleNetEvent(m);
break;
}
}
下载代码(右键另存为):water.js