物联网通讯协议-MQTT、Modbus、OPC

引言

在物联网迅速发展的今天,设备间的通信协议扮演着至关重要的角色。它们是不同设备、系统之间实现数据交换的桥梁。本文将详细介绍三种在物联网领域广泛应用的通讯协议------MQTT、Modbus和OPC,包括它们的基础概念、特点及在C#中的实现方法。

一、MQTT协议

1. 基础概念

MQTT(Message Queuing Telemetry Transport)是一种轻量级的发布/订阅消息传输协议,专为物联网设备通信设计 6 。它基于发布/订阅(Pub/Sub)模式,包含三个核心角色:

  • 发布者(Publisher) :发送消息的设备或应用

  • 代理(Broker) :消息的中转中心,负责接收和分发消息

  • 订阅者(Subscriber) :接收特定主题消息的设备或应用 MQTT的轻量级特性体现在:

  • 最小化报文头仅2字节,最小报文仅2字节

  • 低带宽消耗,1KB消息传输开销小于5%

  • 支持QoS(服务质量)分级保障:

    • QoS 0:至多一次(Fire and Forget)

    • QoS 1:至少一次(Acknowledged Delivery)

    • QoS 2:精确一次(Assured Delivery)

2. C#实现示例

在C#中,我们可以使用MQTTnet库来实现MQTT通信。首先通过NuGet安装:

复制代码
Install-Package MQTTnet

以下是一个简单的MQTT客户端实现:

