当前位置: 首页 > 知识库问答 >
问题:

串口缓冲区/波特率/数据丢失

养枫涟
2023-03-14

我正在使用下面的代码片段每秒一次通过com端口发送gps数据:

serialPort = new SerialPort("COM4", 4800, Parity.None, 8, StopBits.One);
serialPort.Handshake = Handshake.None;
serialPort.WriteTimeout = 500;
serialPort.Open();

这一切都很好,但是当使用以下方法写入串行端口时:

serialPort.Write(theString);

我的读取程序,使用:

  while (true) {
      Console.Write(serialPort.ReadExisting());
  }

将只从该写入状态读取254字节的数据。油灰也是如此。

我尝试过将写状态分成254个字节大小的块并写两次,但是第二次写操作,尽管被确认为由我的写入程序运行,却从未被读取程序读取。

我知道我的写缓冲区是4096字节,读缓冲区是2048字节。

我的字符串是这样的:

$GPGGA,191500.00,3351.6474,S,15112.6510,E,2,04,2.5,+0008,M,+020,M,00,0000*76
$GPVTG,057.3,T,,,000.0,N,000.0,K,A*41
$GPRMC,191500.00,A,3351.6474,S,15112.6510,E,000.0,057.3,120412,D*40
$GPGLL,3351.6474,S,15112.6510,E,191500.00,A,A*79
$GPGSA,A,3,,,,,,,,,,,,,2.5,1.3,2.1*34
$GPGSV,1,1,5,03,20,40,89,06,18,30,86,12,25,15,80,20,5,36,70*77
$GPDTM,999,,0.0,S,0.0,E,+0.0,W84*3B
$GPZDA,191500.00,11,04,12*60
$GPGBS,191500.00,+020.0,+020.0,+000.0,,0.00000,+0000.0,0000.0*63
$GPMSS,999,999,200.0,4800,*56

当我尝试使用字符串中每行一个写入语句写入缓冲区时,它会将所有内容写入缓冲区,然而,两个写入操作会在读卡器中交错,因此结果如下:

etc...
$GPGGA,191500.00,3351.6474,S,15112.6510,E,2,04,2.5,+0008,M,+020,M,00,0000*76
$GPDTM,999,,0.0,S,0.0,E,+0.0,W84*3B
$GPVTG,057.3,T,,,000.0,N,000.0,K,A*41
$GPZDA,191500.00,11,04,12*60
$GPRMC,191500.00,A,3351.6474,S,15112.6510,E,000.0,057.3,120412,D*40
$GPGBS,191500.00,+020.0,+020.0,+000.0,,0.00000,+0000.0,0000.0*63
$GPGLL,3351.6474,S,15112.6510,E,191500.00,A,A*79
$GPMSS,999,999,200.0,4800,*56
$GPGSA,A,3,,,,,,,,,,,,,2.5,1.3,2.1*34
$GPGSV,1,1,5,03,20,40,89,06,18,30,86,12,25,15,80,20,5,36,70*77
etc...

所有这些对我来说都没有意义,尽管在9600波特率交错问题没有发生,(我假设因为4800波特率==480bytes/s),改变波特率不是一个选项,并且以某种方式正常的GPS能够传输所有这些数据在一个突发。

问题:

有人知道为什么当我向流写入504字节的数据时,我的读取只接收254字节的数据吗?有没有什么约束

serialPort.Write(Byte[], int offset, int count);

不允许超过254字节?(这不能解释第二次写入操作没有完成)。

甚至。有人知道更好的串行端口写入方式吗?

这种方法似乎适用于提供的数据(尽管我最初的问题仍然有效):

string Sentence = "";
for (int i = 0; i < block_list[total_block].Count; i+=2) {
    Sentence = block_list[total_block][i] + block_list[total_block][i+1];
    serialPort.Write(Sentence);
}

共有1个答案

丌官晔
2023-03-14

等等,你说你使用了一秒钟的超时,但是你的代码写着:

serialPort.WriteTimeout = 500;

发送端有半秒的超时。在4.8Kbps(如你所说,大约每秒480个字符)的速度下,这只够发送240个字符。

全球定位系统可以做到这一点,因为它没有半秒钟的超时时间。

试着把暂停时间提高一点,看看会发生什么——五秒钟应该会给你足够的喘息空间进行测试。在4.8Kbps的速率下,504个字节需要一秒钟多一点的时间才能完全传输。

确保你真的不想握手?缺少这一点也可能会导致数据丢失。

 类似资料:
  • 问题内容: 我正在开发一个 Android蓝牙 项目,用于从定制硬件发送和接收数据。我使用SDK中的 Bluetooth Chat Sample 作为基础。 我意识到,有没有办法改变 波特率 在客户端(Android手机)和波特率取决于硬件。我尝试在硬件上设置不同的 波特率 ,但没有一个符合我们的期望。 我获得的最快速度是91Kbps(当波特率设置为2.7Mbps〜910Kbps时)。使用最低波特

  • 我在windows和direct show上使用FFMPEG。我正在传输RTMP(下面的命令),我需要非常低的延迟。一旦运行,我会出现以下错误:[dshow@024ce800]实时缓冲区已满204%!框架掉下来了! ffmpeg线程6-f dshow-i video=UScreenCapture-s 1920x1080-an-vco dec libx264-x264opts keyint=25:

  • 已实现波动率数据 Oxford-Man 接口: article_oman_rv 目标地址: https://realized.oxford-man.ox.ac.uk/data/visualization 描述: 获取 Oxford-Man 已实现波动率数据 限量: 单次返回某个指数具体指标的所有历史数据 输入参数 名称 类型 必选 描述 symbol str Y symbol="FTSE", 具体

  • 我有一个二进制数据缓冲区,我想存储在协议缓冲区中。 在留档(https://developers.google.com/protocol-buffers/docs/proto#scalar)中,它说类型等价于C中的。我无法相信这一点,所以我不得不尝试它,是的,这似乎是这样... 本协议: 给出一个包含以下内容的消息定义: 公共setter/getter API如下所示: 当然,这不是在消息中存储二

  • 我正在使用Google Protocol Buffers向服务器发送消息。我对如何发送图像与如何接收图像感到困惑。有关详细信息,请参阅下面的代码,但我的问题是: 我需要base64_decode从未经过base64编码的返回字符串吗,因为它是使用char*和size发送的?也许Google Protocol Buffers处理了这个问题,但我在生成的类中找不到任何证据。 我可能在这里找到了答案,但

  • 我们正在BigQuery表上进行流式插入。 我们希望在不更改表名的情况下更新表的模式。 例如,我们希望删除一列,因为它包含敏感数据,但是我们希望保持所有其他数据和表名不变。 我们的流程如下: 将原始表复制到临时表 删除原始表 使用原始表名和新架构创建新表。 用旧表的数据填充新表。 哭,因为最后(最多)90分钟的数据卡在流缓冲区中,未传输 如何避免最后一步?