????兩年來(lái)陸陸續(xù)續(xù)有朋友加我QQ或發(fā)郵件,討論串口相關(guān)的問(wèn)題,最終解決Unity串口通訊的問(wèn)題也從中解決掉了。思路有三種,等下我會(huì)詳細(xì)介紹。 后面的博客詳細(xì)介紹是我收錄兩年前寫(xiě)的博客,現(xiàn)在我已經(jīng)沒(méi)有往串口方向進(jìn)行開(kāi)發(fā)了,所以只能將一些思路分享給大家。
????解決方式一:將Unity串口通信數(shù)據(jù)模塊(接收與發(fā)送),用C++來(lái)實(shí)現(xiàn),這是最佳最好的解決方式。(最佳)
????解決方式二:用一個(gè)中間介程序去實(shí)現(xiàn),Unity串口通信模塊通過(guò)Socket發(fā)送給中介程序,中介程序在通過(guò)串口將信息發(fā)送到其他地方去。(其次)
????解決方式三:Unity接收串口數(shù)據(jù),進(jìn)行臨時(shí)存儲(chǔ),然后解析,從而分析出正確的串口數(shù)據(jù)。(不穩(wěn)定,局限性很高,需要實(shí)時(shí)接收串口數(shù)據(jù),并且還要進(jìn)行解析,防止數(shù)據(jù)接收錯(cuò)誤)
注:以下文章是我收錄兩年前記錄的CSDN博客。
一、簡(jiǎn)介
????1、我發(fā)布過(guò)一篇關(guān)于Unity的串口通信問(wèn)題,只是闡述了問(wèn)題,但是沒(méi)有什么好的解決方案。經(jīng)過(guò)我?guī)讉€(gè)對(duì)串口相關(guān)的Unity項(xiàng)目開(kāi)發(fā),也發(fā)現(xiàn)了幾種解決方案。開(kāi)發(fā)中遇到的一些問(wèn)題都詳細(xì)的描述出來(lái)。
????2、在上一篇文章我曾提過(guò)Unity因?yàn)椴捎玫氖荕ono .NET 2.0。這個(gè)版本對(duì)COM支持不是很好,所以導(dǎo)致Unity在串口通信方面有些問(wèn)題。不過(guò)最近發(fā)布了Mono .NET4.6版本的Unity 5.5測(cè)試版,該問(wèn)題可能會(huì)解決掉,不過(guò)可能需要等到2017年了。
????3、言歸正傳,我們首先要知道C#接收串口的主要幾種方式:接收字節(jié)byte,接收字節(jié)數(shù)據(jù)byte[],接收字符串string。在Unity中往串口中發(fā)送數(shù)據(jù)是為沒(méi)有問(wèn)題的,主要是接收數(shù)據(jù)會(huì)存在問(wèn)題,下面圖片我總結(jié)了一下,這結(jié)果是我經(jīng)過(guò)不下于100次測(cè)試而來(lái)的,可能每個(gè)人的測(cè)試結(jié)果都不一樣或我的測(cè)試還有一些局限。
????還有其他的串口讀取方法,但是我就沒(méi)有測(cè)試了,因?yàn)槲覍?shí)際項(xiàng)目中就需要這幾種,所以其他的我就不好意思說(shuō)。
二、Unity與Winform(WPF)串口通信的幾種解決方案
我開(kāi)發(fā)過(guò)三個(gè)項(xiàng)目采用收發(fā)字符串(Unity接收字符串,發(fā)送字符串)、收發(fā)單個(gè)字節(jié)(Unity接收單字節(jié),發(fā)送字節(jié)數(shù)組)、收發(fā)字節(jié)數(shù)組。三個(gè)項(xiàng)目都是Unity通過(guò)串口與Winform程序(或WPF程序)進(jìn)行串口通信。
項(xiàng)目一
????1、該項(xiàng)目有兩種串口接收方式,一種是收發(fā)字符串(Unity接收字符串,發(fā)送字符串),另一個(gè)是收單個(gè)字節(jié),然后對(duì)每個(gè)字節(jié)進(jìn)行組裝解析,在發(fā)送字節(jié)數(shù)組。
????2、經(jīng)過(guò)項(xiàng)目的開(kāi)發(fā)和測(cè)試,我發(fā)現(xiàn)收發(fā)字符串是沒(méi)有問(wèn)題的,但是在我自己寫(xiě)的測(cè)試程序中卻出現(xiàn)異常,出現(xiàn)數(shù)據(jù)錯(cuò)誤,數(shù)據(jù)丟失以及接收不到數(shù)據(jù)等隨機(jī)性錯(cuò)誤(第一篇關(guān)于串口文章)。不過(guò)經(jīng)過(guò)我發(fā)現(xiàn)實(shí)際項(xiàng)目中的串口收發(fā)格式是有標(biāo)記位和校驗(yàn)位,但是當(dāng)我自己寫(xiě)程序去測(cè)試時(shí),卻發(fā)現(xiàn)了異常。針對(duì)這個(gè)問(wèn)題我到時(shí)候后期會(huì)在進(jìn)行仔細(xì)研究下,因?yàn)槲椰F(xiàn)在也沒(méi)找到合適的理由去說(shuō)服自己以及讀者,所以我不會(huì)去做詳細(xì)的介紹只是提醒讀者,后期如果解決了我會(huì)在博客上寫(xiě)出來(lái)。
項(xiàng)目二
????1、該項(xiàng)目是接收字符串?dāng)?shù)組和發(fā)送字符串?dāng)?shù)組,在實(shí)際開(kāi)發(fā)項(xiàng)目中卻出現(xiàn)了Unity接收數(shù)據(jù)錯(cuò)誤的問(wèn)題,針對(duì)該問(wèn)題加上項(xiàng)目時(shí)間緊急,不可在此問(wèn)題耗費(fèi)我太大心力,所以無(wú)意中想到用中間件程序來(lái)做Unity與winform程序通信的一個(gè)橋梁。
????2、我寫(xiě)一個(gè)中間件程序,讓W(xué)inform程序與我的中間件程序進(jìn)行串口通信,中間件程序與Unity程序Socket通信。
????3、首先啟動(dòng)我的中間件程序,然后中間件程序啟動(dòng)我的Unity程序。中間件程序隱藏起來(lái)并與Unity程序互相監(jiān)聽(tīng),當(dāng)Unity程序關(guān)閉時(shí),中間件程序也關(guān)閉。這樣從表面上看起來(lái)就只是Unity一個(gè)程序在工作,實(shí)際上中間還有一個(gè)中間件程序在做幕后工作。從而巧妙的完成了所謂的Unity與Winform程序之間的串口通信。但是這終究不是一個(gè)很好的解決方案。
項(xiàng)目三
????1、這個(gè)項(xiàng)目三就是我們的重頭戲了,這也是我最新研究的一種解決方案,而且經(jīng)過(guò)測(cè)試和實(shí)際項(xiàng)目開(kāi)發(fā),也是沒(méi)什么很大問(wèn)題的,不過(guò)有個(gè)項(xiàng)目會(huì)有一些小問(wèn)題,但是被我很簡(jiǎn)單的解決掉了。后面我都會(huì)詳細(xì)的講解這個(gè)解決方案,如果有朋友與我闡述的不符,那么可以參考項(xiàng)目二的解決方案給您一點(diǎn)小思路。
????2、該項(xiàng)目采用的是什么呢,首先Winform程序往Unity中發(fā)送字節(jié)數(shù)組,從Unity中讀取字節(jié)數(shù)組數(shù)據(jù)。按照正常的邏輯上我們的Unity也應(yīng)該從串口中讀取字節(jié)數(shù)組和發(fā)送字節(jié)數(shù)組。但是在這一塊出現(xiàn)了問(wèn)題,上面圖片我闡述過(guò),Unity從串口接收字節(jié)數(shù)組時(shí)會(huì)出現(xiàn)需要兩次才能接收完,第一次接收一個(gè)字節(jié)第二次接收剩下的。數(shù)據(jù)倒不會(huì)出現(xiàn)異常,但是這對(duì)我們的數(shù)據(jù)處理顯然是不好的。針對(duì)此問(wèn)題,我下面一大章節(jié)來(lái)結(jié)合實(shí)際項(xiàng)目來(lái)解釋。
三、Unity解析串口數(shù)據(jù),得到完整數(shù)據(jù)
1、定義存儲(chǔ)串口數(shù)據(jù)變量

