unity的串口编程

本文介绍了使用Unity进行串口编程遇到的挑战和解决方案。由于Unity对串口支持有限,作者通过多线程处理接收和数据处理,以及定时器监控数据接收状态。文章详细讨论了不同串口数据格式的处理策略,并提供了测试方法。通过这种方式,作者模拟了Unity不支持的DataReceived事件。
摘要由CSDN通过智能技术生成

        第一次在csdn上写文章,各种格式之类的完全不熟悉,请见谅。 串口是用来做pc端中控程序与硬件对接的,本来嘛,可以用c++或者vs的wpf这些来做的,但实际上做出来的界面比较丑,很难做得好,也试过用flash加载ane来做串口,但flash貌似有可能被淘汰了,所以现在选择用unity来做中控程序界面试试,感觉有点大材小用了。

         一开始以为unity可以采用c#编程,那么串口就应该不会有什么问题了,但其实不是,unity貌似对串口支持不算很好,会出现各种意想不到的事情。测试了几个,才找到一个可以使用的代码,链接如下:http://www.cnblogs.com/zhaozhengling/p/3696251.html,采用两个线程一个接收,一个处理。但在这里有个缺点,他是一次处理固定的数据长度,但接收数据的长度有时未必固定,或者是只要有一个数据丢失,后面的数据将会全部错误。

         上述链接中最致命的缺点在于没有适当清空liststr的数据,当出现各种意外,使得某次发送长度大于所需长度时,下一次的计算就会从多出的数据开始计算长度。那么解决的方式也很简单。开启个定时器计数,时间间隔为inftimer,定时刷新检测liststr的长度,如果liststr.Count不为0,也就是数据在接收中,当下次liststr.Count大于上次,表示在接收中,否则接收完毕并重置清零。代码如下:

 /****************长时间没继续接收到数据,默认输出读取到的数据,并清空数据**************/
            if (liststr.Count != 0)
            {
                timer -= Time.deltaTime;
                if (timer <= 0)
                {              
                        if (liststr.Count > countcom)
                        {
                            countcom = liststr.Count;
                        }
                        else
                        {                     
                                Porthandle();                //处理函数                       
                        }                  
                    timer = inftimer;
                }
            }        

       在这里会引起其它的问题,一:串口读取后有一个延迟,取决于设定的inftimer的大小;二:这里是读取完数据后才响应的,对于数据连续循环的时候,将毫无办法,然而很多硬件的串口数据其实是不停的。我们着重对处理函数做修改,代码已经补充了很多了,代码如下:

       

using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO.Ports;
using System.Linq;
using System.Threading;
using UnityEngine;
using System.Collections;




/// <summary>
/// C#用SerialPort类实现串口编程
/// </summary>
public class MePortDataHandle : MonoBehaviour
{
    public bool Specialformat = false;   //特殊格式项选择
    public bool Continuousreading = true;  //是否连续读取
    List<byte> liststr;//在ListByte中读取数据,用于做数据处理
    List<byte> ListByte;//存放读取的串口数据


    int Frameheadloopindex = 0;    //用于循环计数判断


    bool isFrameheadmain = false;  //判断是否接收到开始符
    bool[] isFramehead;          //开始符每一个对应的校正对应符
    public string[] Framehead;   //帧头1:字符的ASCII的16进制表示
    int Headtruecount = 0;      //开始校验正确位计算
    bool initFrameheadmain = true; //是否是第一次前缀判断结束


    bool isEnddatamain = false; //判断是否接收到结束符
    bool[] isEnddata;           //结束符每一个对应的校正对应符
    public string[] Enddata;    //结束符1:字符的ASCII的16进制表示
    int Endtruecount = 0;       //结束校验正确位计算     




    private Thread tPort;    //读取串口数据的线程
    private Thread tPortDeal;//处理数据的线程
    bool isStartThread;//控制FixedUpdate里面的两个线程是否调用(当准备调用串口的Close方法时设置为false)
    public SerialPort spstart; //串口变量
    public ComType Comnow=ComType.COM1;     //串口选择
    public BaudRateType BaudRatenow=BaudRateType.B9600;  //波特率选择




    public float inftimer = 0.05f;     //串口读取超时参数
    float timer;                      //串口读取超时变量
    int countcom = 0;                 //串口读取超时辅助计数


    public int revlenght=-1;           //在无前后缀的时候,读取数据的长度
    private byte[] tempArr;           //读取到的byte数据
    /****************输出16进制字符串****************************/
    private string temp16String;      //读取到的16进制字符串数据
    private string tempString;        //读取到的字符串




    private string NoSpecialformatstr16=null;
    private string NoSpecialformatstr=null;
    public MeRevPortclass MeNoSpecialPortdata = new MeRevPortclass();


    private string Specialformatstr16 = null;
    private string Specialformatstr = null;
    public MeRevPortclass MeSpecialPortdata = new MeRevPortclass();
















    void Start()
    {      
        if (Specialformat)
        {
            Continuousreading = false;
        }
        timer = inftimer;
        InitJudgementsign();
        OpenSerialPort(Comnow.ToString(), (int)BaudRatenow);
    }


    /****************开启串口函数***************/
    void OpenSerialPort(string portName, int BaudRateindex)
    {
        isStartThread = true;
        liststr = new List<byte>();
        ListByte = new List<byte>();
 
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值