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

ESP32中断函数发送Telegram消息触发看门狗超时问题求助

ESP32中断中调用Telegram Bot发送消息导致看门狗超时崩溃问题

我基于DFRobot Firebeetle 2(ESP32-WROOM-32E)和Arduino IDE开发项目,实现温度超阈值时通过Telegram Bot发送告警消息的功能,该功能在loop()中运行正常。目前添加了一个状态按钮,计划通过触发中断发送状态消息(后续要使用ESP32休眠功能,休眠时loop()无法执行,故采用中断而非轮询),但在中断函数中发送消息会导致设备崩溃重启。

测试发现:将minStatusMsgInterval设为250并在setup()末尾调用SendStatusMessage()可正常收到消息,说明函数本身无问题,仅在中断调用时出错。错误提示为Guru Meditation Error: Core 1 panic'ed (Interrupt wdt timeout on CPU1),推测bot.sendMessage()执行耗时过长触发看门狗超时,但不确定如何解决,也无法确认是否误解了错误原因。

相关代码

#include <WiFi.h>
#include "WiFiClientSecure.h"
#include <ESP32Time.h>
#include <DFRobot_DHT11.h>
#include <UniversalTelegramBot.h>

//WiFi
#define WLAN_SSID  "ESP32Test"
#define WLAN_PASS "*********"

//WiFiFlientSecure for SSL/TLS support
WiFiClientSecure client;

//Time
ESP32Time rtc(0);  // offset in seconds; 0 = GMT, 3600 = GMT+1

//Telegram
#define TELEGRAM_TOKEN "*********:*************************"
#define CHAT_ID "**********"

UniversalTelegramBot bot(TELEGRAM_TOKEN, client);

//Temperature
DFRobot_DHT11 DHT;
#define DHT11_PIN D11

//Buttons
#define ONBOARD_BUTTON_PIN 27 //ESP32 pin 27
#define STATUS_BUTTON_PIN D10 //ESP32 pin 12
int StatusButtonLastInterrupt = 0;

//Alerts
int alertValue = 27;
bool alertSent = false;
int minStatusMsgInterval = 5000;

void IRAM_ATTR SendStatusMessage() {  
  
  if (millis() - StatusButtonLastInterrupt < minStatusMsgInterval) return; //Prevent executing multiple times per button press or more frequent than required

  String message = "Temperature Monitor Status\n\n";
  message += "Internal temperature: " + String(DHT.temperature) + "C\n";
  message += "Internal humidity: " + String(DHT.humidity) + "%\n";
  //message += "System time: " + rtc.getDateTime(); // Causes ESP to crash and reset. Error: abort() was called at PC 0x40084cf7 on core 1
  
  //TODO: Check WiFi is connected first - will need to connect when woken from sleep

  bot.sendMessage(CHAT_ID, message, ""); // Causes ESP to crash and reset. Error: Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1).

  StatusButtonLastInterrupt = millis();
}

void SyncNTP() {
  Serial.print("Retrieving time: ");
  configTime(0, 3600, "time.google.com"); // get UTC time via NTP
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    Serial.print(".");
    delay(100);
    now = time(nullptr);
  }
  rtc.setTime(now); //Set the time on the realtime clock
  Serial.println(rtc.getDateTime());
}

void setup() {
  pinMode(ONBOARD_BUTTON_PIN, INPUT_PULLUP);
  pinMode(STATUS_BUTTON_PIN, INPUT);

  Serial.begin(115200);

  //Interrupts
  attachInterrupt(STATUS_BUTTON_PIN, SendStatusMessage, FALLING);

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.mode(WIFI_MODE_STA);
  WiFi.begin(WLAN_SSID, WLAN_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    //Serial.print(".");
    Serial.print("WiFi Status: ");
    Serial.println(WiFi.status());
  }
  Serial.println();

  Serial.println("WiFi connected");
  Serial.print("IP address: ");
  Serial.println(WiFi.localIP());

  client.setCACert(TELEGRAM_CERTIFICATE_ROOT); // Add root certificate for api.telegram.org

  SyncNTP();
}

