Unity对接ModbusTCP

Unity对接ModbusTCP

测试版本:unity2019.4.1和Unity2021.3.4均无问题

1、测试工具和dll文件链接:

链接:https://pan.baidu.com/s/1kLPesjtCJQOlT9Fq7qDEYA
提取码:rmug

2、导入NModbus4.dll文件到Unity的Plugins文件夹中

3、测试工具的使用

找到文件夹内ModSim32.exe程序,双击运行
在这里插入图片描述
弹出警告,点击确定
在这里插入图片描述
进入主界面点击File→New新建一个ModSim
在这里插入图片描述
当前未连接,所以会有NOT CONNECTEDI警告
在这里插入图片描述
根据需求选择对应连接模式
在这里插入图片描述
在这里插入图片描述

4、脚本

对应不同模式,使用不同方法
在这里插入图片描述

//using LitJson;
using Modbus.Device;
using System;
using System.Collections;
using System.IO;
using System.Net;
using System.Net.Sockets;
using System.Threading;
using UnityEngine;
using UnityEngine.Networking;
using UnityEngine.UI;
/// <summary>
/// Modbus Tcp/IP
/// </summary>
public class Concent_ : MonoBehaviour
{
    public ModbusMaster modbusIpMaster;
    public TcpClient tcpClient;
    IPAddress Address = new IPAddress(new byte[] { 127, 0, 0, 1 });
    public int Port = 502;
    public bool Conen = false;
    public bool Reda_White;
    private ushort[] Udata = new ushort[] { 0x03 };
    private ushort star = 1;
    Thread mythread;
    public bool isconect = false;

    ushort[] AoData11;
    string ip;
    private void Awake()
    {
        instance = this;
        StartCoroutine(GetData());
    }
    void Start()
    {
        //Ip_.text = "127.0.0.1";//192.168.1.140
        //Port_.text = "502";
 OpenConnect_("127.0.0.1", 502);

        //OpenConnect_(ip, 502);
    }

  //  IEnumerator GetData()
 //   {
    //    var uri = new System.Uri(Path.Combine(Application.streamingAssetsPath, "IP.json"));
    //    UnityWebRequest www = UnityWebRequest.Get(uri);
    //    yield return www.SendWebRequest();

     //   if (www.isNetworkError || www.isHttpError)
    //    {
     //       Debug.Log(www.error);
      //  }
      //  else
     //   {
            // Debug.Log(www.downloadHandler.text);
       //     string jsonStr = www.downloadHandler.text;
       //     IPTest ques = JsonMapper.ToObject<IPTest>(jsonStr);
        //    ip = ques.ip;
        //    Debug.Log(ip);
       // }
   // }
    public void OpenConnect_(string ip, int port)
    {

        if (Connect(ip, port))
        {
            Debug.Log("连接成功");
        }
        else
        {
            Debug.Log("连接失败");        }
    }
    public bool Connect(string ip, int port)
    {
        try
        {
            tcpClient = new TcpClient(ip, port);

            tcpClient.SendTimeout = 1;
            modbusIpMaster = ModbusIpMaster.CreateIp(tcpClient);

            mythread = new Thread(WriteMessageFromClient);

            mythread.Start();
            Conen = true;
            return true;
        }
        catch (Exception ex)
        {
            tcpClient.Close();
            Debug.LogError(ex.Message);
            return false;
        }
    }
    public void WriteMessageFromClient()
    {
        while (Conen)
        {
            try
            {
                if (Reda_White)
                {
                    Write_jiChunQi(star, Udata);
                    Debug.Log("发送成功");
                }
                if (kuse)
                {
                    Debug.Log("a");
                    //READ HOLDING REGISTER
                    //    要从中读取值的设备地址(ModSim  id)  开始阅读的地址(1~125)  要读取的保存寄存器的数目
                    ushort[] msg = modbusIpMaster.ReadHoldingRegisters(0x01, 0x01, 0x02);
                }
            }
            catch
            {
                break;
            }
        }
        tcpClient.Close();
    }
    public void Write_jiChunQi(ushort star, ushort[] data)
    {
        modbusIpMaster.WriteMultipleRegisters(1, star, data);
    }
    private byte GetHex(string msg)
    {
        byte hex = Convert.ToByte(msg);
        return hex;
    }
    public int GetDexx(string msg)
    {
        int res = Convert.ToInt32(msg, 16);
        return res;
    }
    private void OnApplicationQuit()
    {
        tcpClient.Close();
    }
    public bool kuse = false;
    bool[] aa = new bool[] { true, false, true };


