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

Mac Sonoma下Python串口读写CSV报OSError: [Errno 6]问题求助

解决方案:Mac Sonoma下Python串口读取+CSV写入的两个问题

一、修复KeyboardInterrupt捕获的语法错误

常见错误是try-except结构缩进错误或except语句写法有误,正确的逻辑是将主循环包裹在try块内,用except捕获中断信号,同时确保中断时释放串口和文件资源。

示例修正代码:

import serial
import csv
import time

# 初始化串口和CSV文件
ser = serial.Serial('/dev/tty.usbmodem14101', 9600, timeout=1)
csv_file = open('data.csv', 'a', newline='')
writer = csv.writer(csv_file)

try:
    while True:
        # 读取串口数据
        data = ser.readline().decode('utf-8').strip()
        if data:
            print(data)
            # 写入CSV
            writer.writerow(data.split(','))
            # 按需刷新缓冲区,避免数据滞留
            csv_file.flush()
        time.sleep(1)
except KeyboardInterrupt:
    print("\n程序被用户终止")
finally:
    # 无论是否中断,都关闭资源
    ser.close()
    csv_file.close()
    print("资源已释放")

二、解决OSError: [Errno 6] Device not configured问题

结合你提到的「无文件写入的代码可长期运行」,推测问题出在串口读取与文件IO的阻塞交互,加上Mac Sonoma的USB/串口管理特性导致。以下是针对性解决方案:

1. 优化文件IO操作,减少阻塞

  • 保持CSV文件句柄长期打开,避免频繁打开/关闭操作
  • 打开文件时设置行缓冲:open('data.csv', 'a', newline='', buffering=1),平衡性能和数据安全性
  • 减少flush()调用频率,比如每10条数据刷新一次,而非每次写入都刷

2. 添加串口异常重连机制

在读取串口时捕获Errno 6错误,尝试重新连接设备,避免程序直接崩溃:

try:
    data = ser.readline().decode('utf-8').strip()
except OSError as e:
    if e.errno == 6:
        print("设备连接丢失,尝试重新连接...")
        ser.close()
        time.sleep(2)  # 等待2秒再重试
        try:
            ser.open()
            print("重新连接成功")
        except Exception as re_conn_err:
            print(f"重新连接失败: {re_conn_err}")
            break
    else:
        raise  # 其他OSError抛出处理

3. 调整Mac系统的USB节能设置

  • 打开「系统设置」→「电池」(台式机选「电源适配器」)→「选项」
  • 取消勾选「如果可能,使端口进入睡眠状态」,防止Mac自动关闭USB端口导致设备断开

4. 升级pyserial库版本

Mac下旧版本pyserial可能存在兼容性问题,执行命令升级:

pip install --upgrade pyserial

5. 用线程分离串口读取与文件写入

将串口读取和CSV写入拆分为独立线程,避免IO阻塞导致串口超时:

import serial
import csv
import time
from threading import Thread, Queue

data_queue = Queue()

def read_serial():
    ser = serial.Serial('/dev/tty.usbmodem14101', 9600, timeout=1)
    try:
        while True:
            data = ser.readline().decode('utf-8').strip()
            if data:
                data_queue.put(data)
            time.sleep(0.1)
    except OSError as e:
        print(f"串口读取错误: {e}")
    finally:
        ser.close()

def write_csv():
    with open('data.csv', 'a', newline='', buffering=1) as csv_file:
        writer = csv.writer(csv_file)
        while True:
            if not data_queue.empty():
                data = data_queue.get()
                writer.writerow(data.split(','))
            time.sleep(0.5)

# 启动线程
serial_thread = Thread(target=read_serial, daemon=True)
csv_thread = Thread(target=write_csv, daemon=True)
serial_thread.start()
csv_thread.start()

# 主线程等待中断
try:
    while True:
        time.sleep(1)
except KeyboardInterrupt:
    print("\n程序终止")

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 04:35:20