Unity程序联动rs485可编程开关

开发工具:Unity2018.3.7

需要设备:rs485可编程开关,rs485信号转rs232信号转换头,usb串口线,12伏电源

编程开关类似下面:

转换器和串口线:

 

最近公司许多项目用到了串口通讯联动,比如rs485开关面板控制程序影片,网络继电器控制模型启动开关,还涉及了关于Unity打包ipad测试程序,写个博客记录一下,本篇主要是记录rs485开关面板控制程序联动这块。

因为之前是开发Unity程序这块,对串口通讯不太清楚,本篇也只是记录联动开关的用法,具体原理就不深究

首先程序需求为开关面板三个按钮控制pc端程序视频的开始,暂停,播放,播放结束回到待机界面,程序很简单,用的是avproVideo插件里面内置的方法来完成对视频的操作,接着Unity要进行简单的串口通讯需要引入命名空间System.IO.Ports;

这里有一点需要注意,需要将PlayerSettings中Other Settings中Api Compatibility Level改为.NET 4.x,不然会找不到该引用。

接下来是XMl配置文档,用来在外部修改串口号,控制影片是否循环,也方便更改不同可编程开关的触发代码

<?xml version="1.0" encoding="utf-8"?>
<root>
 <!--串口号-->
  <port com="COM3">
  </port>
  <!--播放触发代码-->
  <play code="0A03000237013281">
  </play>
<!--暂停触发代码-->
  <pause code="0A03000238027770">
  </pause>
<!--重播触发代码-->
  <replay code="0A0300023904F6E2">
  </replay>
<!--影片是否循环,0不循环,1循环-->
  <video loop="1">
  </video>
</root>

然后是读取xml的脚本:

using UnityEngine;
using System.Xml;

public class Config_XuTing : MonoBehaviour
{
    private string configPath;
    [HideInInspector]
    public string play_code;
    [HideInInspector]
    public string pause_code;
    [HideInInspector]
    public string replay_code;
    [HideInInspector]
    public string com;
    [HideInInspector]
    public bool loop;
    [HideInInspector]
    public string port;
    public static Config_XuTing instance;
    private void Awake()
    {
        instance = this;
        configPath = Application.streamingAssetsPath + "/config.xml";
        ReadXml();
    }

    void ReadXml()
    {
        XmlDocument doc = new XmlDocument();
        XmlReaderSettings settings = new XmlReaderSettings();
        settings.IgnoreComments = true;//忽略文档里面的注释
        XmlReader reader = XmlReader.Create(configPath, settings);
        doc.Load(reader);
        //doc.LoadXml(configPath);
        XmlNode root = doc.SelectSingleNode("root");
        loop = ((XmlElement)root.SelectSingleNode("video")).GetAttribute("loop") == "1";
        play_code = ((XmlElement)root.SelectSingleNode("play")).GetAttribute("code");
        pause_code = ((XmlElement)root.SelectSingleNode("pause")).GetAttribute("code");
        replay_code = ((XmlElement)root.SelectSingleNode("replay")).GetAttribute("code");
        com = ((XmlElement)root.SelectSingleNode("port")).GetAttribute("com");
    }
}

接下来是串口通讯的base类

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.IO.Ports;
using System.Threading;
using UnityEngine.Events;

public class RelayBase : MonoBehaviour
{
    private SerialPort sp;
    private string com;
    private Thread recvThread;
    private string recvStr = "";
    private UnityAction<string> recvAction;
    private int recvLen;

    protected int requestLen;
    public string RecvStr
    {
        get { return recvStr; }
        set
        {
            recvStr = value;
        }
    }

    protected virtual void Start()
    {
        recvThread = new Thread(Recv);
        recvThread.Start();
    }


    private void Update()
    {
        if (recvAction != null)
            recvAction.Invoke(RecvStr);
    }

    private void OnApplicationQuit()
    {
        sp.Close();
        if (recvThread != null)
        {
            recvThread.Interrupt();
            recvThread.Abort();
        }
    }


