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

ESP32-S3串口打印需延迟才能正常输出,求解决方案

解决ESP32-S3串口调试初期打印丢失问题

问题现象

在Arduino框架开发中,使用Serial.println()输出调试信息时,ESP32-S3(如esp32-s3-devkitc-1)会出现setup()打印和loop()前几次打印丢失的情况。依赖固定delay(3500)可以解决,但希望实现像普通ESP32(如esp32doit-devkit-v1)一样的即时调试反馈。

测试代码

#include <Arduino.h>

int loopCount = 0;

void setup() {
  Serial.begin(460800);
//  delay(3500);
  while(!Serial) {}
  Serial.println("setup");
}

void loop() {
  Serial.println(String(++loopCount) + " " + String(millis()));
  delay(1000);
}

硬件表现差异

  • 普通ESP32:注释掉delay和while(!Serial)后,输出正常:
    setup
    1 28
    2 1029
    3 2028
    
  • ESP32-S3:
    • 无delay或while(!Serial)时,丢失前几次打印:
      4 3098
      5 4098
      6 5098
      
    • 使用while(!Serial)时,丢失更多打印:
      5 4098
      6 5098
      7 6098
      8 7098
      

PlatformIO配置

[platformio]
default_envs = esp32
src_dir = src
include_dir = include

[env:esp32]
platform = espressif32
; board = esp32doit-devkit-v1
board = esp32-s3-devkitc-1
framework = arduino
upload_port = /dev/cu.usb*

; Serial Monitor options
monitor_speed = 460800
monitor_filters = colorize
monitor_echo = yes

核心原因

ESP32-S3默认的Serial是USB CDC虚拟串口,而普通ESP32的Serial为硬件UART。USB串口需要完成主机(Mac)的枚举过程才能建立通信,这段时间内ESP32-S3已经执行完setup和早期loop代码,导致打印内容丢失;while(!Serial)会让程序持续等待USB串口就绪,但PlatformIO串口监视器通常在上传完成后才打开,进一步延长等待时间,错过更多输出。

解决方法

方法1:改用硬件UART

ESP32-S3自带多个硬件UART,切换到硬件UART可避开USB枚举问题,和普通ESP32的调试逻辑一致:

void setup() {
  // 使用UART1,引脚TX=17、RX=16(可根据硬件引脚定义调整)
  Serial1.begin(460800, SERIAL_8N1, 16, 17);
  Serial1.println("setup");
}

void loop() {
  Serial1.println(String(++loopCount) + " " + String(millis()));
  delay(1000);
}

同时修改PlatformIO配置的monitor_port,指定硬件UART对应的串口设备(如/dev/cu.usbserial-*)。

方法2:优化USB CDC等待逻辑

如果坚持使用USB CDC串口,将while(!Serial)替换为等待用户输入的逻辑,灵活控制打印时机:

void setup() {
  Serial.begin(460800);
  // 等待用户打开串口监视器并按任意键
  while (!Serial.available()) {
    delay(50);
  }
  // 清空缓冲区,避免输出用户按键内容
  Serial.read();
  Serial.println("setup");
}

方法3:启用早期调试输出

通过ESP-IDF的app_main入口提前初始化串口,在Arduino框架启动前就开始输出调试信息:

  1. 修改PlatformIO配置,添加编译选项:
    [env:esp32]
    platform = espressif32
    board = esp32-s3-devkitc-1
    framework = arduino
    upload_port = /dev/cu.usb*
    build_flags = 
      -D ARDUINO_USB_CDC_ON_BOOT=1
      -D ARDUINO_USB_MODE=1
    monitor_speed = 460800
    monitor_filters = colorize
    monitor_echo = yes
    
  2. 修改代码,添加app_main初始化:
    #include <Arduino.h>
    
    extern "C" void app_main() {
      Serial.begin(460800);
      delay(100); // 给USB枚举留短暂时间
      Serial.println("app_main: early debug");
      initArduino(); // 启动Arduino框架
    }
    
    int loopCount = 0;
    
    void setup() {
      Serial.println("setup");
    }
    
    void loop() {
      Serial.println(String(++loopCount) + " " + String(millis()));
      delay(1000);
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 15:13:15