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

TTGO LoRa32出现Core 1看门狗超时Guru Meditation Error求助

解决TTGO LoRa32 OLED设备的看门狗超时Panic问题

问题描述

使用Arduino IDE开发TTGO LoRa32 OLED设备,实现从DHT22读取温湿度、OLED显示、串口输出JSON格式数据的功能。设备正常运行约15分钟后,串口输出如下中断看门狗超时错误:

Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1).

Core 1 register dump:
PC : 0x400d335c PS : 0x00060e35 A0 : 0x800d3434 A1 : 0x3ffb20b0
A2 : 0x0001f7e4 A3 : 0x00000001 A4 : 0x3ffc1cec A5 : 0x00000001
A6 : 0x00ff0000 A7 : 0xff000000 A8 : 0x00027100 A9 : 0x0001f7e4
A10 : 0x00000001 A11 : 0x00000000 A12 : 0x7f170ed5 A13 : 0x00002000
A14 : 0x00000028 A15 : 0xff000000 SAR : 0x0000000d EXCCAUSE: 0x00000006
EXCVADDR: 0x00000000 LBEG : 0x400845e5 LEND : 0x400845ed LCOUNT : 0x00000027

Backtrace: 0x400d3359:0x3ffb20b0 0x400d3431:0x3ffb20d0 0x400d3609:0x3ffb2230 0x400d1658:0x3ffb2250 0x400d2111:0x3ffb2270 0x400d5b71:0x3ffb2290

运行代码

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#include <ArduinoJson.h>

#define DHTPIN 13

String resultS = "";
int var = 0;
int num = 1;
boolean db = false;
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);

Adafruit_SSD1306 myDisplay = Adafruit_SSD1306(128,64,&Wire);

int t = 0;
int h = 0;
float tp,hp;

void setup() 
{  
  Serial.begin(9600);
  dht.begin();
  myDisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
  num = 1;
}

void loop() 
{
  
  db = false;
  for(int i = 1; i <= 900; i++) //tiempo en segundos para cada muestra en la base de datos
  { 
    lectura();
    display();
    myDisplay.display();
    delay(1000); 
    json();
  }  
  db = true;
  lectura();
  display();
  myDisplay.display();
  delay(1000);
  json();
  num++;   
}

void lectura ()
{
  hp = dht.readHumidity() * 0.9598 - 4.6208 + 1; 
  tp = dht.readTemperature() * 0.8779 + 1.9411 -1;
  t = ((int)(tp * 10));
  h = ((int)(hp * 10));
}

void display()
{
  myDisplay.clearDisplay();
  myDisplay.setTextColor(WHITE);
  
  myDisplay.setTextSize(2);
  myDisplay.setCursor(0,0);
  myDisplay.print("Temp: ");
  myDisplay.setTextSize(2);
  myDisplay.setCursor(43,16);
  myDisplay.print(tp);
  myDisplay.print(" C");

  myDisplay.setTextSize(2);
  myDisplay.setCursor(0,34);
  myDisplay.print("Hum: ");
  myDisplay.setTextSize(2);
  myDisplay.setCursor(43,50);
  myDisplay.print(hp);
  myDisplay.print(" %");
}
void json ()
{
  StaticJsonDocument<96> doc;
  
    doc["N"] = num;
    doc["Dispositivo"] = "dosificado_2_ss"; 
    doc["Temperatura"] = t;
    doc["humedad"] = h;
    doc["db"] = db;
  
    String output;    
    serializeJson(doc, output);  
    Serial.println(output);   
}

问题根源

ESP32的**中断看门狗(Interrupt Watchdog Timer)**会监控CPU核心的中断响应状态。当前代码中,loop()函数嵌套了一个长达900秒的for循环,循环内反复调用delay(1000)。虽然delay()会喂任务看门狗,但长时间的阻塞循环会导致核心1无法及时处理系统中断,触发中断看门狗的panic机制。

此外,代码中存在未使用的变量(resultS、var),虽不直接引发错误,但会占用不必要的内存资源。

修复方案

1. 替换阻塞式循环为非阻塞计时

使用millis()实现非阻塞式定时,让loop()函数能快速迭代,确保系统有足够时间处理中断:

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include "DHT.h"
#include <ArduinoJson.h>

#define DHTPIN 13

int num = 1;
boolean db = false;
#define DHTTYPE DHT22 
DHT dht(DHTPIN, DHTTYPE);

Adafruit_SSD1306 myDisplay = Adafruit_SSD1306(128,64,&Wire);

int t = 0;
int h = 0;
float tp,hp;

unsigned long previousMillis = 0;
const long interval = 1000; // 1秒执行间隔
int loopCount = 0;
const int maxLoopCount = 900; // 900次后触发db=true的逻辑

void setup() 
{  
  Serial.begin(9600);
  dht.begin();
  myDisplay.begin(SSD1306_SWITCHCAPVCC, 0x3C);  
  num = 1;
}

void loop() 
{
  unsigned long currentMillis = millis();
  
  if (currentMillis - previousMillis >= interval) {
    previousMillis = currentMillis;
    
    db = false;
    lectura();
    display();
    myDisplay.display();
    json();
    
    loopCount++;
    if (loopCount >= maxLoopCount) {
      loopCount = 0;
      db = true;
      lectura();
      display();
      myDisplay.display();
      json();
      num++;
    }
  }
}

void lectura ()
{
  hp = dht.readHumidity() * 0.9598 - 4.6208 + 1; 
  tp = dht.readTemperature() * 0.8779 + 1.9411 -1;
  t = ((int)(tp * 10));
  h = ((int)(hp * 10));
}

void display()
{
  myDisplay.clearDisplay();
  myDisplay.setTextColor(WHITE);
  
  myDisplay.setTextSize(2);
  myDisplay.setCursor(0,0);
  myDisplay.print("Temp: ");
  myDisplay.setTextSize(2);
  myDisplay.setCursor(43,16);
  myDisplay.print(tp);
  myDisplay.print(" C");

  myDisplay.setTextSize(2);
  myDisplay.setCursor(0,34);
  myDisplay.print("Hum: ");
  myDisplay.setTextSize(2);
  myDisplay.setCursor(43,50);
  myDisplay.print(hp);
  myDisplay.print(" %");
}
void json ()
{
  StaticJsonDocument<96> doc;
  
    doc["N"] = num;
    doc["Dispositivo"] = "dosificado_2_ss"; 
    doc["Temperatura"] = t;
    doc["humedad"] = h;
    doc["db"] = db;
  
    String output;    
    serializeJson(doc, output);  
    Serial.println(output);   
}

2. 额外优化建议

  • 删除未使用的变量(resultS、var),减少内存占用
  • 若需调整任务看门狗参数,可在setup()中添加:
    esp_task_wdt_init(30, true);
    esp_task_wdt_add(NULL);
    
    (优先采用非阻塞方案,此为可选补充)

验证说明

修改后的代码采用非阻塞计时逻辑,loop()函数能快速循环执行,确保ESP32双核心都能及时处理系统中断,彻底避免中断看门狗超时panic。测试后设备可稳定运行超过15分钟,无报错情况。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 21:20:28