void loop() {

  DHT.read(DHT11_PIN);
  Serial.print("temp:");
  Serial.print(DHT.temperature);
  Serial.print(" humi:");
  Serial.println(DHT.humidity);

  if (DHT.temperature >= alertValue)
  {
    if (!alertSent)
    {
      bot.sendMessage(CHAT_ID, "TEMPERATURE ALERT: Internal temperature is: " + String(DHT.temperature), "");
      alertSent = true;
    }
    
  } else {
    if (alertSent)
    {
      bot.sendMessage(CHAT_ID, "Alert Cleared: Internal temperature is: " + String(DHT.temperature), "");
      alertSent = false; //Reset the flag when temperature drops below alertValue
    }
  }

  delay(1000);
}

串口监视器输出

Connecting to ESP32Test
WiFi Status: 6
WiFi Status: 6
WiFi Status: 6
WiFi Status: 6
WiFi Status: 3

WiFi connected
IP address: 192.168.1.2
Retrieving time: ....................Sun, Feb 19 2023 22:23:38
temp:25 humi:57
temp:24 humi:53
temp:24 humi:60
temp:24 humi:60
temp:24 humi:60
temp:24 humi:60
Guru Meditation Error: Core  1 panic'ed (Interrupt wdt timeout on CPU1). 

Core  1 register dump:
PC      : 0x40090362  PS      : 0x00060f34  A0      : 0x8008f47e  A1      : 0x3ffbeb00  
A2      : 0x3ffde700  A3      : 0x3ffbd994  A4      : 0x00000004  A5      : 0xb33fffff  
A6      : 0x00000001  A7      : 0x00000001  A8      : 0x3ffbd994  A9      : 0x3ffbd994  
A10     : 0x00000019  A11     : 0x00000019  A12     : 0x3ffc3afc  A13     : 0xb33fffff  
A14     : 0x00000001  A15     : 0x00000001  SAR     : 0x0000000f  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400896b0  LEND    : 0x400896c6  LCOUNT  : 0xffffffff  
Core  1 was running in ISR context:
EPC1    : 0x400e8e33  EPC2    : 0x00000000  EPC3    : 0x00000000  EPC4    : 0x40090362


Backtrace:0x4009035f:0x3ffbeb000x4008f47b:0x3ffbeb20 0x4008de7c:0x3ffbeb40 0x40106ab7:0x3ffbeb80 0x400f408f:0x3ffbeba0 0x401071c5:0x3ffbebd0 0x40107464:0x3ffbebf0 0x400f379d:0x3ffbec40 0x400d49d2:0x3ffbec60 0x400d472d:0x3ffbeed0 0x400d483e:0x3ffbef00 0x400d6c31:0x3ffbef20 0x400d7ece:0x3ffbef80 0x400d8406:0x3ffbf000 0x4008139e:0x3ffbf070 0x400d93f5:0x3ffbf0d0 0x40084a8d:0x3ffbf0f0 0x40173c7f:0x3ffc78f0 0x400e82e9:0x3ffc7910 0x4008e417:0x3ffc7930 


Core  0 register dump:
PC      : 0x40090522  PS      : 0x00060634  A0      : 0x8008fc1b  A1      : 0x3ffb3290  
A2      : 0x3ffbf108  A3      : 0x3ffb32ac  A4      : 0x00060623  A5      : 0xb33fffff  
A6      : 0x0000cdcd  A7      : 0x0000abab  A8      : 0x0000abab  A9      : 0x0000abab  
A10     : 0x3ffde770  A11     : 0x000000d0  A12     : 0x3ffc6948  A13     : 0xb33fffff  
A14     : 0x00000001  A15     : 0x00000001  SAR     : 0x00000011  EXCCAUSE: 0x00000006  
EXCVADDR: 0x00000000  LBEG    : 0x400896b0  LEND    : 0x400896c6  LCOUNT  : 0xffffffff  



Backtrace:0x4009051f:0x3ffb32900x4008fc18:0x3ffb32d0 0x4008dd9c:0x3ffb32f0 0x401069c0:0x3ffb3330 0x40106d0e:0x3ffb3350 0x400f56bb:0x3ffb3370 0x400f5739:0x3ffb3390 0x400f812c:0x3ffb33b0 0x400f8211:0x3ffb33e0 0x40108557:0x3ffb3400 0x400f3f19:0x3ffb3420  



ELF file SHA256: 0000000000000000

Rebooting...
ets Jul 29 2019 12:21:46