2、打開(kāi)串口

3、打印串口數(shù)據(jù)
這個(gè)打印串口數(shù)據(jù)是一個(gè)方法,就是在Unity中打印接收到的串口數(shù)據(jù),怕讀者看代碼是有點(diǎn)不懂這方法是干嘛的,所以我貼出來(lái)。

4、讀取串口數(shù)據(jù)

從winform程序中發(fā)送數(shù)據(jù)過(guò)去

Unity接收到的數(shù)據(jù)情況,發(fā)送數(shù)據(jù)經(jīng)過(guò)我們組合后是沒(méi)有問(wèn)題的。

但是當(dāng)我Unity中發(fā)送給上位機(jī)數(shù)據(jù)時(shí),突然unity串口中接收到一個(gè)00數(shù)據(jù),該測(cè)試不是從我寫(xiě)的測(cè)試程序測(cè)試的,而是從實(shí)際項(xiàng)目中測(cè)試的,但是我在自己寫(xiě)的測(cè)試程序中又沒(méi)有這個(gè)問(wèn)題。針對(duì)此結(jié)果加上一些數(shù)據(jù)規(guī)律,我后期自己進(jìn)行了改動(dòng)(后面會(huì)詳細(xì)介紹)。
經(jīng)過(guò)解析數(shù)據(jù),然后返回給Winform數(shù)據(jù),返回后突然又接到異常數(shù)據(jù)。

Winform接收到的數(shù)據(jù)

5、解析串口數(shù)據(jù)



六、總結(jié)
1、上述可能會(huì)讓一些讀者覺(jué)得有比較多的漏洞,我后續(xù)如果發(fā)現(xiàn)更好的解決方案和問(wèn)題,也會(huì)陸續(xù)更新。一方面是記錄下曾經(jīng)問(wèn)題方便以后,另一方面也是讓Unity開(kāi)發(fā)串口這邊的開(kāi)發(fā)者一個(gè)思路和想法吧。因?yàn)槲疑罡写颂幍目印?/p>
2、如果有讀者看到了,有一些好的解決方案、幫助等都可以聯(lián)系我,我們共同探討。關(guān)注我的公眾號(hào)(Hua灬清),每周推送原創(chuàng)技術(shù)博客。