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

Arduino串口输出存CSV遇[Errno16]资源占用问题求助

串口资源占用错误排查与CSV保存方案

问题背景

我在Arduino Mega板上搭建了热敏电阻采集电路,使用以下代码实现温度采集与串口输出:

int ThermistorPin = 0; //pin number connected to thermistor
int Vo; //stores analog reading from thermistor
float R1 = 10000; //resistance value of the fixed resistor
float logR2, R2, T, Tc, Tf; //variables used for calculations related to thermistor & temperature
float c1 = 1.009249522e-03, c2 = 2.378405444e-04, c3 = 2.019202697e-07; //steinhart-hart coefficients

void setup() //initialize serial communication with a baud rate of 9600
{
Serial.begin(9600);
}

void loop() //repeated function
{
  unsigned long currentTime = millis(); //time in milliseconds

  // Calculate hours, minutes, and seconds from milliseconds
  unsigned long seconds = currentTime / 1000;
  unsigned long minutes = seconds / 60;
  seconds = seconds % 60;
  minutes = minutes % 60;

  Vo = analogRead(ThermistorPin); //reads analog input from thermistor connected to ThermistorPin
  R2 = R1 * (1023.0 / (float)Vo - 1.0); //calculates resistance of thermistor from analog reading
  logR2 = log(R2); 
  T = (1.0 / (c1 + c2*logR2 + c3*logR2*logR2*logR2)); //steinhart-hart equation
  T = T - 273.15;

  Serial.print(minutes);
  Serial.print(":");
  Serial.print(seconds);
  Serial.print(", ");
  Serial.println(T);

  delay(1000);
}

尝试用以下Python代码读取串口输出并保存到CSV文件:

import serial
import csv


serial_port = '/dev/cu.usbmodem1101'
baud_rate = 9600

#initialize serial connection
ser = serial.Serial(serial_port, baud_rate)

#empty lists to store data
timestamps = []
temps = []

def read_and_process_data():
    line = ser.readline().decode('utf-8').strip() #read a line & decode & remove white space
    values = line.split(', ') #split line into string using commas as separator
    
    timestamps.append(str(values[0])) #append values to empty list
    temps.append(float(values[1]))
    
    print(f'timestamp: {values[0]}, temp: {values[1]}') 
    
    with open('arduino_data.csv', 'w', newline = '') as csvfile: 
        writer = csv.writer(csvfile)
        writer.writerow(['timestamp', 'temp'])
        for ts, tp in zip(timestamps, temps):
            writer.writerow([ts, tp])

运行Python代码时出现错误:

SerialException: [Errno 16] could not open port /dev/cu.usbmodem1101: [Errno 16] Resource busy: '/dev/cu.usbmodem1101'

错误排查步骤

  • 关闭占用串口的程序:检查Arduino IDE的串口监视器、Screen、CoolTerm等工具是否正在使用该端口,关闭后再运行Python脚本。
  • 确认端口路径:在Arduino IDE的「工具」→「端口」中查看当前Arduino对应的端口,确保Python代码里的serial_port路径与实际一致。
  • 权限修复(Linux/macOS):Linux执行sudo usermod -a -G dialout $USER,macOS临时执行sudo chmod 666 /dev/cu.usbmodem1101,重启终端后重试。
  • 重启设备:异常占用导致端口卡住时,重启Arduino和电脑后再尝试连接。

优化后的Python代码

原代码存在未循环调用读取函数、每次写入覆盖文件的问题,优化后版本:

import serial
import csv
import time

serial_port = '/dev/cu.usbmodem1101'
baud_rate = 9600

# 初始化串口,添加超时避免卡死,等待Arduino重启
ser = serial.Serial(serial_port, baud_rate, timeout=1)
time.sleep(2)

# 初始化CSV文件并写入表头
with open('arduino_data.csv', 'w', newline='') as csvfile:
    writer = csv.writer(csvfile)
    writer.writerow(['timestamp', 'temp'])

    try:
        while True:
            line = ser.readline().decode('utf-8').strip()
            if line:
                try:
                    timestamp, temp = line.split(', ')
                    writer.writerow([timestamp, float(temp)])
                    print(f'timestamp: {timestamp}, temp: {temp}')
                except ValueError:
                    print(f'无效数据行: {line}')
            time.sleep(1)
    except KeyboardInterrupt:
        print('采集停止')
    finally:
        ser.close()

替代工具推荐

  • Arduino IDE串口监视器:点击右上角「保存」按钮将输出存为.txt,再手动转CSV或用Excel另存为CSV格式。
  • CoolTerm:跨平台免费串口工具,支持直接将数据保存为CSV,操作简单。
  • PuTTY:Windows平台常用,开启日志功能保存输出后再转换格式。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.30 18:57:39