亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

串口基本流給出部分/擾亂/重復的數據

串口基本流給出部分/擾亂/重復的數據

C#
茅侃侃 2023-12-17 16:51:41
我目前正在編寫一個簡單的應用程序,它將通過 ftdi232 芯片(串行端口)與基于 arduino 的設備進行通信我在基流讀取方面遇到了困難 - 我的應用程序在虛擬端口(com0com)上測試時運行良好,但是當我切換到 ftdi 設備時,接收到的數據變得混亂和/或重復。發送和接收端口配置相同:19200波特率8 個數據位奇偶校驗 = 無停止位 = 1dtr 和 rts 被禁用DiscardNull 已啟用。目前(測試)兩個 ftdi 板都連接到同一臺機器。 板通過 3 條線連接(rx、tx [交叉] 和接地)。有問題的方法:public async Task StartReceivingAsync()    {        _isLissening = true;        string errorData = string.Empty;        byte[] mainBuffer = new byte[_completeCommandSizeWithSep];        while(_port.IsOpen && !_receiveToken.IsCancellationRequested)        {                            int bytesRead = await _port.BaseStream.ReadAsync(mainBuffer, 0, _completeCommandSizeWithSep, _receiveToken);                            string rawData = Encoding.GetEncoding(_port.Encoding.CodePage).GetString(mainBuffer);            if(_port.Encoding.CodePage == Encoding.ASCII.CodePage)                _receivedBuffer.Append(RemoveNonAsciiChars(rawData));            else                _receivedBuffer.Append(rawData);            if(_receivedBuffer.Length >= _completeCommandSizeWithSep)            {                ICommandModel command = _commandModelFac();                string workPiece = _receivedBuffer.ToString(0, _completeCommandSizeWithSep);                int whereToCut = CheckRawData(workPiece);                if(whereToCut == -1)                {                    command.Data = workPiece;                    _receivedBuffer.Remove(0, _completeCommandSizeWithSep);                }                else if(whereToCut > 0)                {                    command.Data = _receivedBuffer.ToString(0, whereToCut);                    _receivedBuffer.Remove(0, whereToCut);                }                   
查看完整描述

1 回答

?
開心每一天1111

TA貢獻1836條經驗 獲得超13個贊

我找到了解決辦法!

StartReceivingAsync方法byte[] mainBuffer中初始化一次。
初始化后會出現“一會兒...”實際流讀取數據的循環。

我不知道 FTDI 芯片的確切規格,但在不斷發送時,它確實會以相當隨機的部分發送數據(發送方和接收方沒有超時)

所以,執行時
int bytesRead = await _port.BaseStream.ReadAsync(mainBuffer, 0, _completeCommandSizeWithSep, _receiveToken);
我會收到發送的數據的隨機部分。該數據將按照預期寫入 mainBuffer 字節數組,然后將其添加到 _receivedBuffer。

事情來了:mainBuffer 當流接收到小于 _completeCommandSizeWithSep 的數據部分時,不會被清理。
BaseStream 讀取器只是從 0 索引處替換收到的 mainBuffer 中的盡可能多的字符,忽略其余部分。

解決方法是僅添加長度等于 bytesRead 的子字符串 值而不是整個 mainBuffer 到接收緩沖區:

int bytesRead = await _port.BaseStream.ReadAsync(mainBuffer, 0, _completeCommandSizeWithSep, _receiveToken);


Bad code:

string rawData = Encoding.GetEncoding(_port.Encoding.CodePage).GetString(mainBuffer);


Working code:

string rawData = Encoding.GetEncoding(_port.Encoding.CodePage).GetString(mainBuffer).Substring(0, bytesRead);

替代解決方案是在 While 循環內重新初始化mainBuffer 數組。


查看完整回答
反對 回復 2023-12-17
  • 1 回答
  • 0 關注
  • 262 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號