Unity串口通訊

1、串口簡介編程

 串行接口(串口)一般指COM接口,是採用串行通訊方式的擴展接口。串口按位(bit)發送和接收字節。儘管比按字節(byte)的並行通訊慢,可是串口能夠在使用一根線發送數據的同時用另外一根線接收數據。特別適用於遠距離通訊。數組

1、查看串口:右鍵 個人電腦-管理-設備管理器-端口,選擇一個端口,雙擊查看屬性。微信

二、 串口屬性:從上圖中能夠看到串口屬性,串口通訊最重要的屬性參數是波特率、數據位、中止位和奇偶校驗。對於兩個進行通訊的端口,這些參數必須匹配。工具

(1)波特率:這是一個衡量符號傳輸速率的參數。指的是信號被調製之後在單位時間內的變化,即單位時間內載波參數變化的次數,如每秒鐘傳送960個字符,而每一個字符格式包含10位(1個起始位,1箇中止位,8個數據位),這時的波特率爲960Bd,比特率爲10位*960個/秒=9600bps。學習

(2)數據位:這是衡量通訊中實際數據位的參數。當計算機發送一個信息包,實際的數據每每不會是8位的,標準的值是六、7和8位。標準的ASCII碼是0~127(7位),擴展的ASCII碼是0~255(8位)。測試

(3)中止位:用於表示單個包的最後幾位。典型的值爲1,1.5和2位。因爲數據是在傳輸線上定時的,而且每個設備有其本身的時鐘,極可能在通訊中兩臺設備間出現了小小的不一樣步。所以中止位不只僅是表示傳輸的結束,而且提供計算機校訂時鐘同步的機會。ui

(4)校驗位:在串口通訊中一種簡單的檢錯方式。有四種檢錯方式:偶、奇、高和低。固然沒有校驗位也是能夠的。編碼

三、串口通訊原理:spa

串行接口在嵌入式系統中是一種重要的數據通訊接口,其本質功能是做爲CPU和串行設備間的編碼轉換器。在發送數據時,數據從CPU經串行端口,字節數據轉換爲串行的位;在接收數據時,串行的位轉換爲字節數據。設計

四、經常使用的協議:

RS-232: 標準串口,最經常使用的一種串行通信接口採起不平衡傳輸方式,即所謂單端通信, 是爲點對點通信而設計的。

RS-422: 支持點對多的雙向通訊。採用單獨的發送和接收通道,所以沒必要控制數據方向,各裝置之間任何須須的信號交換都可以按軟件方式(XON/XOFF握手)或硬件方式(一對單獨的雙絞線)實現。

RS-485: 從RS-422基礎上發展而來的, RS-485能夠採用二線與四線方式,二線制可實現真正的多點雙向通訊,而採用四線鏈接時,與RS-422同樣只能實現點對多的通訊,但它比RS-422有改進,不管四線仍是二線鏈接方式總線上可多接到32個設備。

串口的接口標準規範9針串口:

針腳功能:

一、數據載波檢測(DCD)      

二、串口接收數據(RXD)   

三、串口發出數據(TXD)

四、數據終端就緒(DTR)

五、信號地線(GND)

六、數據發送就緒(DSR)

七、發送數據請求(RTS)

八、清除發送(CTS)

九、鈴聲指示(RI)

2、使用C#和Unity進行串口編程

在對串口進行編程時候,咱們要向串口發送指令,而後咱們解析串口返回的指令。從.NET Framework 2.0開始,C#提供了SerialPort類用於實現串口控制。命名空間:System.IO.Ports。詳細信息能夠參看(MSDN技術文檔

一、 經常使用的字段:

PortName:獲取或設置通訊端口

BaudRate:獲取或設置串行波特率

DataBits:獲取或設置每一個字節的標準數據位長度

Parity:獲取或設置奇偶效驗檢查協議

StopBits:獲取或設置每一個字節的標準中止位數

二、 經常使用方法:

Close:關閉端口鏈接,將IsOpen屬性設置false,並釋放內部Stream對象

GetPortNames:獲取當前計算機的串行端口名稱數組

Open:打開一個新的串行端口鏈接

Read:從SerialPort輸入緩衝區中讀取

Write:將數據寫入串行端口輸出緩衝區

三、經常使用事件:

DataReceived:表示將處理SerialPort對象的數據接收事件的方法

DisPosed:經過調用釋放組件時發生Dispose方法(繼承自Component)

四、SerialPort 控件使用流程

流程是設置通訊端口號及波特率、數據位、中止位和校驗位,再打開端口鏈接、發送數據、接收數據,最後關閉端口鏈接步驟。

 3、編程遇到的問題

一、沒有將Unity3D的API平臺切換成.NET2.0,這時Unity編寫SerialPort類會報錯。

解決方法:將Unity3D的API平臺切換成.NET2.0,切換方法: 「Edit–>project Setting–>Player–>Other Setting –>Api Compatibility level」。在這裏將「.NET2.0 Subset」切換爲「.NET2.0」

二、Unity的目標平臺沒有切換爲Windows平臺,會提示該命名空間不支持SystemIO,提示你切換工具。

解決方法:把目標平臺切換爲Windows平臺,不然是其餘平臺會報錯誤。