复制代码
using MQTTnet;
using MQTTnet.Client;
using System.Text;
​
class MQTTClientExample
{
    private static async Task Main(string[] args)
    {
        // 创建MQTT客户端
        var factory = new MqttFactory();
        var client = factory.CreateMqttClient();
​
        // 配置连接选项
        var options = new MqttClientOptionsBuilder
        ()
            .WithTcpServer("broker.hivemq.com", 
            1883) // 连接到公共MQTT代理
            .WithClientId("CsharpClient")
            .WithCleanSession()
            .Build();
​
        // 连接事件处理
        client.ConnectedAsync += async (e) =>
        {
            Console.WriteLine("已连接到MQTT代理");
            // 订阅主题
            await client.SubscribeAsync("iot/
            sensors");
            Console.WriteLine("已订阅主题: iot/
            sensors");
        };
​
        // 消息接收事件处理
        client.ApplicationMessageReceivedAsync += 
        (e)
            =>
            {
                Console.WriteLine($"收到消息: 主题=
                {e.ApplicationMessage.Topic}, 内容
                ={Encoding.UTF8.GetString(e.
                ApplicationMessage.Payload)}");
                return Task.CompletedTask;
            };
​
        // 连接到MQTT代理
        await client.ConnectAsync(options);
​
        // 发布消息
        var message = new 
        MqttApplicationMessageBuilder()
            .WithTopic("iot/commands")
            .WithPayload("
            {\"action\":\"read_sensors\"}")
            .WithQualityOfServiceLevel
            (MqttQualityOfServiceLevel.
            AtLeastOnce)
            .Build();
​
        await client.PublishAsync(message);
        Console.WriteLine("已发布消息到主题: iot/
        commands");
​
        // 保持程序运行
        Console.ReadLine();
        await client.DisconnectAsync();
    }
}

二、Modbus协议

1. 基础概念

Modbus是一种应用广泛的工业通信协议,由Modicon公司(现施耐德电气)于1979年开发 2 。它是一种主从式协议,支持以下几种主要变体:

  • Modbus RTU :基于串口(RS-232/RS-485)的二进制格式

  • Modbus ASCII :基于串口的ASCII字符格式

  • Modbus TCP :基于以太网的TCP/IP协议 Modbus协议通过寄存器地址进行数据访问,主要包含:

  • 线圈寄存器(Coils):用于开关量输出

  • 离散输入寄存器(Discrete Inputs):用于开关量输入

  • 保持寄存器(Holding Registers):用于模拟量输出和数据存储

  • 输入寄存器(Input Registers):用于模拟量输入

2. C#实现示例

在C#中,我们可以使用NModbus库来实现Modbus通信。首先通过NuGet安装:

复制代码
Install-Package NModbus

以下是一个Modbus TCP客户端实现示例:

复制代码
using Modbus.Data;
using Modbus.Device;
using Modbus.Utility;
using System.Net.Sockets;
​
class ModbusTcpClientExample
{
    private static void Main(string[] args)
    {
        // 连接到Modbus TCP服务器
        TcpClient client = new TcpClient("127.0.0.
        1", 502);
        IModbusMaster master = ModbusIpMaster.
        CreateIp(client);
​
        // 读取保持寄存器(地址100-103)
        ushort startAddress = 100;
        ushort numRegisters = 4;
        ushort[] registers = master.
        ReadHoldingRegisters(1, startAddress, 
        numRegisters);
​
        Console.WriteLine("读取保持寄存器结果:");
        for (int i = 0; i < registers.Length; i++)
        {
            Console.WriteLine($"寄存器 
            {startAddress + i}: {registers[i]}");
        }
​
        // 写入单个保持寄存器
        ushort writeAddress = 100;
        ushort writeValue = 1234;
        master.WriteSingleRegister(1, 
        writeAddress, writeValue);
        Console.WriteLine($"已写入寄存器 
        {writeAddress}: {writeValue}");
​
        // 写入多个保持寄存器
        ushort[] writeValues = { 5678, 9012 };
        master.WriteMultipleRegisters(1, 101, 
        writeValues);
        Console.WriteLine("已写入多个寄存器");
​
        client.Close();
    }
}

三、OPC协议

1. 基础概念

OPC(OLE for Process Control)是工业自动化领域的通信标准,旨在实现不同厂商设备和系统之间的互操作性 3 。目前主要有两个版本:

  • OPC DA(Data Access) :基于微软COM/DCOM技术,适用于Windows平台

  • OPC UA(Unified Architecture) :平台无关、厂商无关的统一架构,支持跨平台通信 OPC UA的主要特点:

  • 平台无关:支持Windows、Linux、macOS等多种操作系统

  • 安全可靠:提供端到端的加密和认证

  • 信息建模:支持复杂的数据结构和语义

  • 可扩展性:支持分布式系统和大规模部署

2. C#实现示例

对于OPC UA,我们可以使用OPC Foundation提供的OPC UA .NET Standard库。首先通过NuGet安装:

复制代码
Install-Package Opc.Ua.Client

以下是一个简单的OPC UA客户端实现:

复制代码
using Opc.Ua;
using Opc.Ua.Client;
using System;
using System.Collections.Generic;
​
class OpcUaClientExample
{
    private static void Main(string[] args)
    {
        // 创建应用程序配置
        ApplicationConfiguration config = new 
        ApplicationConfiguration()
        {
            ApplicationName = "CsharpOpcUaClient",
            ApplicationType = ApplicationType.
            Client,
            SecurityConfiguration = new 
            SecurityConfiguration()
            {
                ApplicationCertificate = new 
                CertificateIdentifier() { 
                StoreType = "Directory", 
                StorePath = 
                @"%CommonApplicationData%\OPC 
                Foundation\CertificateStores\Machi
                neDefault", SubjectName = 
                "CsharpOpcUaClient" },
                TrustedIssuerCertificates = new 
                CertificateTrustList { StoreType 
                = "Directory", StorePath = 
                @"%CommonApplicationData%\OPC 
                Foundation\CertificateStores\UA 
                Certificate Authorities" },
                TrustedPeerCertificates = new 
                CertificateTrustList { StoreType 
                = "Directory", StorePath = 
                @"%CommonApplicationData%\OPC 
                Foundation\CertificateStores\UA 
                Applications" },
                RejectedCertificateStore = new 
                CertificateTrustList { StoreType 
                = "Directory", StorePath = 
                @"%CommonApplicationData%\OPC 
                Foundation\CertificateStores\Rejec
                tedCertificates" }
            }
        };
        config.Validate(ApplicationType.Client).
        GetAwaiter().GetResult();
​
        // 创建会话
        string endpointUrl = "opc.tcp://
        localhost:4840/";        
        EndpointDescription endpoint = 
        CoreClientUtils.SelectEndpoint
        (endpointUrl, useSecurity: false);        
        ConfiguredEndpoint configuredEndpoint = 
        new ConfiguredEndpoint(null, endpoint, 
        EndpointConfiguration.Create(config));
        Session session = Session.Create(config, 
        configuredEndpoint, false, 
        "CsharpOpcUaClient", 60000, new 
        UserIdentity(), null).GetAwaiter().
        GetResult();
​
        Console.WriteLine("已连接到OPC UA服务器");
​
        // 读取节点值
        NodeId nodeId = new NodeId("ns=2;
        s=Temperature");
        DataValue value = session.ReadValue
        (nodeId);
        Console.WriteLine($"读取节点值: {value.
        Value}