一篇文章学会Unity/C#串口通信(图文、虚拟串口下载\使用,unity22亲测可实现)

unity是一款强大的游戏引擎,我们可以利用unity实现一些仿真需求,这就需要用到串口。

c#的标准库里是提供串口的api,详细了解可以去看微软跌的官方文档:

SerialPort 类The Port

这里简单讲述一下使用方法

参考了这位老哥的文章:

Unity3D 串口通讯(二)---进行串口通讯

首先为了调试方便,需要虚拟串口,可以在这里下载学习版:

https://www.xue51.com/soft/9349.html

按照教程破解,然后打开,启动虚拟串口

 我这里用的是1、2串口

扫描二维码关注公众号,回复: 17332742 查看本文章

串口助手不必多说我用的是XCOM

 (注意这里是串口1,发送端,我们脚本里需要启动串口2来接收)

ok现在打开unity,新建一个项目,新建一个脚本

还有一个东西要准备,需要将unity的NET版本改成2.0

打开Player Setting,将Configuration中的Api Compatibility level设置为.Net2.0

22的话选择.NET Framework

 好,然后新建一个脚本

 串口初始化,我是写在Awake()里的,写在start()里应该也行

    public SerialPort uart;
    void Awake()
    {
        uart = new SerialPort
        {
            PortName = "COM2",//串口号
            BaudRate = 115200,//波特率
            DataBits = 8,//数据位
            StopBits = StopBits.One,//停止位
            Parity = Parity.None,//验证位
            DtrEnable = true,
            RtsEnable = true,
            ReadTimeout = 1000
        };
        
        uart.Open();//启动串口
        
        Thread recT = new Thread(SerialPort_DataReceived);
        recT.IsBackground = true;
        recT.Start();
    }

我们不用Update()方法接收,太慢了,每帧才执行一次,需要单独开一个线程,这里就开了一个

public void SerialPort_DataReceived()
    {

        while (true)
        {
            if (uart.IsOpen)
            {
                var length = uart.BytesToRead;//获取接收字符串长度
                if (length > 0)//大于0的话才会接收
                {
                    byte[] bytestest = new byte[length];
                    uart.Read(bytestest, 0, length);
                    Debug.Log(System.Text.Encoding.UTF8.GetString(bytestest));
                    //以日志的形式输出到控制台
                } 
                
            }
        }
    }

看一下执行效果:

 可以看到接收到了字符串

现在还有一个问题,我们做仿真的话,发送速度会非常快,这种时候我们用10ms定时发送看一下会怎么样:

 可以看到因为发送速度过快,导致接收的字符串有截断的情况

这里可以用SerialPort提供的ReadTo方法

 接收函数可以改成这样:

 public void SerialPort_DataReceived()
    {
        while (true)
        {
            if (uart.IsOpen)
            {
                var length = uart.BytesToRead;
                if (length > 0)
                {
                    Debug.Log(uart.ReadTo("E"));
                    uart.DiscardInBuffer();
                } 
            }
        }
    }

我这里设置E为截至字符

注意,这里需要用DiscardInBuffer()清空缓冲区,不然会报超时异常

再看效果:

 没有出现截断问题。

希望能提供一些帮助

猜你喜欢

转载自blog.csdn.net/qq_38830492/article/details/131430581