跳转至

水文水利超省电上报


概述

本项目使用锂电池供电,每小时开机上报一次,传感器电源由继电器控制,上报完成后进入待机,待机电流只有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