    bool[] bool_coilstatus;
    public ushort[] HoldingRegister;
    public void BtnOnClick()
    {
        modbusIpMaster.WriteSingleCoil(0x01, 0, !zongkaiguan);
    }
    void FixedUpdate()
    {
        //if (Input.GetKeyDown(KeyCode.Alpha1))//第一个发送
        //{
        //    modbusIpMaster.WriteSingleCoil(0x01, 0, false);//发送单个
        //    //modbusIpMaster.WriteMultipleCoils(0x01, 0, aa);//发送数组
        //    Debug.Log("发送成功");
        //}
        //if (Input.GetKeyDown(KeyCode.Alpha2))//第三个发送
        //{
        //    //modbusIpMaster.WriteSingleRegister(0x01, 0, 7);//发送单个
        //    modbusIpMaster.WriteMultipleRegisters(0x01, 0, new ushort[] { 10, 2, 2 });//发送数组
        //    Debug.Log("发送成功");
        //}



        //if (Input.GetKeyDown(KeyCode.Alpha5))//第一个
        //{
        //    bool_coilstatus = modbusIpMaster.ReadCoils(0x01, 0, 0x1);
        //    zongkaiguan = bool_coilstatus[0];
        //    foreach (var item in bool_coilstatus)
        //    {
        //        Debug.Log("读取到的数据:" + item);
        //    }
        //}
        //if (Input.GetKeyDown(KeyCode.Alpha6))//第二个
        //{
        //    // modbusIpMaster.ReadInputRegistersAsync(0x01, 0, 0x5);
        //    //modbusIpMaster.ReadInputsAsync(0x01, 0, 0x5);
        //    s = modbusIpMaster.ReadInputs(0x01, 0, 0xe);
        //    foreach (var item in s)
        //    {
        //        Debug.Log("读取到的数据:" + item);
        //    }
        //}
        //if (Input.GetKeyDown(KeyCode.Alpha7))//第三个
        //{
        //    HoldingRegister = modbusIpMaster.ReadHoldingRegisters(0x01, 0, 0x03);

        //    //string str = AoData.ToString();
        //    //Debug.Log(AoData.Length);
        //    foreach (var item in HoldingRegister)
        //    {
        //        Debug.Log("读取到的数据:" + item);
        //    }
        //}
        //if (Input.GetKeyDown(KeyCode.Alpha8))//第四个
        //{
        //    ushort[] msg = modbusIpMaster.ReadInputRegisters(0x01, 0, 0x01);
        //    foreach (var item in msg)
        //    {
        //        Debug.Log(item);
        //    }
        //}
    }
}

public class IPTest
{
    public string ip;
}

### 关于 Unity 和 Modbus 的集成 在讨论如何将 Modbus 集成到 Unity 中之前,需明确两个概念:Unity 是一种依赖注入容器以及游戏开发引擎[^1],而 Modbus 是一种通信协议,用于工业自动化设备之间的数据交换。两者的功能领域不同,因此需要通过特定的技术手段来实现它们的协作。 #### 使用 C# 实现 Modbus 客户端/服务器 由于 Unity 支持 C# 编程语言,可以通过引入第三方库或自行编写代码来处理 Modbus 协议的数据交互。以下是几种常见的方法: 1. **使用开源 Modbus 库** 存在多个成熟的 .NET 或 C# 开源项目支持 Modbus 协议,例如 NModbus4。NModbus4 提供了一个简单易用的接口,可以轻松创建 Modbus TCP 或 RTU 客户端和服务器实例[^3]。 下面是一个简单的 Modbus TCP 客户端示例: ```csharp using System; using System.Net.Sockets; using NModbus; public class ModbusClientExample : MonoBehaviour { private TcpClient _client; private IModbusMaster _master; void Start() { _client = new TcpClient("localhost", 502); _master = ModbusFactory.CreateMaster(_client); ushort startAddress = 0; // 起始寄存器地址 ushort numRegisters = 10; // 请求的数量 var result = _master.ReadHoldingRegisters(1, startAddress, numRegisters); // 设备ID为1 foreach (var value in result) Debug.Log($"Register Value: {value}"); } void OnDestroy() { _client?.Close(); } } ``` 2. **自定义 Modbus 数据包解析** 如果不想依赖外部库,也可以手动构建 Modbus 数据帧并发送给目标设备。这通常涉及低级别的网络编程(如 Socket),并通过字节流的形式读取响应数据。这种方法虽然灵活但复杂度较高,适合有经验的开发者。 3. **中间件解决方案** 对于更复杂的场景,可能需要借助消息队列或其他形式的中介服务完成异步通讯任务。比如利用 Azure Service Bus 或者 RabbitMQ 来桥接 Unity 应用程序与实际硬件之间基于 Modbus 的操作流程。 #### 注意事项 - 确保所选方案兼容当前使用的 Unity 版本及其运行环境(编辑器模式 vs 发布平台)。 - 测试阶段应充分考虑异常情况下的错误恢复机制,防止因网络中断等原因造成整个系统崩溃。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Ke-Di

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值