跳转至

MODBUS模块


概述

演示通过RS485串口读取MODBUS数据。这里接的是一个温湿度模块,值的数据类型为16位整数。如果值的数据类型为其他,可以用"2l","4l","4b","fl","fb"等参数据需要的值。第二个代码使用协议库的方式。


代码


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");
    UART.send(2, d);
}

function processData(port, data)
{
    if(port == 1)
    {
        var cmd = data.gets();
        if(cmd == "read")
        {
            readModbus(1, 4, 1, 1);
        }
        else if(cmd == "read2")
        {
            readModbus(1, 4, 1, 2);
        }
        else
        {
            print("unknown cmd");
        }
    }
    if(port == 2)
    {
        if(Coder.crc16(data, "modbus") == 0)
        {
            var addr = data.geti(0);
            var cmd = data.geti(1);
            var count = data.geti(2) / 2;
            for(var i = 0; i < count; i++)
            {
                print(data.geti(3 + i * 2 , "2b"));
            }
        }
    }
}
UART.open(2, 9600);

while(true)
{
    var m = Event.get();
    switch(m.msg)
    {
        case Event.UART_RECV:
            processData(m.port, m.data);
            break;
    }
}

代码(协议库版本)


function processData(data)
{
    print(data.addr, data.cmd);
    var count = data.data.geti(0) / 2;
    for(var i = 0; i < count; i++)
    {
        print(data.data.geti(1 + i * 2 , "2b"));
    }
}
function processUartData(port, data)
{
    if(port == 1)
    {
        var cmd = data.gets();
        if(cmd == "read")
        {
            UART.send(2, Packet.Modbus.packet(1, 4, 1, 1));
        }
        else if(cmd == "read2")
        {
            UART.send(2, Packet.Modbus.packet(1, 4, 1, 2));
        }
        else
        {
            print("unknown cmd");
        }
    }
    if(port == 2)
    {
        pm.parse(data);
    }
}

UART.open(2, 9600);
var pm = Packet.Modbus.Parser.create(processData);

while(true)
{
    var m = Event.get();
    switch(m.msg)
    {
        case Event.UART_RECV:
            processUartData(m.port, m.data);
            break;
    }
}