【问题标题】:Unable to Read/Write using pyserial on Linux (Xubuntu 18.04)无法在 Linux (Xubuntu 18.04) 上使用 pyserial 读取/写入
【发布时间】:2019-07-30 13:48:20
【问题描述】:

我有一个专有设备,它通过 USB 数据线连接到我的计算机。

在我的 Xubuntu 安装上运行代码时,我无法成功读取(或写入,或两者兼而有之?)。

注意:相同的逻辑在 Windows(在 7、8 和 10 上测试)和 Mac(在优胜美地和莫哈韦)。

这是我尝试运行的代码(为简单起见,硬编码了一些值):

ser = serial.Serial('/dev/ttyACM0', 500000, timeout = 0.03, write_timeout = 0.015)
ser.write(bytes([248, 40, 0]))
ser.flush()
reply = ser.read(40)

当前行为

设备正在运行一些代码来响应它收到的数据包。在这个初始数据包中,我的 Python 代码请求设备状态的完整副本,它以高达 40 字节的数组接收该副本。

在 Linux 上,返回以下内容而不是请求的 40 个字节: [248, 13, 10, 40, 13, 10, 0, 13, 10]

我发现有趣的是它返回的字节与我尝试写入的字节完全相同,它们之间有 13 和 10。

预期行为 在 Mac 和 Windows 上,都会返回类似这样的内容(内容并不重要):

[71, 89, 65, 32, 1, 4, 50, 0, 27, 0, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 238, 1, 255, 255, 136, 1, 255, 255, 255, 255]

预期行为与 Mac 和 Windows 上的行为相同。

额外信息

  • 在 Python 3.5 上运行。

  • 我使用的是完全相同的USB设备电缆。

  • 我已经尝试了计算机上的所有端口。

  • 代码在所有操作系统上完全相同,只是端口名称因操作系统的性质不同而不同。

  • 串口确认是我需要的设备(我打印名字),确认打开(我打印串口对象)。

    李>
  • 我玩过 timeoutsbaudrates,但无济于事。

  • 我尝试用if(ser.in_waiting): reply = ser.read() 交换读取,但没有真正改变

  • 我已验证该设备位于端口/dev/ttyACM0

  • 在遇到 OSError: [Errno 13] Permission denied: '/dev/ttyACM0' 错误后,我已向该端口添加权限。

  • 在阅读了此处的一些解决方案后,使用sudo chmod 666 /dev/ttyACM0sudo usermod -aG dialout $USER 添加了权限。

  • 我已经尝试过time.sleep()

  • [EDIT] 尝试了@michael-o 给出的建议。没有运气。

  • 我研究并尝试过的其他一些 SO 问题,排名不分先后:

任何信息/想法将不胜感激!

[EDIT2] 问题变得更加奇怪了。这是我今天尝试的:

  • 首先,我在 Windows 机器上编写了一个 Arduino 程序,以不断打印一个数字并在收到任何内容时使 LED 闪烁。然后我在 Linux 机器上进行了测试,一切正常。

  • 然后,我们对硬件进行了编程以执行相同的操作 - 不断打印一个数字并在收到任何内容时闪烁 LED。

  • 即使逻辑相同,它仍然无法读取或写入任何内容。我什至尝试使用 GtkTerm 来检查设备和计算机之间的通信内容。什么都没有。

  • 但是!向设备发送“X”会触发一个小型定制终端,该终端具有一些内置命令,例如用于压力测试的“S”等。

  • 这里重要的命令是“E”,它会退出终端。如果这样做了(在 GtkTerm 中),设备会突然开始打印前面提到的那个数字。这里的直觉是,在 Linux 上(或至少在 GtkTerm 中),无论出于何种原因,“X”都会发送到设备。所以我们尝试退出那个自定义终端。

  • 不幸的是,这在 Python 中没有。它仍然继续接收与之前描述的相同的数据包。

  • 所以……我们被困住了。但它似乎是一个固件问题捆绑与操作系统的一些奇怪的怪癖。如果我们弄明白了会更新。

【问题讨论】:

    标签: linux python-3.x ubuntu pyserial


    【解决方案1】:

    分辨率:

    操作系统在初始连接后 5-6 秒向设备发送“X”。

    无论启动什么应用程序都会发生这种情况。它在后台执行此操作。

    我们的固件被编程为“X”启动调试模式,我们用它来测试硬件的状态。必须先退出它,然后才能发送/接收任何有价值的东西。

    我不确定为什么系统会发送这个字符,或者是否它只发生在单次安装中,但它是几乎没有附加软件的准系统计算机安装在 VS Code 和 Git 之外。

    [最终更新]

    在其他运行 Linux 的系统(更具体地说,是 Fedora 实例)上也观察到了同样的问题。

    【讨论】:

      【解决方案2】:

      如果在将用户添加到dialout 组后没有这样做,请尝试重新启动计算机。

      连接时尝试发送与您的设备相关的其他信息,例如XON/XOFFparitystopbits 等。

      在脚本开头添加# coding: utf-8

      【讨论】:

      • 嗨迈克尔,感谢您的建议。我都试过了。 1.重启了很多次,但我还是重试了。没有运气。 2.# coding: utf-8 没用。我还从docs.python.org/3.4/howto/unicode.html#the-string-type 尝试了# -*- coding: <encoding name> -*-。 3. 我花了一段时间尝试了XON/XOFFparitystopbits 的所有选项,但它们都得到了来自设备的相同回复。
      • @Ivan 尽量不要写完后flush,而是加个延迟;也可以试试ser.read_all() 而不是ser.read(40)
      • 这些都不起作用。我做了一些进一步的测试(包括向 Arduino 写入/读取以验证问题出在设备上)。如果您好奇,可以查看我的编辑。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      • 2017-10-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-04-22
      • 1970-01-01
      相关资源
      最近更新 更多