串口基本流给出部分/扰乱/重复的数据

我目前正在编写一个简单的应用程序,它将通过 ftdi232 芯片(串行端口)与基于 arduino 的设备进行通信

我在基流读取方面遇到了困难 - 我的应用程序在虚拟端口(com0com)上测试时运行良好,但是当我切换到 ftdi 设备时,接收到的数据变得混乱和/或重复。

发送和接收端口配置相同:

  • 19200波特率

  • 8 个数据位

  • 奇偶校验 = 无

  • 停止位 = 1

  • dtr 和 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);

                }                   



茅侃侃
浏览 71回答 1
1回答

开心每一天1111

我找到了解决办法!在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 数组。
打开App,查看更多内容
随时随地看视频慕课网APP