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

ESP32中断代码运行触发Guru Meditation错误求助

ESP32中断看门狗超时(Guru Meditation Error)问题排查与修复

在Arduino IDE 2.1.0环境下开发ESP32中断相关代码时,持续触发Guru Meditation Error,错误显示Core 1因CPU1中断看门狗超时panic。代码预期通过引脚18、19的外部触发切换MainLoop变量值,进入对应主循环逻辑,以下是错误日志、问题分析及修复方案。

错误日志

Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).
Core 1 register dump:
PC : 0x4008e6b4 PS : 0x00060c35 A0 : 0x8008d64e A1 : 0x3ffbefac
A2 : 0x3ffb8a00 A3 : 0x3ffb8890 A4 : 0x00000004 A5 : 0x00060c23
A6 : 0x00060c23 A7 : 0x00000001 A8 : 0x3ffb8890 A9 : 0x00000018
A10 : 0x3ffb8890 A11 : 0x00000018 A12 : 0x3ffc42d4 A13 : 0x00060c23
A14 : 0x007bf158 A15 : 0x003fffff SAR : 0x0000000e EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x40089c09 LEND : 0x40089c19 LCOUNT : 0xfffffffc
Core 1 was running in ISR context:
EPC1 : 0x400dffeb EPC2 : 0x00000000 EPC3 : 0x00000000 EPC4 : 0x00000000
Backtrace:0x4008e6b1:0x3ffbefac |<-CORRUPTED
Core 0 register dump:
PC : 0x4008e833 PS : 0x00060035 A0 : 0x8008d277 A1 : 0x3ffbeaac
A2 : 0x3ffbf158 A3

问题根源

  1. ISR内执行耗时/阻塞操作:LimitSwitches中断服务函数中调用SensorN17.getCumulativePosition(),该函数涉及I2C总线操作,属于依赖中断的耗时操作。ESP32的ISR要求尽可能短小,不能执行阻塞或依赖其他中断的代码,否则会导致中断看门狗超时。
  2. Switch语句缺少Break:ISR中的switch未添加break,匹配case 11后会继续执行case 22和default逻辑,造成MainLoop变量被错误修改,逻辑混乱。
  3. 主循环死阻塞:主循环中while(GetTimeN17)是无限死循环,完全阻塞主循环,导致ESP32无法处理系统任务、看门狗喂狗操作,最终触发看门狗panic。
  4. 标志位逻辑错误:主循环末尾每次都将LastLimitState设为true,会覆盖ISR中设置的false,导致中断触发逻辑失效。

修复方案

  1. 简化ISR逻辑:ISR仅负责修改标志位和MainLoop变量,所有耗时操作(如传感器读取、串口打印)移到主循环中执行。
  2. 修复Switch语句:为每个case添加break,避免逻辑串执行。
  3. 替换死循环:将while(GetTimeN17)改为条件判断,每次循环执行一次打印,避免阻塞主循环。
  4. 调整标志位赋值:仅在处理完中断逻辑后,在主循环中重置LastLimitState,而非每次循环都赋值。

修复后的完整代码

#include <Wire.h>
#include <AS5600.h>
#include <WiFi.h>
#include <esp_now.h>
 
#define HES 19
#define LimitPins 18

#define TCA9548A_ADDR 0x70
#define N17AS5600 3
#define N23AS5600 2

#define AS5600_ADDR 0x36

volatile bool HESstate = true;
volatile bool LastHESState = true;
volatile int Count = 0;

volatile bool LimiteState = true;
volatile bool LastLimitState = true;

volatile bool N17Direction = false;

volatile int MainLoop = 1;
volatile int StartValue;
volatile int StopValue;
volatile int DistanceN17;

volatile long LastButtonPress = 0;

volatile bool FirstTimeN17 = false;
volatile bool HomeZeroN17 = false;
volatile bool GetTimeN17 = false;
volatile bool NeedUpdateDistance = false; // 新增标志位,标记需要读取传感器数据

volatile bool FirstTimeN23 = false;
volatile bool HomeZeroN23 = false;

int16_t Angle17;
int16_t Angle23;
int32_t Distance17;
int32_t Distance23;
int32_t OffsetD17;
int32_t OffsetD23;

AS5600 SensorN17;
AS5600 SensorN23;

