Unity接硬件串口

一、PortControl脚本(硬件串口数据)

using UnityEngine;
using System.Collections;
using System.IO.Ports;
using System;
using System.Collections.Generic;
using System.Threading;
using System.Text;
using UnityEngine.UI;

public class PortControl : MonoBehaviour
{
    public static PortControl Instance;
 
    #region 定义串口属性
    //定义基本信息
    public string portName = "COM5";//串口名
    public int baudRate = 115200;//波特率
    public Parity parity = Parity.None;//效验位
    public int dataBits = 8;//数据位
    public StopBits stopBits = StopBits.One;//停止位
    public SerialPort sp = null;  
    public Thread dataReceiveThread;
    public Thread dataSendThread;
    //发送数据
    public List<byte> listReceive = new List<byte>();
    public Queue<byte[]> recBuffer = new Queue<byte[]>();//接受所有的buffer  队列 先进先出
    public Queue<byte[]> sendBuffer = new Queue<byte[]>();//发包  队列
    char[] strchar = new char[100];//接收的字符信息转换为字符数组信息
    string str;
    byte[] buffer = new byte[1024];
    byte[] receiveBuffer = new byte[1024];
    int receivePosition;
    #endregion
    void Start()
    {
        Instance = this;
        dataReceiveThread = new Thread(new ThreadStart(DataReceiveFunction));
        dataReceiveThread.Start();
        dataSendThread = new Thread(new ThreadStart(WriteData));
        dataSendThread.Start();
        //ThreadPool.QueueUserWorkItem(new WaitCallback(WriteData));
    }
 
