【问题标题】:Serial (COM)-Port reconnect on Windows串行 (COM) - Windows 上的端口重新连接
【发布时间】:2015-08-18 11:48:14
【问题描述】:

我正在编写一个通过串行连接到 Arduino 或 Teensy 的小软件。我希望软件能够识别 USB-Serial 是否断开连接,并在再次插入时自动重新连接。

这在 Linux 下非常简单,但我什至不确定在 Windows 上是否可行,因为我发现的所有终端程序在断开连接后无法重新连接到 COM 端口而不重新启动。

我目前正在使用 QT5 QSerialPort 实现,但如果有人知道能够正确重新连接而无需重新启动程序的 C++ 类,我会在一秒钟内进行更改。

另外,如果有人知道可以自动重新连接的串行终端程序,我将不胜感激。

edit我使用的是 64 位 Win7,通常是 32 位程序。

【问题讨论】:

  • 如果重新连接,为什么需要重新启动程序?我使用了类似的东西,但使用了 python,并且我使用了一个线程来通过串行端口获取数据。它工作正常。
  • 你有python的示例代码吗?这在 Windows 上确实有效吗?我不知道为什么我必须重新启动,但是我尝试过的 Putty、hTerm、hyperterm 和其他 3 个工具也必须重新启动。
  • 我将其发布为答案,因为它有太多字符无法发表评论。
  • 典型的 USB 设备驱动程序和 5 美元的硬件无法完成这项任务,您必须花费真金白银。 始终在断开连接之前使用“安全删除硬件”托盘图标。
  • 为什么这是驱动问题?断开设备后驱动程序没有卸载吗?或者它保持打开状态,因为它没有正确关闭......下面的python示例证明它可以做到。

标签: c++ windows serial-port


【解决方案1】:

关键是,当连接到串行端口的设备断开连接时,您将在 readline 中收到 null,因此如果它为 null,您将尝试重新连接。此外,您需要设置超时,否则 readline 将永远等待。 Python 示例:

import serial
import threading
import time
class MainTHread(threading.Thread):
    def __init__(self):
        threading.Thread.__init__(self)
        self._data = ""
        self.ser = None
    def run(self):
        while(True):
            try:
                time.sleep(1)
                ser = serial.Serial('COM3',9600,timeout=2)

            except serial.SerialException as err:
                print("Connection failed")
                try:
                    ser.close()
                except UnboundLocalError:
                    print("No Serial")
                print(err)
                continue
            while True:
                try:
                    print("Trying to read")
                    data_json = ser.readline()
                    self._data =data_json.decode('UTF-8');
                    if(not self._data):
                        break
                    print("Main Thread " + self._data)
                except serial.SerialException as err:
                    print("Connection failed")
                    ser.close()
                    break
    def getData(self):
        return self._data
thread = MainTHread()
thread.start()

【讨论】:

  • 感谢您的代码,但它对我不起作用。当我断开 USB/串行端口然后重新插入时,它再次出现在同一个 COM 端口下,但 python 脚本返回“连接失败”并且err 包含“系统找不到指定的文件”。这是我经常遇到的错误。系统是 Windows 7 64 Bit,我安装了 32bit python & pyserial btw。
  • 尝试增加超时时间
  • serial.Serial... 调用后立即发生错误。我将超时时间增加到 10,但没有成功。
  • 这很奇怪。像当您重新连接时,您的设备无法识别。将此块 except serial.SerialException as err: print("Connection failed") break 替换为 except serial.SerialException as err: print("Connection failed") ser.close() break
  • 正好解决了这个问题。您必须确保在第一次尝试时不执行ser.close,即当您从设备断开连接开始时。
【解决方案2】:

在 Powershell 上更轻松:

function triaComPort(){
$selection = [System.IO.Ports.SerialPort]::getportnames()

If($selection.Count -gt 0){
    $title = "Serial port selection"
    $message = "Which port would you like to use?"

    # Build the choices menu
    $choices = @()
    For($index = 0; $index -lt $selection.Count; $index++){
        $choices += New-Object System.Management.Automation.Host.ChoiceDescription $selection[$index]
    }

    $options = [System.Management.Automation.Host.ChoiceDescription[]]$choices
    $result = $host.ui.PromptForChoice($title, $message, $options, 0) 

    $selection = $selection[$result]
}

return $selection
}

$port = triaComPort

if(!$port){"Must choose";return}

Write-Host $("Port:"+$comport)
$port= new-Object System.IO.Ports.SerialPort $port,57600,None,8,one

while($true){
    if(!$port.IsOpen){
        try{
            $port.Open()
            write-host "+" 
        }catch{
            write-host "-" -NoNewline
        }
    }
    if($port.BytesToRead -gt 0){
        Write-Host $port.ReadExisting()
    }
}
$port.Close()

此脚本打印 - 无法连接时和 + 连接时,速度固定为 57600,您可以更改它。

希望对你有帮助。

【讨论】:

    猜你喜欢
    • 2010-11-15
    • 2012-08-09
    • 1970-01-01
    • 1970-01-01
    • 2012-09-16
    • 2012-01-07
    • 2013-11-03
    • 2010-12-13
    • 1970-01-01
    相关资源
    最近更新 更多