2022/3/2

開發版序列埠高速傳輸錯誤問題

 請問要如何用serial port傳180000 bytes 左右的資料?

我使用的board是teensy4.0, ram 有1024KB, 存的下這麼多
但目前傳輸到60000 bytes左右時就會出現問題,會有近10000bytes遺失,但接下來的又能繼續傳輸。我懷疑是serial buffer滿了,所以每傳30000 bytes我就Serial.flush()且delayMicroseconds(20000)。但沒有改善,請問這是因為Serial buffer溢位?又要如何解決呢?

[解決方式]
首先謝謝各位的建議。結果這個問題源自於我PC端接收。
我PC端用的是python的pyserial,在接收時,我把數字先轉成ascii再傳(因為我要傳很多筆,中間用\t隔開,若直接傳byte可能會有誤讀)
具體作法是:第一個進來的int*10+第二個
但我中間打錯,*變成**(次方),由於python資料結構會自動延長,結果傳70進來時變成10^70,電腦端延遲了。修改後就能順利傳資料。
不過在我發現這個bug前,我還是成功傳了數字。用的是Serial.availableForWrite(), 基本上是寫一個while loop,檢查已傳多少byte,沒有傳完就繼續寫。不過要給一點餘裕,比方說Serial.availableForWrite()回傳100 bytes,那下一個迴圈我只寫入50 bytes,這樣最穩。
總而言之,謝謝各位幫忙


為了相容於舊系統,把baud rate 降低到9600以下,打個比較複雜的console 畫面,很容易就會發生,會被serial.write 卡住,其實不太好處理。


去年11月,我有試著降低傳輸速度,看能否研發出好的解決方案,試驗結果是,爛的傳輸線是扶不起的阿斗,程式越改越糟,徒然自找麻煩。螢幕前面是用 ESP32 充當邏輯分析儀,讀取 FPGA 輸出的簡單固定頻率的方波(1:1 duty cycle)


高速的處理器如果跟電腦連,windows下必須用 overlapped 結構處理,否則資料極易 loss, 如果是跟 mac 連,這我就沒經驗了
我在 PC 高速傳輸時會遇到線材太爛,傳輸錯誤率飆高的問題,除了更換纜線之外,我很努力嘗試加強電腦檢測錯誤資料的能力,但程式越寫大,效率就越差




低速的 Arduino 極少有問題,但在高速裝置、設定超過幾百 kbps, 我是遇到「穩的時候大約十幾秒沒問題,但我拿個電源線在旁干擾,很快就出錯,而且出錯後很難回復穩定,要先先停止傳輸數秒,然後再重啟傳輸,這招也不是每次都有效」


1. 改一下baud rate, 因為 baud rate 是由mcu震盪頻率除頻而來, 有些速率不是剛好整除, 導致每個 pulse 寬度有誤差, 連續傳送時, 時間造成的 jitter 會累積, 然後接收端就會解碼錯誤, 所以要找一個可以整除的速率, 甚至可能要改變mcu的震盪頻率, 這個問題在早期8051時代, 使用12Mhz震盪器就會有這個問題, 要使用11.059Mhz才能正確收發. 解決這個問題可以先寫一個程式測試傳送多少byte會有錯誤, 例如傳送資料0,1,2,... 每次加1, 這樣接收端就很容易查出來有問題, 然後就可以知道每隔多久要休息一下才能繼續傳送, 最笨就是每1個byte休息一次. 每傳30000 bytes休息一次並沒有甚麼根據, 只是隨意猜測, 結果一定不對.
2. 發送端用2bit停止位元, 例如N82, 這樣可以拉長byte之間的間隔時間, 接收端依然用N81, 這樣就能抓到每個byte的起始位元脈波
3. 用示波器看波形, 線路阻抗與傳送 baud 不匹配時, 可能自己就會造成震盪干擾, 或者TX訊號串音干擾到RX, 這個在較長線路時容易發生, 有時降低 baud 也能改善
4. buffer問題有分軟體與硬體, 通常現在的uart晶片硬體內建buffer有16~256bytes, 軟體則視宣告而定, 例如可以查看 C:\Program Files (x86)\Arduino\hardware\arduino\avr\cores\arduino錄下 HardwareSerial.h 裡面的宣告, 這可以透過計算得知會不會滿, 例如buffer有64 bytes, 用你的baud傳送64 bytes需要多少時間, 你的接收端能否在這段時間回應處理, 若真的只是buffer滿的問題, 可以加上同步方法, 文字資料可以用軟體XON/XOFF同步, 二進位資料只能用硬體CTS/RTS同步


180k 有點操,你的uart 標準只有115200 如果好一點也許可以擴展2-4倍。但是你在看一下protocol 要再吃掉至少20%。uart 並不是甚麼高速傳輸好的東西,另外inband sync要看你的機制。 如果資料量要到連續的同步,dual buffer 或是cycling buffer 也是不可少的機制



目前用 atmel 的 51 系列,因為速度不快,資料量不夠大,甚少發生傳輸錯誤,在高速、大量的情形下,最好是有像古代的 DTR, RTS 功能。我之前做的邏輯分析儀,在阿丟諾的板子跑很順,但其實是資料總量相對於電腦的處理能力小很多,電腦側游刃有餘難出包。但在 ESP32 對電腦開 500kbps, 猛產生中斷逼 ESP32 狂送資料,電腦側開始漏接或數據錯誤,即使重傳也是繼續錯誤 (自訂 CRC 檢查數值異常)..











沒有留言:

張貼留言