我从 Raspberry Pi 上的四个 USB 串行端口长期记录数据,最终需要到达本地网络上的另一台机器进行进一步处理。有一些限制使得事情比看起来更复杂。到目前为止,我尝试过的所有方法都会随机导致数据丢失或顺序错误。我正在用Python 进行编程。抱歉,下面的内容很长,但我想完整地描述一下情况。
以下是数据概要:
A。每个串行端口连接到一个传感器,该传感器输出两个 115.2kb 测量通道的数据(即八个数据通道)。每次测量的数据由一行组成。这两行是从串行设备单独发送的,而不是作为一条消息发送。
b.每次测量均以“XXXX.xxxxxxxxxx chX”形式的时间戳开始。整数部分是从 1 开始并无限增加的秒,小数部分是 11 位小数(10 皮秒分辨率)。时间戳后跟唯一标识符“chA”、“chB”等,直到“chH”,并且该行以换行符结束。时间戳是数据——它显示何时从外部设备接收到脉冲。下面是一个示例:“123.12345678901 chD\n”
b.标称数据速率是每个通道每秒进行一次测量。
C。对于八个读数的每个“节”,我可以规定所有有效时间戳必须在距中值 +/-0.5 秒的范围内。传播通常更像是几微秒,因此 1 秒范围为有效数据提供了很大的余量。
d.节中的时间戳可以跨越第二个边界,或者全部发生在一秒内(相位关系在启动时任意建立)。
e.无法保证每个节的数据行的接收顺序。这是一个示例节:
1234.01231231231 查 1234.02342342342 chB 1233.99999912345 ch 1234.03453453453 chC 1234.03213213213 chD 1234.04324324324 法郎 1234.01234567890 chG 1233.99999954321 chH
这表明:(1)一节中的数据可能会跨越整数秒; (2) 可能无法按通道顺序接收数据; (3)数据并不总是按照时间戳升序接收。
我需要将每个节的数据按照严格的通道 ID 顺序(chA、chB、chC、chD、chE、chF、chG、chH)放置。上面的示例应记录为:
1234.01231231231 查 1234.02342342342 chB 1234.03453453453 chC 1234.03213213213 chD 1233.99999912345 ch 1234.04324324324 法郎 1234.01234567890 chG 1233.99999954321 chH
我目前的做法:
我有一个在每个串行端口的单独线程中运行的 Serial.read() 调用,提供一个公共队列,我使用一个用全零初始化的 8 项列表来处理该队列,其中每个列表项与一个通道相关联(例如,list[0 ] 是 chA,list[1] 是 chB,等等)。当每行数据进入时,时间戳被放置在其通道的适当槽中。当列表不再包含任何零值时,该节就完成了,我将列表从 chA 迭代到 chH 以输出每个值,然后将其归零以用于下一个节。
问题:
这通常是有效的,但我随机最终会出现数据乱序的情况——例如,一个通道的串行数据丢失了一秒钟,因此列表中的槽位在一秒钟后被下一个时间戳填充。有时整节会消失(尽管这种情况很少见)。我的猜测是,串行数据的问题结果是异步传入的,随机处理延迟会导致值丢失(测试已确定串行数据实际上正在发送到 RPi;丢失发生在该处理中)。
我最初将数据提供给套接字服务器,以便远程计算机(位于同一网络上)可以通过线路获取数据。我认为网络堆栈可能会导致问题,因此尝试将数据本地写入 RPi 上。虽然效果更好,但我仍然得到这些丢失和无序的样本。
因此,我正在寻找一种方法,可以避免导致消息丢失的任何瓶颈,或者提供某种可以将数据重新排序到适当节的重组器。我也不确定读取单个线程中的四个通信端口是否是最好的方法。任何想法将不胜感激。再次抱歉这个问题太长了。
谢谢!约翰