使用Python3.6.9运行在WSLUbuntu18.4.2LTS下的pyserial有一个奇怪的问题
我设置了一个简单的函数将GCODE命令发送到串口:
def gcode_send(data):
print("Sending: " + data.strip())
data = data.strip() + "\n" # Strip all EOL characters for consistency
s.write(data.encode()) # Send g-code block to grbl
grbl_out = s.readline().decode().strip()
print(grbl_out)它有点工作,但我发送的每一条命令都是“持有”的,直到下一个命令被发送为止。
例如:
设备不响应G0 X0
G0 X1
G1 X0 >设备响应
我的设置代码是:
s = serial.Serial(com, 115200)
s.write("\r\n\r\n".encode()) # Wake up grbl
time.sleep(2) # Wait for grbl to initialize
s.flushInput() # Flush startup text in serial input我可以暂时绕开延迟,但这很烦人,我找不到其他人也在经历同样的事情。知道是什么导致的吗?
发布于 2020-03-22 12:22:08
这里可能会有很多问题,但是请放心,这个问题并不是由吡喃引起的。它使用底层操作系统的API与UART驱动程序进行通信。尽管如此,您首先必须使用真正的Linux测试代码,以确定WSL是否导致了这种情况。也就是说,Linux和Windows缓冲区是否被正确同步。很抱歉,我无法判断您的代码中是否有问题,因为我不知道您正在使用的设备,所以我无法猜测它在通信通道的末端发生了什么。请记住,在最好的情况下,只有Windows才能做出奇怪的行为,所以,在这里做好一些挫折的准备吧。检查您的主板或USB2Serial转换器驱动程序或任何您正在使用的hw。
接下来,您应该知道,有时,如果没有设置超时,通信就会变得混乱。为什么?没人真正知道。所以试着设置超时。检查是否需要打开软件Xon/Xoff,以及与您通信的设备可能需要的其他RS232参数。
另外,看看s.readline()是怎么回事,我不会亲自使用它。超时可能会有所帮助,或者您可以在超时时使用s.read(1024)。我现在不记得了,但是看看pyserial是否支持异步通信。如果是这样的话,您可以尝试使用它而不是标准的阻塞模式。
此外,检查是否必须在s.write()之后强制刷新串行缓冲区,还是在它之后添加睡眠。可能会发生这样的情况:设备没有收到消息,但读取请求被激活。由于设备没有接收到命令,所以它没有响应。发送另一个命令后,IO缓冲区将被刷新,而上一个命令将被传递,依此类推。串行通信很有趣,但当它遇到一个障碍,它可以是一个真正的P在A,相信我。
检查设备是否只发送"\r\n“或”\r\n“,还是"\r”或"\n“作为响应。s.readline()可能会感到困惑。首先,尝试一个接一个地放置两个s.readline(),然后打印出每个输出。如果设备发送双EOL,那么只有一个s.readline()在空行上停止,当您发送另一个命令s.readline()通过缓冲区并返回已经存在但之前没有读取的完整行时,程序会收到一个空响应。
发布于 2020-03-22 13:29:58
开始吧。注释中出现的代码。它的大部分删除和错误检查也。
它是一个通过蓝牙在Symbian系列的诺基亚智能手机上使用PyS60 Python控制台的打字终端。效果非常好。
from serial import *
from thread import start_new_thread as thread
from time import sleep
import sys, os
# Original code works on Linux too
# The following code for gettin one character from stdin without echoing it on terminal
# has its Linux complement using tricks from Python's stdlib getpass.py module
# I.e. put the terminal in non-blocking mode, turn off echoing and use sys.stdin.read(1)
# Here is Win code only (for brevity):
import msvcrt
def getchar ():
return msvcrt.getch()
def pause ():
raw_input("\nPress enter to continue . . .")
port = raw_input("Portname: ")
if os.name=="nt":
nport = ""
for x in port:
if x.isdigit(): nport += x
port = int(nport)-1
try:
s = Serial(port, 9600)
except:
print >> sys.stderr, "Cannot open the port!\nThe program will be closed."
pause()
sys.exit(1)
print "Port ready!"
running = 1
def reader():
while running:
try:
msg = s.read()
# If timeout is set
while msg=="":
msg = s.read()
sys.stdout.write(msg)
except: sleep(0.001)
thread(reader,())
while 1:
try: c = getchar()
except Exception, e:
running = 0
print >> sys.stderr, e
s.write('\r\n\x04')
break
if c=='\003' or c=='\x04':
running = 0
s.write('\r\n\x04')
break
s.write(c)
s.close()
pause()https://stackoverflow.com/questions/60798992
复制相似问题