    void Recv()
    {
        byte[] recvBuf = new byte[16];
        string str = "";
        while (true)
        {
            if (sp.IsOpen)
                recvLen = sp.Read(recvBuf, 0, 16);
            if (recvLen > 0)
            {
                for (int i = 0; i < recvLen; i++)
                {
                    str += recvBuf[i].ToString("X2");
                }
                if (str.Length < requestLen)
                    continue;
                RecvStr = str;
                recvAction += delegate (string s)
                {
                    Debug.Log(s);
                    ReceivedCallBack(s);
                    recvAction = null;
                };
                str = "";
                sp.DiscardInBuffer();
                //Thread.Sleep(150);
            }
        }
    }

    protected virtual void ReceivedCallBack(string s)
    {

    }

    protected void InitSerialPort(string com)
    {
        sp = new SerialPort(com, 9600, Parity.None, 8, StopBits.One);
        try
        {
            sp.Open();
        }
        catch
        {
            Debug.Log("串口打开失败");
        }
    }

}

然后是继承RelayBase的脚本,用来接收面板发出的信号:

public class Relay_xuTing : RelayBase
{
    protected override void ReceivedCallBack(string s)
    {
        if (s == Config_XuTing.instance.play_code)
            SystemManager_XuTing.instance.PlayClick();
        else if (s == Config_XuTing.instance.pause_code)
            SystemManager_XuTing.instance.PauseClick();
        else if (s == Config_XuTing.instance.replay_code)
            SystemManager_XuTing.instance.ReplayClick();
        //else if (s == Config_XuTing.instance.stop_code)
        //    SystemManager_XuTing.instance.StopClick();
    }
    protected override void Start()
    {
        InitSerialPort(Config_XuTing.instance.com);
        requestLen = Config_XuTing.instance.play_code.Length;
        base.Start();
    }
}

最后就是UI脚本了SystemManager_XuTing,UI用了AVProVideo插件来播放视频

一个背景UGUI用来播放待机画面的视频,另外一个用来播放主视频,根据收到的串口信号,调用SystemManager_XuTing中播放,暂停和重播方法。

主要脚本都在上面,其中需要将xml文件和需要播放的视频放在StreamingAssets文件夹下,这样打包出来可以随时修改。

 

  • 6
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
Unity与RS485通信可以通过使用SerialPort类来实。SerialPort类提供了与串行端口进行通信的功能。 首先,你需要确保你的电脑上已经连接了RS485设备,并且你知道该设备的串口号。在Unity中,你可以使用以下代码来实现与RS485设备的通信: ```csharp using System.IO.Ports; public class RS485Communication : MonoBehaviour { SerialPort serialPort; void Start() { // 设置串口号和波特率 string portName = "COM1"; // 替换为你的串口号 int baudRate = 9600; // 替换为你的波特率 serialPort = new SerialPort(portName, baudRate); // 打开串口 serialPort.Open(); } void Update() { // 发送数据 string dataToSend = "Hello, RS485!"; serialPort.WriteLine(dataToSend); // 接收数据 string receivedData = serialPort.ReadLine(); Debug.Log("Received data: " + receivedData); } void OnDestroy() { // 关闭串口 if (serialPort != null && serialPort.IsOpen) { serialPort.Close(); } } } ``` 在上面的代码中,我们首先在Start()方法中设置了串口号和波特率,并打开了串口。然后,在Update()方法中,我们可以使用serialPort.WriteLine()方法发送数据到RS485设备,使用serialPort.ReadLine()方法读取从设备接收到的数据。最后,在OnDestroy()方法中,我们关闭了串口。 请注意,上述代码仅为示例,你需要将"COM1"和9600替换为你实际使用的串口号和波特率。此外,你还可以根据需要在Update()方法中添加其他逻辑来处理RS485通信。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

hzTom11

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

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

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

打赏作者

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

抵扣说明:

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

余额充值