untiy 串口通信
生活随笔
收集整理的這篇文章主要介紹了
untiy 串口通信
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
untiy的串口通信是垃圾中的垃圾,只能使用線程監聽串口消息,而不能使用c#提供的更方便安全的注冊委托的方法,根本原因是mono沒有完全實現c#的using System.IO.Ports下的內容,導致unity中只能用被閹割過的串口
首先,引入命名空間
using System.IO.Ports;這是一個最簡單的開啟串口的演示
SerialPort s = new SerialPort{//串口的名字 波特率 數據位 停止位 驗證位 必須和硬件中設置相同,否則無法正常通信PortName = "COM1",//串口的名字可以通過設備管理器的 “端口”查看BaudRate = 115200,//波特率DataBits = 8,//數據位StopBits = StopBits.One,//停止位Parity = Parity.None,//驗證位DtrEnable = true,RtsEnable = true,ReadTimeout = 1000};s.Open();對于一個串口,我們可以通過一個線程監聽串口發過來的消息
//接上放代碼,打開一個串口s.Open();//監聽當前串口的消息Thread recT = new Thread(SerialPort_DataReceived);recT.IsBackground = true;recT.Start();//接收線程的方法public void SerialPort_DataReceived(){while (true){if (s.IsOpen){var length = s.BytesToRead;byte[] bytestest = new byte[length];s.Read(bytestest, 0, length); //得把數據讀出來,不然緩存區域會一直有數據//處理數據}}}關閉串口
s.Close();對于純c# 代碼,可以使用委托更優雅的接收串口消息,因為線程接收的方式可以能出現數據粘包
但這個委托在Untiy中無法使用
以下是批量查找串口,批量接收消息,批量關閉
批量查找
/// <summary>/// 獲取本地可用串口列表/// </summary>/// <param name="ignoreCom1">是否忽略串口1 PC機默認有COM1</param>/// <returns>返回串口名稱列表</returns>public List<SerialPort> GetPorts(bool ignoreCom1 = true){Ports = new List<SerialPort>();string[] proteNames = System.IO.Ports.SerialPort.GetPortNames();foreach (string protName in proteNames){if (ignoreCom1 && protName == "COM1") continue;// if ( protName != "COM4"&&protName != "COM5") continue;var s = new SerialPort{PortName = protName,BaudRate = 115200,DataBits = 8,StopBits = StopBits.One,Parity = Parity.None,DtrEnable = true,RtsEnable = true,ReadTimeout = 1000};Ports.Add(s);}return Ports;}批量接收
/// <summary>/// 打開串口(包括新啟動和再次啟動)/// </summary>/// <returns></returns>public bool Start(){try{GetPorts();如果串口開啟了就關閉//Stop();foreach (SerialPort p in Ports){try{//開啟當前的串口p.Open();//監聽當前串口的消息Thread recT = new Thread(SerialPort_DataReceived);recT.IsBackground = true;recT.Start(p);threadsDic.Add(p, recT);}catch (Exception ex){Console.WriteLine($"打開串口{p.PortName}時發生錯誤{ex.Message}");}}return true;}catch (Exception e){Console.WriteLine(DateTime.Now.ToShortDateString() + e.Message + e.StackTrace);return false;}}/// <summary>/// 接收信號觸發事件/// </summary>/// <param name="sender"></param>/// <param name="e"></param>public void SerialPort_DataReceived(object obj){while (true){SerialPort tempPort = obj as SerialPort;//更新最后獲取信號的時間//UpdateSignalTime?.Invoke(DateTime.Now, 0);//進行數據分包if (tempPort.IsOpen){var length = tempPort.BytesToRead;//對異常數據進行分包if (length > 32) //這里是32位是因為我規定的硬件發送一條數據為32個字節{byte[] bytestest = new byte[length];tempPort.Read(bytestest, 0, length); //得把數據讀出來,不然緩存區域會一直有數據ShuntPacker(tempPort, bytestest);continue;}//少包丟棄else if (length < 32){continue;}byte[] bytes = new byte[length];tempPort.Read(bytes, 0, length); //得把數據讀出來,不然緩存區域會一直有數據//處理一個包的數據OnePackerHandle(tempPort, bytes);}else{Console.WriteLine("串口非正常關閉");}}}批量關閉
/// <summary>/// 關閉所有串口 清空緩存數據 清空監聽線程/// </summary>/// <returns></returns>public void StopAllSerialPort(){foreach (SerialPort p in Ports){StopOneSerialPort(p);}lastStr = null;ReceivedData = null;lock (lockAck){if (AckCache != null && AckCache.Count > 0){AckCache.Clear();}}}/// <summary>/// 關閉一個串口/// </summary>/// <param name="serialPort"></param>public void StopOneSerialPort(SerialPort serialPort){try{if (serialPort != null && serialPort.IsOpen){//關閉串口serialPort.Close();//關閉接收線程threadsDic[serialPort].Abort();threadsDic.Remove(serialPort);}}catch (Exception e){// LogInfo.WriteErrorLog(e.Message + "|||" + e.StackTrace);}}總結
以上是生活随笔為你收集整理的untiy 串口通信的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux手动安装JDK并配置多个版本J
- 下一篇: 面试B站,结果面试官牵着一条狗出来面试我