uint8_t broadcastAddress[] = {0xC8, 0xF0, 0x9E, 0xA6, 0x08, 0xF0};

typedef struct struct_message {
  int MSG;
} struct_message;

struct_message myData;
esp_now_peer_info_t peerInfo;

void TCA9548A(byte bus){
  if(bus > 7) return;
  Wire.beginTransmission(TCA9548A_ADDR);
  Wire.write(1 << bus);
  Wire.endTransmission();
}

void SetupInterrupts(){
  pinMode(HES, INPUT_PULLUP);
  attachInterrupt(HES, HallEffectSensor, FALLING);

  pinMode(LimitPins, INPUT_PULLUP);
  attachInterrupt(LimitPins, LimitSwitches, RISING);
}

void SetupTCA9548A(){
  TCA9548A(N17AS5600);
  SensorN17.begin(21, 22); // .begin(sda, scl) pour ESP32
 
  TCA9548A(N23AS5600);
  SensorN23.begin(21, 22); // .begin(sda, scl) pour ESP32
  OffsetD23 = -1 * SensorN23.getCumulativePosition();
}

void SetupESP_NOW(){
  WiFi.mode(WIFI_STA);

  if(esp_now_init() != ESP_OK){
    Serial.println("Error initializing ESP-NOW");
    return;
  }
  
  memcpy(peerInfo.peer_addr, broadcastAddress, 6);
  peerInfo.channel = 0;  
  peerInfo.encrypt = false;
      
  if(esp_now_add_peer(&peerInfo) != ESP_OK){
    Serial.println("Failed to add peer");
    return;
  }
}

void setup() {
  Serial.begin(9600);
  Wire.begin();

  SetupInterrupts();
  SetupTCA9548A();
  SetupESP_NOW();

  delay(5000);
}

void loop() {
  // 处理传感器数据读取
  if(NeedUpdateDistance){
    TCA9548A(N17AS5600); // 切换到N17的I2C总线
    DistanceN17 = SensorN17.getCumulativePosition();
    NeedUpdateDistance = false;
  }

  if(MainLoop == 1){
    myData.MSG = 170; // 170: Nema17 va UP.
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
    MainLoop = 11;
  }

  // 替换死循环为条件判断,每次循环执行一次打印
  if(GetTimeN17){
    Serial.print("Temps: ");
    Serial.print(StopValue - StartValue);
    Serial.print(" | Vitesse: ");
    Serial.println(DistanceN17 / (StopValue - StartValue));
    // 如果需要停止打印,可以添加停止条件,比如设置GetTimeN17 = false
  }

  if(MainLoop == 2){
    myData.MSG = 171; // 171: Nema17 va DOWN.
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
    MainLoop = 22;

    if(!FirstTimeN17){
      StartValue = millis();
      FirstTimeN17 = true;
    }
  }

  if(MainLoop == 9){
    myData.MSG = 179; // 179: Nema17 à l'arrêt.
    esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));

    if(!HomeZeroN17){
      TCA9548A(N17AS5600);
      OffsetD17 = -1 * SensorN17.getCumulativePosition();
      HomeZeroN17 = true;
      MainLoop = 2;
    } else {
      MainLoop = 11;
    }
  }

  // 仅在ISR处理完成后重置标志位
  if(!LastLimitState){
    LastLimitState = true;
  }
}

void HallEffectSensor(){
  // 保留原有注释逻辑,如需启用请确保逻辑正确
  /*if(LastHESState){
    if(!N23Homed){
      myData.MSG = 239; // 239: Nema23 à l'arrêt.
      esp_err_t result = esp_now_send(broadcastAddress, (uint8_t *) &myData, sizeof(myData));
      N23Homed = true;
    }
    
    //HESstate = !HESstate;
    LastHESState = false;
  }*/
}

void LimitSwitches(){
  if(LastLimitState){
    switch(MainLoop){
      case 11:
        MainLoop = 9;
        break; // 添加break,避免执行后续case

      case 22:
        MainLoop = 1;
        StopValue = millis();
        NeedUpdateDistance = true; // 设置标志位,让主循环读取传感器数据
        GetTimeN17 = true;
        break; // 添加break

      default:
        MainLoop = 0;
        break;
    }
    LastLimitState = false;
  }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 02:24:59