日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

untiy 串口通信

發布時間:2024/1/8 编程问答 33 豆豆
生活随笔 收集整理的這篇文章主要介紹了 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中無法使用

SerialPort s;private void Awake(){s.DataReceived += ReceiveData; }private void ReceiveData(object sender, SerialDataReceivedEventArgs e){//讀取串口緩沖區的字節數據byte[] result = new byte[s.BytesToRead];}

以下是批量查找串口,批量接收消息,批量關閉

批量查找

/// <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 串口通信的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。