首页
学习
活动
专区
圈层
工具
发布

1写延迟
EN

Stack Overflow用户
提问于 2020-03-22 11:54:15
回答 2查看 2.2K关注 0票数 0

使用Python3.6.9运行在WSLUbuntu18.4.2LTS下的pyserial有一个奇怪的问题

我设置了一个简单的函数将GCODE命令发送到串口:

代码语言:javascript
复制
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

  • I G0 X1

  • and G1 X0 >设备响应

  • 等等.

我的设置代码是:

代码语言:javascript
复制
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

我可以暂时绕开延迟,但这很烦人,我找不到其他人也在经历同样的事情。知道是什么导致的吗?

EN

回答 2

Stack Overflow用户

发布于 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()通过缓冲区并返回已经存在但之前没有读取的完整行时,程序会收到一个空响应。

票数 0
EN

Stack Overflow用户

发布于 2020-03-22 13:29:58

开始吧。注释中出现的代码。它的大部分删除和错误检查也。

它是一个通过蓝牙在Symbian系列的诺基亚智能手机上使用PyS60 Python控制台的打字终端。效果非常好。

代码语言:javascript
复制
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()
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/60798992

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档