停止从串口读取字节 (Python/RPi/UART)
Stop reading bytes from serial port (Python/RPi/UART)
这个问题比较复杂。看起来我有简单的双向通信 beetwen 2 设备,其中阅读方是 Raspberry pi 3. 我正在尝试传输文件。我正在逐个发送它(5kb 部分)。看起来像:
1) 发送方发送前 5kb 部分(正好 5136 字节其中前 16 字节是ID/SIZE/ADD_INFO/CRC)
2) RPi3读取5136字节,计算chunk的CRC
3) RPi3比较从发送方收到的CRC和RPi计算得到的CRC
4a) 如果 CRC 不匹配,我使用具有三态输出的双总线缓冲器门将通道从 RX 切换到 TX 线,并在 TX 线上设置高状态(我保持 30ms)。
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 抱歉语言混乱,但我正在尝试尽可能简单地解释它
好吧,我拼了。我在 sudo raspi-congif
中启用了选项 "Would you like a login shell to be accessible over serial"。不知道为什么这会弄乱一切,但禁用此修复程序。这很奇怪,因为我在玩覆盆子和串口有一段时间了,如果 RPi3 通过 uart 发送一些东西或者它只是在不换行等情况下读取时没有问题 :)
这个问题比较复杂。看起来我有简单的双向通信 beetwen 2 设备,其中阅读方是 Raspberry pi 3. 我正在尝试传输文件。我正在逐个发送它(5kb 部分)。看起来像:
1) 发送方发送前 5kb 部分(正好 5136 字节其中前 16 字节是ID/SIZE/ADD_INFO/CRC)
2) RPi3读取5136字节,计算chunk的CRC
3) RPi3比较从发送方收到的CRC和RPi计算得到的CRC
4a) 如果 CRC 不匹配,我使用具有三态输出的双总线缓冲器门将通道从 RX 切换到 TX 线,并在 TX 线上设置高状态(我保持 30ms)。
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 抱歉语言混乱,但我正在尝试尽可能简单地解释它
好吧,我拼了。我在 sudo raspi-congif
中启用了选项 "Would you like a login shell to be accessible over serial"。不知道为什么这会弄乱一切,但禁用此修复程序。这很奇怪,因为我在玩覆盆子和串口有一段时间了,如果 RPi3 通过 uart 发送一些东西或者它只是在不换行等情况下读取时没有问题 :)