【发布时间】:2017-11-29 09:30:13
【问题描述】:
这个问题相当复杂。似乎我有简单的双向通信 beetwen 2 设备,其中读取端是 Raspberry pi 3。我正在尝试传输文件。我正在逐部分发送(5kb 部分)。它看起来像:
1) 发送方发送前 5kb 部分(正好是 5136 字节,其中前 16 字节为 ID/SIZE/ADD_INFO/CRC)
2) RPi3 读取 5136 字节,计算块的 CRC。
3) RPi3 比较从发送端接收并由 RPi 计算的 CRC
4a) 如果 CRC 不匹配,我使用具有 3 态输出的双总线缓冲门将通道从 RX 切换到 TX 线,并在 TX 线设置高状态(我将其保持 30 毫秒)。
4b) 如果 CRC 匹配,我只需等待下一个文件块
5) 如果状态为 HIGH/1(当 CRC 不匹配),也发送侧开关通道并读取我的 TX 状态,如果状态为 LOW/0,则发送相同的块(重传)发送另一个块。 (改变状态需要 10 毫秒)
在示波器上它看起来像这样(4a):
还有这个(4b):
Beetwen 5136 块有空闲时间来计算 CRC,然后如果我们必须在 RPi3 端更改状态,因为 CRC 不匹配(4a 处的红线)并从发送端读取 TX 端。
好的,现在来自 RPi 的一些简化代码:
def recv():
while True:
#Set line to low because I want to read data
GPIO.output(16, GPIO.LOW)
ID = ser.read(4)
SIZE = ser.read(4)
ADD_INFO = ser.read(4)
CRC = ser.read(4)
#get crc from sending side
crc_chunk = int.from_bytes(CRC, byteorder='little')
data = ser.read(5120)
#calculating CRC from chunk
rpiCRC = crcSTM(data)
while True:
<--- here I wait about 20ms to calculate CRC
if rpiCRC != crc_chunk:
#Crc doesn't match I want retransmission
GPIO.output(16, GPIO.HIGH)
<--- keep it HIGH for about 30ms
break
else:
#keep it low because crc match and we are waiting for next chunk
GPIO.output(16, GPIO.HIGH)
break
所有这些看起来都是合法的,但切中要害。在 RPi 停止读取字节之后,我总是只得到第一个块。仅在“4b”我正确获得第一个块并且我正在等待下一个块然后RPi停止读取字节或不时给我一些划痕的情况下才会发生这种情况。我测试如果我正确获得第一个块并设置重新传输的东西,但一切看起来都很好,我一直在重新传输第一个块并一直得到它。我发现当我处于 LOW/1 状态时,发送端的更改线路会影响 RPi,它只是停止正确读取字节。不知道为什么它会弄乱它,也不知道如何与之抗争。我尝试冲洗缓冲区,在发送侧换行之前关闭端口,并在它再次更改行后打开它,但这一切都无济于事,我还能做些什么?
P.S 我在自己的计时器中做这些等待的事情,但没有必要在这里放像来自发送端的代码之类的代码,因为问题出在 RPi 端。 P.S 对混乱的语言感到抱歉,但我试图尽可能简单地解释它
【问题讨论】:
标签: python raspberry-pi serial-port communication pyserial