三、串口發送的信息不能正常解析

解決方法:把串口發送的消息使用字節流進行轉換。(字符流轉換)

四、串口接收信息的缺失問題

(1)接收字符串(string):port.ReadLine()

數據接收可能錯誤,數據丟失,數據接收不到

(2)接收字節數組(byte[]):port.Read()

接收數據斷層,會分兩次接收完整數據

(3)接收單個字節(byte):port.ReadByte()

將接收到的數據進行組合

代碼能夠直接使用,測試有效,直接複製到Unity腳本中和串口調試助手配合使用便可。

 

  1 using UnityEngine;
  2 using System.Collections;
  3 using System.IO.Ports;
  4 using System;
  5 using System.Collections.Generic;
  6 using System.Threading;
  7 using System.Text;
  8 
  9 public class PortControl : MonoBehaviour
 10 {
 11     #region 定義串口屬性
 12     public GUIText gui;
 13     //public GUIText Test;
 14     //定義基本信息
 15     public string portName = "COM3";//串口名
 16     public int baudRate = 9600;//波特率
 17     public Parity parity = Parity.None;//效驗位
 18     public int dataBits = 8;//數據位
 19     public StopBits stopBits = StopBits.One;//中止位
 20     SerialPort sp = null;
 21     Thread dataReceiveThread;
 22     //發送的消息
 23     string message = "";
 24     public List<byte> listReceive = new List<byte>();
 25     char[] strchar = new char[100];//接收的字符信息轉換爲字符數組信息
 26     string str;
 27     #endregion
 28     void Start()
 29     {
 30         OpenPort();
 31         dataReceiveThread = new Thread(new ThreadStart(DataReceiveFunction));
 32         dataReceiveThread.Start();
 33     }
 34     void Update()
 35     {
 36 
 37     }
 38 
 39     #region 建立串口,並打開串口
 40     public void OpenPort()
 41     {
 42         //建立串口
 43         sp = new SerialPort(portName, baudRate, parity, dataBits, stopBits);
 44         sp.ReadTimeout = 400;
 45         try
 46         {
 47             sp.Open();
 48         }
 49         catch (Exception ex)
 50         {
 51             Debug.Log(ex.Message);
 52         }
 53     }
 54     #endregion
 55 
 56 
 57 
 58     #region 程序退出時關閉串口
 59     void OnApplicationQuit()
 60     {
 61         ClosePort();
 62     }
 63     public void ClosePort()
 64     {
 65         try
 66         {
 67             sp.Close();
 68             dataReceiveThread.Abort();
 69         }
 70         catch (Exception ex)
 71         {
 72             Debug.Log(ex.Message);
 73         }
 74     }
 75     #endregion
 76 
 77 
 78     /// <summary>
 79     /// 打印接收的信息
 80     /// </summary>
 81     void PrintData()
 82     {
 83         for (int i = 0; i < listReceive.Count; i++)
 84         {
 85             strchar[i] = (char)(listReceive[i]);
 86             str = new string(strchar);
 87         }
 88         Debug.Log(str);
 89     }
 90 
 91     #region 接收數據
 92     void DataReceiveFunction()
 93     {
 94         #region 按單個字節發送處理信息,不能接收中文
 95         //while (sp != null && sp.IsOpen)
 96         //{
 97         //    Thread.Sleep(1);
 98         //    try
 99         //    {
100         //        byte addr = Convert.ToByte(sp.ReadByte());
101         //        sp.DiscardInBuffer();
102         //        listReceive.Add(addr);
103         //        PrintData();
104         //    }
105         //    catch
106         //    {
107         //        //listReceive.Clear();
108         //    }
109         //} 
110         #endregion
111 
112 
113         #region 按字節數組發送處理信息,信息缺失
114         byte[] buffer = new byte[1024];
115         int bytes = 0;
116         while (true)
117         {
118             if (sp != null && sp.IsOpen)
119             {
120                 try
121                 {
122                     bytes = sp.Read(buffer, 0, buffer.Length);//接收字節
123                     if (bytes == 0)
124                     {
125                         continue;
126                     }
127                     else
128                     {
129                         string strbytes = Encoding.Default.GetString(buffer);
130                         Debug.Log(strbytes);
131                     }
132                 }
133                 catch (Exception ex)
134                 {
135                     if (ex.GetType() != typeof(ThreadAbortException))
136                     {
137                     }
138                 }
139             }
140             Thread.Sleep(10);
141         }
142         #endregion
143     }
144     #endregion
145 
146 
147 
148     #region 發送數據
149     public void WriteData(string dataStr)
150     {
151         if (sp.IsOpen)
152         {
153             sp.Write(dataStr);
154         }
155     }
156     void OnGUI()
157     {
158         message = GUILayout.TextField(message);
159         if (GUILayout.Button("Send Input"))
160         {
161             WriteData(message);
162         }
163         string test = "AA BB 01 12345 01AB 0@ab 發送";//測試字符串
164         if (GUILayout.Button("Send Test"))
165         {
166             WriteData(test);
167         }
168     }
169     #endregion
170 }

 

 

 

最後爲我微信公衆號引個流,歡迎你們關注個人微信公衆號,你們一塊兒學習一塊兒進步

相關文章
相關標籤/搜索