You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Ubuntu Linux下无法读写串口问题排查求助

问题描述

我编写了如下Python脚本用于串口读写,在Windows系统下可正常操作COM3端口(连接的是能通过串口返回数据的Arduino)。但在Ubuntu Linux系统中使用/dev/tty2端口时无法正常工作:已将自身加入对应用户组,串口对象显示已连接,但连接后无任何数据交互。另外,/dev/tty1和/dev/tty3无法连接,这是否说明/dev/tty2的权限配置正常?实际上我更希望连接/dev/tty1,但始终无法获取该端口的访问权限。

# This test file will write / read to a COM port on Windows but not on
# Ubuntu Linux against "/dev/tty2". Why? 


import serial

while True:

    try:
        ser = serial.Serial('/dev/tty2', 9600, timeout = 1)

        if ser:
            print("Connected to: ", ser.name)

    except serial.SerialException as e:
        print(f"Error opening serial port: {e}")
        exit()

    try:
        ser.write(b"Test from Python\n")

        while True: 
            data = ser.readline()
            if data:
                print("Received: ", data.decode().strip())

    except Exception as e:
        print(f"Error during communication: {e}")
    finally:
        # Close the serial port
        if ser.is_open:
            ser.close()
            print("Serial port closed")

问题分析与解决方法

1. 核心误区:Linux下的TTY设备区分

/dev/tty1、/dev/tty2这类设备是虚拟控制台终端,并非Arduino使用的串口设备。这就是为什么:

  • 你能打开/dev/tty2但无数据交互:它只是系统的控制台窗口,和Arduino无关
  • /dev/tty1//dev/tty3无法连接:这些控制台通常被系统占用,普通用户没有访问权限

Arduino在Linux下会被识别为/dev/ttyACM*(大部分官方板)或/dev/ttyUSB*(第三方USB转串口芯片的板)。

2. 找到正确的Arduino串口设备

  • 插拔Arduino前后,执行以下命令对比,找到新增的设备:
    ls /dev/ttyACM* /dev/ttyUSB*
    
  • 或者查看内核日志确认设备路径:
    dmesg | grep tty
    
    日志中会显示类似usb 1-1.2: ch341-uart converter now attached to ttyUSB0的信息,ttyUSB0就是目标端口。

3. 配置串口访问权限

  • 将当前用户加入dialout组(Linux下串口设备的默认所属组):
    sudo usermod -aG dialout $USER
    
  • 注销并重新登录,让权限变更生效
  • 验证权限:执行ls -l /dev/ttyACM0(替换为你的设备路径),确认所属组为dialout,且当前用户有读写权限。

4. 调整Python脚本

将脚本中的串口路径替换为找到的正确设备(比如/dev/ttyACM0),同时优化脚本逻辑(原外层while循环会重复打开串口,易导致异常):

import serial
import time

def main():
    # 替换为正确的串口设备路径
    port = '/dev/ttyACM0'
    baud_rate = 9600
    ser = None

    try:
        ser = serial.Serial(port, baud_rate, timeout=1)
        print(f"Connected to: {ser.name}")

        while True:
            # 发送测试数据
            ser.write(b"Test from Python\n")
            # 读取返回数据
            data = ser.readline()
            if data:
                print(f"Received: {data.decode().strip()}")
            time.sleep(0.1)

    except serial.SerialException as e:
        print(f"Error opening serial port: {e}")
    except Exception as e:
        print(f"Error during communication: {e}")
    finally:
        if ser and ser.is_open:
            ser.close()
            print("Serial port closed")

if __name__ == "__main__":
    main()

内容的提问来源于stack exchange,提问作者DaveFer

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 23:50:03