【问题标题】:Reset an open serial port重置打开的串行端口
【发布时间】:2019-11-04 07:28:52
【问题描述】:

我正在从 arduino 发送的串行端口读取数据。

我有两个文件,我分别使用它们来编写一些代码并尝试不同的东西。在其中一个中,我读取数据并使用 matplotlib 图形绘制它。在我使用完它后,它仍然连接到我的计算机并发送数据。所以,我需要做的是“重置”端口。也就是说,关闭打开的端口并再次打开它,并阻止它发送数据,这样我就可以使用 arduino 尝试对该文件的代码进行一些修改。

为了完成这个,我的意思是,为了重置端口,我创建了另一个文件并编写了以下代码:

import serial

print "Opening port"

try:
  serial_port = serial.Serial("com4", 9600)
  print "Port is open"

except serial.SerialException:
  serial.Serial("com4", 9600).close()
  print "Port is closed"
  serial_port = serial.Serial("com4",9600)
  print "Port is open again"

print "Ready to use"

但此代码似乎不起作用。端口仍处于连接状态并正在发送数据。所以,这意味着我不能用我的代码关闭端口,然后重新打开它。

我做错了什么?如何阻止 arduino 发送数据?或者我怎样才能重置 thw arduino,也许?

希望你能帮助我。

----- 编辑 -----

我完成了找出我遇到的真正问题,这不是我想的那样。问题不在于端口是开放的,尽管我使用了 Pyserial 拥有的closefunction。真实情况是端口正在按我的意愿关闭,但设备(arduino)仍在发送数据。所以,我改变了代码来重现这种情况。

这是代码:

print "Abriendo puerto"

ser = serial

try:
  ser = serial.Serial("com4", 9600, timeout = 1)
  serial_port = "Open"
  print "The port %s is available" %ser

except serial.serialutil.SerialException:
  print "The port is at use"

  ser.close()
  ser.open()

while ser.read():
  print "Sending data"

ser.setBreak(True)
time.sleep(0.2)

ser.sendBreak(duration = 0.02)
time.sleep(0.2)

ser.close()
time.sleep(0.2)
print "The port is closed"

exit()

有了这段代码,我要做的是:

1) 我打开串口

2)如果设备正在发送数据,我打印“发送数据”

3) 1 秒后,我尝试关闭端口并停止设备发送数据

我用close 函数尝试了最后两件事来关闭端口,并阅读了我用setBreaksendBreak 尝试的文档,如您在上面的代码中所见(我故意留下它们)。但是设备仍在发送数据,这意味着代码不起作用。

那么,有没有办法告诉 arduino “停止发送数据”,或者我可以重置设备吗?

【问题讨论】:

  • “我做错了什么?” -- 你并没有解释 “不工作” 是什么意思以及你所期望的.您期望 "reset" 做什么?为什么你认为你需要它?您可能在问XY question。 IOW 你试图解决错误的问题并提出错误的问题。
  • 感谢您的评论。我将问题编辑得更清楚。
  • 按照您的描述我有问题(例如过度使用 "it")。你假设太多而忽略太多。是什么让您认为串行端口的“重置”“阻止 arduino 发送数据”? (目标端口对发送端口几乎/没有控制权。)“或者我如何重置 thw arduino,也许?” -- 你想做什么?您可以使用硬件流控制暂停数据传输。您可以实现传输协议。您可以添加一条控制线来强制对 Arduino 进行硬重置。
  • 再次感谢您的回答。你在哪里对,我的问题不清楚。所以我再次编辑了我遇到的真正问题,感谢您和其他回答的用户。再次感谢您,希望您能帮助我。
  • 我不使用 Arduino 的东西,所以我没有答案。串行链路(以及一般的通信链路)可以分为两种配置。 (1)主从。主设备授予从设备发送权限。通常这是一个简单的请求(来自主机)和响应(来自从机)对话框。 (2) 点对点。任何人都可以发送给任何人;您选择接受或不接受请求,以及响应或不响应。那么,您要使用哪种拓扑?似乎您需要在 Arduino 中实现一个协议处理程序,以便它接受关闭命令。或者使用调制解调器控制线。

标签: python serial-port pyserial


【解决方案1】:

我做了一个非常相似的事情,成功的两种方式。

第一种方法是让Arduino连续发送数据。这里的问题是,当您的 python 代码唤醒并开始从串行端口读取时,Arduino 可能在其程序中的任何位置。简单的解决方案是修改 Arduino 代码以发送某种“重启”行。在这种情况下,您需要做的所有 python 代码就是等待“重启”,然后读取真实数据,直到它再次看到“重启”。我有嘈杂的行,所以我的代码通过多个周期读取(和解析)以确保它得到良好的数据。

resetCount = 0;
while resetCount < 3:
    line = s.readline().rstrip("\r\n")
    if string.find(line, "restart") != -1 :
        resetCount += 1
    elif resetCount > 0 :
        fields = string.split(line, " ")
        dict[fields[0]] = fields

第二种方法是使用 Arduino 实现命令响应协议,其中 Arduino 仅在请求时发送数据。在这种情况下,您的 python 代码向 Arduino 发送一个命令(下例中的“RT”),然后从 Arduino 读取数据,直到它看到“完成”行或超时。

        dict = {}
        regex = re.compile('28-[0-9A-Fa-f]{12}') # 28-000005eaa80e

        s = serial.Serial('/dev/ttyS0', 9600, timeout=5)
        s.write("RT\n");

        while True:
            line = s.readline().rstrip("\r\n")
            print line
            if string.find(line, "completed") != -1:
                break;

            fields = string.split(line)
            if (regex.match(fields[0]) != None and len(fields) == 4) :
                dict[fields[0]] = fields
        s.close()

【讨论】:

    【解决方案2】:

    有可能当您关闭端口时,数据仍然来自 arduino 并被操作系统缓冲。在您的脚本调用 close() 和设备驱动程序实际关闭内容之间存在短暂的延迟。

    立即重新打开可能允许驱动程序在不重置其缓冲区的情况下继续运行。这是设备驱动缓冲区,不是 Python 串口实例看到的。

    如果您在调用 close() 之后至少等待几秒钟,然后再尝试调用 open(),那么行为应该如您所愿。

    我刚刚花了一天的大部分时间来弄清楚这是阻止我的代码正常工作的原因。

    【讨论】:

      【解决方案3】:

      我认为您必须在创建后立即执行 serial_port.open() 才能真正打开端口。

      它看起来也只是打开端口并在成功时退出。也许我在这里遗漏了一些东西。我从未使用过 pySerial,我只是按照文档进行操作。

      【讨论】:

      • 感谢您的回答。不,只要使用serial_port = serial.Serial("com4", 9600),端口就打开了。
      • 哦,我正在阅读文档,其中指出:“当给定端口时,该端口在对象创建时立即打开。当端口为 None 并且连续调用 open( ) 是必须的。”这是在类 serial.Serial 部分下。 link 奇怪的是它不能那样工作。
      【解决方案4】:

      尝试使用句柄关闭端口,而不是再次调用构造函数。 如果您的端口已打开并且您调用 serial.Serial("com4", 9600) 它将尝试再次重新打开端口并失败。

      如果 serial_port 分配成功,则 serial_port.close() 应该关闭它。

      【讨论】:

      • 感谢您的回答。我已经尝试过了,我仍然可以让它工作。我编辑了问题以更好地解释我的问题。希望你能帮助我
      猜你喜欢
      • 2013-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-08-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多