rst:0xc (SW_CPU_RESET),boot:0x13 (SPI_FAST_FLASH_BOOT)
configsip: 0, SPIWP:0xee
clk_drv:0x00,q_drv:0x00,d_drv:0x00,cs0_drv:0x00,hd_drv:0x00,wp_drv:0x00
mode:DIO, clock div:1
load:0x3fff0030,len:1412
load:0x40078000,len:13400
load:0x40080400,len:3672
entry 0x400805f8


Connecting to ESP32Test

问题原因

你的推测完全正确:ESP32的中断服务函数(ISR)执行时间有严格限制,中断看门狗会监控ISR的运行时长,一旦超过阈值(通常为几毫秒)就会触发panic重启。bot.sendMessage()涉及SSL/TLS加密、网络IO等耗时操作,完全不适合在ISR中执行。

此外,ISR中还应避免以下操作:

  • 调用delay()等阻塞函数
  • 使用动态内存分配(比如String拼接,可能引发内存碎片或竞争问题)
  • 访问主程序正在操作的共享资源(比如DHT.temperature,可能导致数据不一致)

解决方法

采用中断触发标记+主程序处理的嵌入式标准模式:

  1. 定义全局布尔变量作为触发标记,标记是否需要发送状态消息
  2. 中断函数仅执行防抖检查和设置标记的极简逻辑
  3. 在loop()中定期检查标记,若标记为真则执行消息发送逻辑,随后重置标记

修改后的代码示例

#include <WiFi.h>
#include "WiFiClientSecure.h"
#include <ESP32Time.h>
#include <DFRobot_DHT11.h>
#include <UniversalTelegramBot.h>

//WiFi
#define WLAN_SSID  "ESP32Test"
#define WLAN_PASS "*********"

//WiFiFlientSecure for SSL/TLS support
WiFiClientSecure client;

//Time
ESP32Time rtc(0);  // offset in seconds; 0 = GMT, 3600 = GMT+1

//Telegram
#define TELEGRAM_TOKEN "*********:*************************"
#define CHAT_ID "**********"

UniversalTelegramBot bot(TELEGRAM_TOKEN, client);

//Temperature
DFRobot_DHT11 DHT;
#define DHT11_PIN D11

//Buttons
#define ONBOARD_BUTTON_PIN 27 //ESP32 pin 27
#define STATUS_BUTTON_PIN D10 //ESP32 pin 12
volatile int StatusButtonLastInterrupt = 0;
volatile bool sendStatusMsgFlag = false; // 中断触发标记

//Alerts
int alertValue = 27;
bool alertSent = false;
int minStatusMsgInterval = 5000;

void IRAM_ATTR StatusButtonISR() {  
  // 仅处理防抖和设置标记
  if (millis() - StatusButtonLastInterrupt < minStatusMsgInterval) return;
  sendStatusMsgFlag = true;
  StatusButtonLastInterrupt = millis();
}

void SendStatusMessage() {  
  String message = "Temperature Monitor Status\n\n";
  message += "Internal temperature: " + String(DHT.temperature) + "C\n";
  message += "Internal humidity: " + String(DHT.humidity) + "%\n";
  
  // 检查WiFi连接状态
  if(WiFi.status() == WL_CONNECTED){
    bot.sendMessage(CHAT_ID, message, "");
  }
}

void SyncNTP() {
  Serial.print("Retrieving time: ");
  configTime(0, 3600, "time.google.com"); // get UTC time via NTP
  time_t now = time(nullptr);
  while (now < 24 * 3600)
  {
    Serial.print(".");
    delay(100);
    now = time(nullptr);
  }
  rtc.setTime(now); //Set the time on the realtime clock
  Serial.println(rtc.getDateTime());
}

void setup() {
  pinMode(ONBOARD_BUTTON_PIN, INPUT_PULLUP);
  pinMode(STATUS_BUTTON_PIN, INPUT);

  Serial.begin(115200);

  //Interrupts
  attachInterrupt(STATUS_BUTTON_PIN, StatusButtonISR, FALLING);

  // Connect to WiFi access point.
  Serial.println(); Serial.println();
  Serial.print("Connecting to ");
  Serial.println(WLAN_SSID);

  WiFi.mode(WIFI_MODE_STA);
  WiFi.begin(WLAN_SSID, WLAN_PASS);

  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print("WiFi Status: ");
    Serial.println(WiFi.status());
  }
  Serial.println();

  Serial
相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 11:20:28