串口转MQTT,串口桥

有啥用?暂时还不知道
首先是一些定义,串口设备需要一个id,比如通信模块可以用型号+imei,其它模块可以型号+序列号等
串口到MQ的主题:uart/id/miso
MQ到串口的主题:uart/id/mosi
首先初始化串口,由于mono下DataReceived有bug,所以采用线程处理

serialPort1 = new SerialPort();
serialPort1.BaudRate = 115200;
serialPort1.PortName = "/dev/ttyUSB4";
//mono补丁
Thread spThread = new Thread(new ThreadStart(DataReceived));
spThread.Start();
//serialPort1.DataReceived += SerialPort1_DataReceived;
serialPort1.Open();

串口接收线程

static object o = new object();
static void DataReceived()
{
    while (serialPort1 != null)
    {
        lock (o)
        {
            if (serialPort1.IsOpen && serialPort1.BytesToRead > 0)
                Sp_DataReceived();
        }
        Thread.Sleep(20);
    }
}

串口接收处理

private static void Sp_DataReceived()
{
    Thread.Sleep(20);
    int r = serialPort1.BytesToRead;
    while (r > 0)
    {
        string topic = "uart/" + id + "/miso";
        byte[] buf = new byte[r];
        serialPort1.Read(buf, 0, r);
        client.Publish(topic, new MqttPayload(buf, 0), QoS.BestEfforts, false);
        r = serialPort1.BytesToRead;
    }
}

初始化MQ部分,顺便订阅,暂时都没有考虑重连

string cid = "ub_slave_" + id;
client = MqttClientFactory.CreateClient("tcp://" + ip + ":" + port.ToString(), cid, "miku");
client.Connected += Client_Connected;
client.PublishArrived += Client_PublishArrived;
client.ConnectionLost += Client_ConnectionLost;
client.Connect(true);

private static void Client_Connected(object sender, EventArgs e)
{
    client.Subscribe("uart/" + id + "/mosi", QoS.BestEfforts);
}

MQ部分接收处理

private static bool Client_PublishArrived(object sender, PublishArrivedArgs e)
{
    string topic = e.Topic;
    string payload = e.Payload;
    byte[] buf = e.Payload.TrimmedBuffer;
    serialPort1.Write(buf, 0, buf.Length);
    return true;
}

附温湿度解析

//02 03 04 01 02 00 C0 69 5F
string msg = "设备:" + buf[0].ToString();
float sd = buf[3] * 256 + buf[4];
float wd = buf[5] * 256 + buf[6];
msg += ",温度:" + (wd / 10).ToString();
msg += ",湿度:" + (sd / 10).ToString();

标签: none

添加新评论