串行端口 basestream 给出部分/加扰/重复数据
Serial port basestream gives partial / scrambled / duplicated data
我目前正在编写一个简单的应用程序,它将通过 ftdi232 芯片(串行端口)与基于 arduino 的设备进行通信
我遇到了基本流读取问题 - 我的应用程序在虚拟端口 (com0com) 上测试时运行良好,但当我切换到 ftdi 设备时,接收到的数据变得混乱和/或重复。
发送端口和接收端口配置相同:
- 19200波特率
- 8 个数据位
- 奇偶校验 = none
- 停止位 = 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);
}
if (whereToCut != 0)
command.CommandType = CommandType.Error;
else
{
command = CommandTranslator(workPiece);
_receivedBuffer.Remove(0, _completeCommandSizeWithSep);
}
DataReceived?.Invoke(this, command);
}
else
{
continue;
}
}
_isLissening = false;
}
发送方式:
while (true)
{
serial.Write($@"*{"0015"}*" + i.ToString().PadLeft(4, '0') + '*' + i.ToString().PadLeft(30, '.'));
Console.WriteLine(serial.ReadExisting());
i++;
Console.WriteLine("...");
Console.ReadLine();
}
_completeCommandSizeWithSep是应该接收的命令长度。
命令格式为*0001*AAAA*123456789123asdfgh12345678584a
发送数据时来自 workPiece 变量的数据示例(几乎是普通的,只是删除了非 ascii 字符):
Sended data:
*0015*0EF9*.............................0
*0015*2K3R*.............................1
*0015*C80S*.............................2
Received data:
*0015*0EF9*.0EF9*.0EF9*.0EF9*.0EF9*.0EF9*
...F9*...F9*...F9*...F9*...F9*...F9*...F9
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*0..F
*...F9*...F9*...F9*...F9*...F9*0..F9**..F
*...F9*...F9*...F9*...F9*0..F9**..F9*00.F
*...F9*...F9*...F9*0..F9**..F9*00.F9*10.F
*...F9*...F9*0..F9**..F9*00.F9*10.F9*50.F
*...F9*0..F9**..F9*00.F9*10.F9*50.F9**0.F
*0..F9**..F9*00.F9*10.F9*50.F9**0.F9*00.F
**..F9*00.F9*10.F9*50.F9**0.F9*00.F9*E0.F
*..F9*00.F9*10.F9*50.F9**0.F9*00.F9*E0.F9
*00.F9*10.F9*50.F9**0.F9*00.F9*E0.F9*F0.F
*10.F9*50.F9**0.F9*00.F9*E0.F9*F0.F9*90.F
*50.F9**0.F9*00.F9*E0.F9*F0.F9*90.F9**0.F
**0.F9*00.F9*E0.F9*F0.F9*90.F9**0.F9*.0.F
*0.F9*00.F9*E0.F9*F0.F9*90.F9**0.F9*.0.F9
*00.F9*E0.F9*F0.F9*90.F9**0.F9*.0.F9*...F
*E0.F9*F0.F9*90.F9**0.F9*.0.F9*...F9*....
*F0.F9*90.F9**0.F9*.0.F9*...F9*....9*....
*90.F9**0.F9*.0.F9*...F9*....9*....9*....
**0.F9*.0.F9*...F9*....9*....9*....9*....
*0.F9*.0.F9*...F9*....9*....9*....9*....9
*.0.F9*...F9*....9*....9*....9*....9*....
*...F9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*0...
*....9*....9*....9*....9*....9*0...9**...
*....9*....9*....9*....9*0...9**...9*0...
*....9*....9*....9*0...9**...9*0...9*01..
*....9*....9*0...9**...9*0...9*01..9*51..
*....9*0...9**...9*0...9*01..9*51..9**1..
*0...9**...9*0...9*01..9*51..9**1..9*21..
**...9*0...9*01..9*51..9**1..9*21..9*K1..
*...9*0...9*01..9*51..9**1..9*21..9*K1..9
*0...9*01..9*51..9**1..9*21..9*K1..9*31..
*01..9*51..9**1..9*21..9*K1..9*31..9*R1..
*51..9**1..9*21..9*K1..9*31..9*R1..9**1..
**1..9*21..9*K1..9*31..9*R1..9**1..9*.1..
*1..9*21..9*K1..9*31..9*R1..9**1..9*.1..9
*21..9*K1..9*31..9*R1..9**1..9*.1..9*.1..
*K1..9*31..9*R1..9**1..9*.1..9*.1..9*.1..
*31..9*R1..9**1..9*.1..9*.1..9*.1..9*.1..
*R1..9**1..9*.1..9*.1..9*.1..9*.1..9*....
**1..9*.1..9*.1..9*.1..9*.1..9*....9*....
*1..9*.1..9*.1..9*.1..9*.1..9*....9*....9
*.1..9*.1..9*.1..9*.1..9*....9*....9*....
*.1..9*.1..9*.1..9*....9*....9*....9*....
*.1..9*.1..9*....9*....9*....9*....9*....
*.1..9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*1...
*....9*....9*....9*....9*....9*1...9**...
*....9*....9*....9*....9*1...9**...9*0...
*....9*....9*....9*1...9**...9*0...9*0...
*....9*....9*1...9**...9*0...9*0...9*1...
*....9*1...9**...9*0...9*0...9*1...9*5...
*1...9**...9*0...9*0...9*1...9*5...9**...
**...9*0...9*0...9*1...9*5...9**...9*2...
*...9*0...9*0...9*1...9*5...9**...9*2...9
*0...9*0...9*1...9*5...9**...9*2...9*K...
*0...9*1...9*5...9**...9*2...9*K...9*3...
*1...9*5...9**...9*2...9*K...9*3...9*R*..
*5...9**...9*2...9*K...9*3...9*R*..9*.*..
**...9*2...9*K...9*3...9*R*..9*.*..9*.*..
*...9*2...9*K...9*3...9*R*..9*.*..9*.*..9
*2...9*K...9*3...9*R*..9*.*..9*.*..9*.*..
*K...9*3...9*R*..9*.*..9*.*..9*.*..9*.*..
*3...9*R*..9*.*..9*.*..9*.*..9*.*..9*.*..
*R*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*....
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*....9*
*.*..9*.*..9*.*..9*.*..9*.*..9*....9*....
*..9*.*..9*.*..9*.*..9*.*..9*....9*....9*
*.*..9*.*..9*.*..9*.*..9*....9*....9*....
*..9*.*..9*.*..9*.*..9*....9*....9*....9*
*.*..9*.*..9*.*..9*....9*....9*....9*....
*..9*.*..9*.*..9*....9*....9*....9*....9*
*.*..9*.*..9*....9*....9*....9*....9*....
*..9*.*..9*....9*....9*....9*....9*....9*
*.*..9*....9*....9*....9*....9*....9*....
*..9*....9*....9*....9*....9*....9*....9*
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*1...
*....9*....9*....9*....9*....9*1...9**...
*....9*....9*....9*....9*1...9**...9*0...
*....9*....9*....9*1...9**...9*0...9*01..
*....9*....9*1...9**...9*0...9*01..9*5*..
*....9*1...9**...9*0...9*01..9*5*..9*C8..
*1...9**...9*0...9*01..9*5*..9*C8..9*08..
**...9*0...9*01..9*5*..9*C8..9*08..9*S8..
*...9*0...9*01..9*5*..9*C8..9*08..9*S8..9
*0...9*01..9*5*..9*C8..9*08..9*S8..9**...
*01..9*5*..9*C8..9*08..9*S8..9**...9*....
*5*..9*C8..9*08..9*S8..9**...9*....9*....
*..9*C8..9*08..9*S8..9**...9*....9*....9*
*C8..9*08..9*S8..9**...9*....9*....9*....
*08..9*S8..9**...9*....9*....9*....9*....
*S8..9**...9*....9*....9*....9*....9*....
**...9*....9*....9*....9*....9*..........
*...9*....9*....9*....9*....9*...........
*....9*....9*....9*....9*................
*....9*....9*....9*......................
*....9*....9*............................
*....9*..................................
*........................................
....................2*....0*....015...*C5
Additionally - data from port listener:
1619781: 2019-09-21 23:37:52,7484713 +0,2099872
2A 30 30 31 35 2A 30 45 46 39 2A 2E 2E 2E 2E 2E *0015*0EF9*.....
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 2E 2E 2E 2E 2E 2E 2E 30 2A 30 30 31 35 2A 30 ........0*0015*0
45 46 39 2A 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E EF9*............
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 30 .0
1620349: 2019-09-21 23:37:54,4023089 +0,3609614
2A 30 30 31 35 2A 32 4B 33 52 2A 2E 2E 2E 2E 2E *0015*2K3R*.....
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 2E 2E 2E 2E 2E 2E 2E 31 2A 30 30 31 35 2A 32 ........1*0015*2
4B 33 52 2A 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E K3R*............
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 31 .1
1620937: 2019-09-21 23:37:54,8706713 +0,3255464
2A 30 30 31 35 2A 43 38 30 53 2A 2E 2E 2E 2E 2E *0015*C80S*.....
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 2E 2E 2E 2E 2E 2E 2E 32 2A 30 30 31 35 2A 43 ........2*0015*C
38 30 53 2A 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 80S*............
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2
我找到了解决办法!
在StartReceivingAsync
方法中byte[] mainBuffer
被初始化一次。
初始化之后是一个 'while...' 循环,它执行实际的数据流读取。
我不知道 FTDI 芯片的确切规格,但它确实在不断发送时以相当随机的部分发送数据(发送方和接收方没有超时)
所以,当执行
int bytesRead = await _port.BaseStream.ReadAsync(mainBuffer, 0, _completeCommandSizeWithSep, _receiveToken);
我会随机发送一部分数据。该数据将按预期写入 mainBuffer
字节数组,然后将其添加到 _receivedBuffer
.
事情来了:当流收到小于 _completeCommandSizeWithSep
的数据部分时,mainBuffer
没有被清理。
BaseStream reader 仅从接收到的 0 索引中替换 mainBuffer
中的尽可能多的字符,忽略其余部分。
The fix is to just add a substring of length equal to bytesRead
value instead of whole mainBuffer
to received buffer:
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
数组。
我目前正在编写一个简单的应用程序,它将通过 ftdi232 芯片(串行端口)与基于 arduino 的设备进行通信
我遇到了基本流读取问题 - 我的应用程序在虚拟端口 (com0com) 上测试时运行良好,但当我切换到 ftdi 设备时,接收到的数据变得混乱和/或重复。
发送端口和接收端口配置相同:
- 19200波特率
- 8 个数据位
- 奇偶校验 = none
- 停止位 = 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);
}
if (whereToCut != 0)
command.CommandType = CommandType.Error;
else
{
command = CommandTranslator(workPiece);
_receivedBuffer.Remove(0, _completeCommandSizeWithSep);
}
DataReceived?.Invoke(this, command);
}
else
{
continue;
}
}
_isLissening = false;
}
发送方式:
while (true)
{
serial.Write($@"*{"0015"}*" + i.ToString().PadLeft(4, '0') + '*' + i.ToString().PadLeft(30, '.'));
Console.WriteLine(serial.ReadExisting());
i++;
Console.WriteLine("...");
Console.ReadLine();
}
_completeCommandSizeWithSep是应该接收的命令长度。
命令格式为*0001*AAAA*123456789123asdfgh12345678584a
发送数据时来自 workPiece 变量的数据示例(几乎是普通的,只是删除了非 ascii 字符):
Sended data:
*0015*0EF9*.............................0
*0015*2K3R*.............................1
*0015*C80S*.............................2
Received data:
*0015*0EF9*.0EF9*.0EF9*.0EF9*.0EF9*.0EF9*
...F9*...F9*...F9*...F9*...F9*...F9*...F9
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*...F
*...F9*...F9*...F9*...F9*...F9*...F9*0..F
*...F9*...F9*...F9*...F9*...F9*0..F9**..F
*...F9*...F9*...F9*...F9*0..F9**..F9*00.F
*...F9*...F9*...F9*0..F9**..F9*00.F9*10.F
*...F9*...F9*0..F9**..F9*00.F9*10.F9*50.F
*...F9*0..F9**..F9*00.F9*10.F9*50.F9**0.F
*0..F9**..F9*00.F9*10.F9*50.F9**0.F9*00.F
**..F9*00.F9*10.F9*50.F9**0.F9*00.F9*E0.F
*..F9*00.F9*10.F9*50.F9**0.F9*00.F9*E0.F9
*00.F9*10.F9*50.F9**0.F9*00.F9*E0.F9*F0.F
*10.F9*50.F9**0.F9*00.F9*E0.F9*F0.F9*90.F
*50.F9**0.F9*00.F9*E0.F9*F0.F9*90.F9**0.F
**0.F9*00.F9*E0.F9*F0.F9*90.F9**0.F9*.0.F
*0.F9*00.F9*E0.F9*F0.F9*90.F9**0.F9*.0.F9
*00.F9*E0.F9*F0.F9*90.F9**0.F9*.0.F9*...F
*E0.F9*F0.F9*90.F9**0.F9*.0.F9*...F9*....
*F0.F9*90.F9**0.F9*.0.F9*...F9*....9*....
*90.F9**0.F9*.0.F9*...F9*....9*....9*....
**0.F9*.0.F9*...F9*....9*....9*....9*....
*0.F9*.0.F9*...F9*....9*....9*....9*....9
*.0.F9*...F9*....9*....9*....9*....9*....
*...F9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*0...
*....9*....9*....9*....9*....9*0...9**...
*....9*....9*....9*....9*0...9**...9*0...
*....9*....9*....9*0...9**...9*0...9*01..
*....9*....9*0...9**...9*0...9*01..9*51..
*....9*0...9**...9*0...9*01..9*51..9**1..
*0...9**...9*0...9*01..9*51..9**1..9*21..
**...9*0...9*01..9*51..9**1..9*21..9*K1..
*...9*0...9*01..9*51..9**1..9*21..9*K1..9
*0...9*01..9*51..9**1..9*21..9*K1..9*31..
*01..9*51..9**1..9*21..9*K1..9*31..9*R1..
*51..9**1..9*21..9*K1..9*31..9*R1..9**1..
**1..9*21..9*K1..9*31..9*R1..9**1..9*.1..
*1..9*21..9*K1..9*31..9*R1..9**1..9*.1..9
*21..9*K1..9*31..9*R1..9**1..9*.1..9*.1..
*K1..9*31..9*R1..9**1..9*.1..9*.1..9*.1..
*31..9*R1..9**1..9*.1..9*.1..9*.1..9*.1..
*R1..9**1..9*.1..9*.1..9*.1..9*.1..9*....
**1..9*.1..9*.1..9*.1..9*.1..9*....9*....
*1..9*.1..9*.1..9*.1..9*.1..9*....9*....9
*.1..9*.1..9*.1..9*.1..9*....9*....9*....
*.1..9*.1..9*.1..9*....9*....9*....9*....
*.1..9*.1..9*....9*....9*....9*....9*....
*.1..9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*1...
*....9*....9*....9*....9*....9*1...9**...
*....9*....9*....9*....9*1...9**...9*0...
*....9*....9*....9*1...9**...9*0...9*0...
*....9*....9*1...9**...9*0...9*0...9*1...
*....9*1...9**...9*0...9*0...9*1...9*5...
*1...9**...9*0...9*0...9*1...9*5...9**...
**...9*0...9*0...9*1...9*5...9**...9*2...
*...9*0...9*0...9*1...9*5...9**...9*2...9
*0...9*0...9*1...9*5...9**...9*2...9*K...
*0...9*1...9*5...9**...9*2...9*K...9*3...
*1...9*5...9**...9*2...9*K...9*3...9*R*..
*5...9**...9*2...9*K...9*3...9*R*..9*.*..
**...9*2...9*K...9*3...9*R*..9*.*..9*.*..
*...9*2...9*K...9*3...9*R*..9*.*..9*.*..9
*2...9*K...9*3...9*R*..9*.*..9*.*..9*.*..
*K...9*3...9*R*..9*.*..9*.*..9*.*..9*.*..
*3...9*R*..9*.*..9*.*..9*.*..9*.*..9*.*..
*R*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*
*.*..9*.*..9*.*..9*.*..9*.*..9*.*..9*....
*..9*.*..9*.*..9*.*..9*.*..9*.*..9*....9*
*.*..9*.*..9*.*..9*.*..9*.*..9*....9*....
*..9*.*..9*.*..9*.*..9*.*..9*....9*....9*
*.*..9*.*..9*.*..9*.*..9*....9*....9*....
*..9*.*..9*.*..9*.*..9*....9*....9*....9*
*.*..9*.*..9*.*..9*....9*....9*....9*....
*..9*.*..9*.*..9*....9*....9*....9*....9*
*.*..9*.*..9*....9*....9*....9*....9*....
*..9*.*..9*....9*....9*....9*....9*....9*
*.*..9*....9*....9*....9*....9*....9*....
*..9*....9*....9*....9*....9*....9*....9*
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*....
*....9*....9*....9*....9*....9*....9*1...
*....9*....9*....9*....9*....9*1...9**...
*....9*....9*....9*....9*1...9**...9*0...
*....9*....9*....9*1...9**...9*0...9*01..
*....9*....9*1...9**...9*0...9*01..9*5*..
*....9*1...9**...9*0...9*01..9*5*..9*C8..
*1...9**...9*0...9*01..9*5*..9*C8..9*08..
**...9*0...9*01..9*5*..9*C8..9*08..9*S8..
*...9*0...9*01..9*5*..9*C8..9*08..9*S8..9
*0...9*01..9*5*..9*C8..9*08..9*S8..9**...
*01..9*5*..9*C8..9*08..9*S8..9**...9*....
*5*..9*C8..9*08..9*S8..9**...9*....9*....
*..9*C8..9*08..9*S8..9**...9*....9*....9*
*C8..9*08..9*S8..9**...9*....9*....9*....
*08..9*S8..9**...9*....9*....9*....9*....
*S8..9**...9*....9*....9*....9*....9*....
**...9*....9*....9*....9*....9*..........
*...9*....9*....9*....9*....9*...........
*....9*....9*....9*....9*................
*....9*....9*....9*......................
*....9*....9*............................
*....9*..................................
*........................................
....................2*....0*....015...*C5
Additionally - data from port listener:
1619781: 2019-09-21 23:37:52,7484713 +0,2099872
2A 30 30 31 35 2A 30 45 46 39 2A 2E 2E 2E 2E 2E *0015*0EF9*.....
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 2E 2E 2E 2E 2E 2E 2E 30 2A 30 30 31 35 2A 30 ........0*0015*0
45 46 39 2A 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E EF9*............
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 30 .0
1620349: 2019-09-21 23:37:54,4023089 +0,3609614
2A 30 30 31 35 2A 32 4B 33 52 2A 2E 2E 2E 2E 2E *0015*2K3R*.....
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 2E 2E 2E 2E 2E 2E 2E 31 2A 30 30 31 35 2A 32 ........1*0015*2
4B 33 52 2A 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E K3R*............
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 31 .1
1620937: 2019-09-21 23:37:54,8706713 +0,3255464
2A 30 30 31 35 2A 43 38 30 53 2A 2E 2E 2E 2E 2E *0015*C80S*.....
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2E 2E 2E 2E 2E 2E 2E 2E 32 2A 30 30 31 35 2A 43 ........2*0015*C
38 30 53 2A 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 80S*............
2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E 2E ................
2
我找到了解决办法!
在StartReceivingAsync
方法中byte[] mainBuffer
被初始化一次。
初始化之后是一个 'while...' 循环,它执行实际的数据流读取。
我不知道 FTDI 芯片的确切规格,但它确实在不断发送时以相当随机的部分发送数据(发送方和接收方没有超时)
所以,当执行
int bytesRead = await _port.BaseStream.ReadAsync(mainBuffer, 0, _completeCommandSizeWithSep, _receiveToken);
我会随机发送一部分数据。该数据将按预期写入 mainBuffer
字节数组,然后将其添加到 _receivedBuffer
.
事情来了:当流收到小于 _completeCommandSizeWithSep
的数据部分时,mainBuffer
没有被清理。
BaseStream reader 仅从接收到的 0 索引中替换 mainBuffer
中的尽可能多的字符,忽略其余部分。
The fix is to just add a substring of length equal to
bytesRead
value instead of wholemainBuffer
to received buffer:
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
数组。