    #region 创建串口,并打开串口
    public void OpenPort()
    {
        //创建串口
        sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
        sp.ReadTimeout =800;//操作超出时间 这个时间越长报错越少,但不能太长
        try
        {
            sp.Open();
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    #endregion
 
 
    #region 程序退出时关闭串口
    //void OnApplicationQuit()
    //{
    //    ClosePort();
    //}
    public void ClosePort()
    {
        try
        {
            sp.Close();
            dataReceiveThread.Abort();
        }
        catch (Exception ex)
        {
            Debug.Log(ex.Message);
        }
    }
    #endregion
 
 
    /// <summary>
    /// 打印接收的信息
    /// </summary>
    void PrintData()
    {
        for (int i = 0; i < listReceive.Count; i++)
        {
            strchar[i] = (char)(listReceive[i]);
            str = new string(strchar);
        }
        Debug.Log(str);
    }
 
    public byte[] Dispatch()
    {
        //判断接受的数据是否为空
        if (recBuffer.Count == 0) return null;       
        return recBuffer.Dequeue();//头部读取并删除       
    }
  
 
    #region 接收数据
    public void DataReceiveFunction()
    {
        #region 按字节数组发送处理信息,信息缺失      
 
        int bytes = 0;
        while (true)
        {
            if (sp != null && sp.IsOpen)
            {
                try
                {
                    bytes = 0;
                    bytes = sp.Read(buffer, 0, buffer.Length);//接收字节 数                      
                    if (bytes == 0)
                    {
                        continue;
                    }
                    else
                    {                      
                        Array.Copy(buffer, 0, receiveBuffer, receivePosition, bytes);
                        Array.Clear(buffer, 0, buffer.Length);//清空buffer数组
                        receivePosition += bytes;
                     
                        int index = 0;
                        while (index <= 50)
                        {
                            index++;
                            bool has7E = false;
                            //一串数中,第一个126
                            var first7E = receiveBuffer[index];
                            if (first7E == 0x7E)
                            {
                                has7E = true;
                                var head = receiveBuffer[0];//第一个刚才跳过了,现在额外判断
                                if (head == 0x7E)
                                {
                                    if (index == 16 || index == 7)
                                    {
                                        var bbuffer = new byte[index];
                                        Array.Copy(receiveBuffer, 0, bbuffer, 0, index);
 
                                        recBuffer.Enqueue(bbuffer);
                                      
                                    }
                                }
                                for (int i = 0; i < 50; i++)
                                {
                                    receiveBuffer[i] = receiveBuffer[index + i];
                                }
                                receivePosition -= index;
                                break;
                            }
 
                            if (index == 50 && has7E == false && receivePosition >= 50)
                            {
                                for (int i = 0; i < 50; i++)
                                {
                                    receiveBuffer[i] = receiveBuffer[index + i];
                                }
                                receivePosition -= index;
                            }
                        }
                    }
                }
                catch (Exception ex)
                {
                    if (ex.GetType() != typeof(ThreadAbortException))
                    {
 
                    }
                }
            }
            Thread.Sleep(10);
        }
    }
    #endregion
    #endregion
 
 
 
 
    #region 发送数据
    //public void WriteData(string dataStr)
    //{
    //    //传进来的是字符串
    //    if (sp.IsOpen)
    //    {
    //        sp.Write(dataStr);
    //    }
    //}
    //public void WriteData(byte[] buffer)
    //{
    //    //传进来的是十六进制的,例如:byte []byte1 =new byte[] { 0X7E, 0X02, 0X01, 0X00, 0X01, 0X01 };
    //    if (sp.IsOpen)
    //    {
    //        sp.Write(buffer, 0, buffer.Length);
    //    }
    //}
    public void WriteData()
    {              
        while (true)
        {
            if (sp.IsOpen)
            {
                try
                {
                    var datas = SendBuffer();
                    sp.Write(datas, 0, datas.Length);                  
                }
                catch (Exception ex)
                {
                    Debug.Log(ex .Message);
                }
            }
            Thread.Sleep(20);
        }
      
    }
    byte []SendBuffer()
    {
        if (sendBuffer.Count == 0)
        {
            byte[] buffer = new byte[] { 0X7E, 0X02, 0X01, 0X00, 0X01, 0X01 };
            return buffer;
        }
        else
        {
            return sendBuffer.Dequeue();
        }          
    }
   
    #endregion
 
}

二、PortDispose脚本 ( 串口数据读取处理)

using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using LitJson;
 
 
public class PortDispose : MonoBehaviour {
  
    public static PortDispose Instance;
    public PortControl control;
  
    private bool Ischange = false;
    public int stateValueDO1 = 0X05;//灯  送风阀和排风阀红灯亮
    public int stateValueDO2 = 0X09;//灯  1#启动灯 2#停止灯
    public int stateValueDI3 = 0X50;//按钮   送风阀自动 排风阀自动
    public int stateValueDI4 = 0X00;//按钮
    public int stateValueDO5 = 0X01;//灯  电源指示灯亮
    public int stateValueDO6 = 0X00;//灯
    public int stateValueDI7 = 0X10;//按钮   1#主2#备
    public int stateValueDI8 = 0X40;//按钮   pulse 自动
    public int stateValueDI9 = 0X00;
    public int stateValueDI10 = 0X00;
    public int SumValue;
 
 
    private void Awake()
    {
        Instance = this;
        Open();
    }
 
    void Update()
    {      
        if (control == null)
            return;
 
        DisposeData();
    }
   
    public bool IsOne(int bit, int which)
    {
        //是否可以按下这个按钮
        return (which & 1 << bit)!=0;
    }
    public void SetValue(int bit, ref int which,int isOn)
    {
        Ischange = true;
        //设置按钮/灯 状态
        if (isOn == 0)
        {
            which=which & ~(1 << bit);
        }
        else if (isOn == 1)
        {
            which =which | (1 << bit);
        }
    }
  
    private void DisposeData()
    {
        var datas = control.Dispatch();
        while (datas != null)
        {          
            //这里写接收到各种数据的处理逻辑     
            if (datas.Length == 16)
            {
                int sum = 0;
                //接收到的 按钮数据包 长度是16
                for (int i = 0; i < datas.Length; i++)
                {
                    //判断数据  校验和是否一致              
                    if (i > 4 && i < datas.Length - 1) sum += datas[i];                  
                }
                if (sum == datas[datas.Length - 1])
                {
                    //7E 01 02 0a 11 00 00 01 00 00 00 00 32 00 00 33(校验和)
                    stateValueDO1 = datas[5];
                    stateValueDO2 = datas[6];
                    stateValueDI3 = datas[7];
                    stateValueDI4 = datas[8];
                    stateValueDO5 = datas[9];
                    stateValueDO6 = datas[10];
                    stateValueDI7 = datas[11];
                    stateValueDI8 = datas[12];
                    stateValueDI9 = datas[13];
                    stateValueDI10 = datas[14];
                  
 
                    UpdateData();                 
                }
                else
                {
                    string itemstr="";
                    foreach (var item in datas)
                    {
                        itemstr += item+"  ";
                    }
                    Debug.Log(itemstr +"校验和不匹配");
                }
 
            }
            else if (datas.Length == 7)
            {
                if (datas[5] != 0) Debug.Log("灯 收包异常");              
            }
            datas = control.Dispatch();
        }
       
    }  

猜你喜欢

转载自blog.csdn.net/qq_41691338/article/details/106994481