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

使用pyserial向Arduino写入数据遇权限拒绝错误,求排查方案

Arduino串口权限错误(PermissionError 13)排查方案

问题描述

我尝试使用pyserial库向连接在USB端口(COM6)的Arduino发送1或0以控制LED亮灭,Arduino端代码正常,整套流程在朋友电脑上可正常运行,但我的设备执行ser = serial.Serial("COM6", 9600)时,抛出错误:

serial.serialutil.SerialException: could not open port 'COM6': PermissionError(13, 'Access is denied.', None, 5)

已关闭所有可能占用串口的程序(包括Arduino IDE),并更新、重启电脑,问题仍未解决。


Arduino控制代码

#define LED_PIN 12

void setup()
{
  // 初始化9600波特率的串口通信
  Serial.begin(9600);

  pinMode(LED_PIN, OUTPUT);
}

void loop()
{
  if (Serial.available() > 0) {
    char cmd = Serial.read();
    if (cmd == '1') {
      digitalWrite(LED_PIN, HIGH);
      Serial.println("LED turned on!");
    }
    else if (cmd == '0') {
      digitalWrite(LED_PIN, LOW);
      Serial.println("LED turned off!");
    }
  }
}

Flask-Python控制代码

import numpy
from flask import Flask, render_template, session, redirect
from functools import wraps
import pymongo
import serial

app = Flask(__name__)

# 设置密钥
app.secret_key = ...

# 数据库连接
client = pymongo.MongoClient(...)
db = client.user_login_system

# 登录验证装饰器
def login_required(f):
    @wraps(f)
    def wrap(*arg, **kwargs):
        if 'logged_in' in session:
            return f(*arg, **kwargs)
        else:
            return redirect('/')
        
    return wrap

# 导入其他路由
from user import routes

# 首页路由
@app.route('/')
def home():
    return render_template('home.html')

# 仪表盘路由(需登录)
@app.route('/dashboard/')
@login_required
def dashbaord():
    return render_template("dashboard.html", status='OFF')

# 全局初始化串口连接
ser = serial.Serial("COM6", 9600)

# LED开启路由
@app.route('/turn_on/')
def turn_on():
    ser.write(b'1')
    return render_template("dashboard.html", status="LED is ON")

# LED关闭路由
@app.route('/turn_off/')
def turn_off():
    ser.write(b'0')
    return render_template("dashboard.html", status="LED is off")

故障排查建议

  • 确认串口编号准确性:打开设备管理器(Win+X → 设备管理器),展开「端口(COM和LPT)」,核实Arduino对应的串口是否为COM6,设备重启或重新插拔后端口号可能变动。
  • 以管理员身份运行程序:右键点击Python脚本或终端,选择「以管理员身份运行」,普通用户权限可能无法访问串口设备。
  • 检查串口驱动状态:在设备管理器中查看Arduino对应的串口设备是否有黄色感叹号,若有则卸载驱动后重新安装Arduino官方驱动。
  • 清理后台隐藏进程:打开任务管理器(Ctrl+Shift+Esc),切换到「详细信息」标签,搜索并结束所有涉及串口通信的进程(如串口调试工具、残留的Python进程),再重试。
  • 调整串口初始化时机:当前代码在Flask启动时就全局初始化串口,若程序多次重启会导致串口被占用。建议将串口初始化移至路由函数内,使用上下文管理器确保连接关闭:
    @app.route('/turn_on/')
    def turn_on():
        with serial.Serial("COM6", 9600, timeout=1) as ser:
            ser.write(b'1')
        return render_template("dashboard.html", status="LED is ON")
    
  • 测试基础串口连通性:先运行极简脚本排除Flask框架影响:
    import serial
    try:
        ser = serial.Serial("COM6", 9600, timeout=2)
        print("串口打开成功")
        ser.write(b'1')
        print(ser.readline().decode('utf-8'))
        ser.close()
    except Exception as e:
        print(f"错误:{e}")
    
  • 更换USB端口/数据线:换一个USB接口连接Arduino,或更换支持数据传输的USB线(部分廉价线仅支持充电)。
  • 禁用系统串口服务:Windows的Serial Console服务可能占用串口,管理员身份打开CMD执行以下命令后重启电脑:
    reg add HKLM\SYSTEM\CurrentControlSet\Services\Serial /v Start /t REG_DWORD /d 4 /f
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.25 14:37:31