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

ESP8266搭配3144霍尔传感器测转速时中断功能异常求助

ESP8266搭配3144霍尔传感器测速故障排查与修复

问题描述

  • 初始代码中执行attachInterrupt(digitalPinToInterrupt(D1), exti_callback, FALLING)时触发系统错误,更换D2引脚后问题依旧,注释该行代码设备可正常运行。尝试更换波特率、上传速率、USB线缆和串口端口均无效,报错信息如下:
load 0x4010f000, len 3424, room 16
tail 0
chksum 0x2e
load 0x3fff20b8, len 40, room 8 
tail 0
chksum 0x2b
csum 0x2b
v00041f10
~ld
⸮⸮⸮⸮o쒜p⸮⸮n|⸮l⸮⸮$`b⸮⸮|r⸮$⸮o⸮⸮o⸮
ets Jan  8 2013,rst cause:2, boot mode:(3,6)
  • 修改代码改用D5引脚后,设备能正常输出初始值0,但用磁铁触发霍尔传感器中断时,串口出现乱码错误,修改后的代码如下:
int flag = 0;
void ICACHE_RAM_ATTR hallInterrupt();
void setup() {
Serial.begin(115200);
pinMode(D5, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(D5), hallInterrupt, FALLING);
}

void loop() {
Serial.println(flag);
delay(500);

}
void hallInterrupt()
{
flag = 1;
delay(500);
}

故障原因分析

  1. 中断服务函数(ISR)非法调用阻塞函数:ESP8266的中断服务函数必须保持极简,不能调用delay()这类依赖系统定时器的阻塞函数。delay()会在ISR中阻塞系统运行,触发看门狗复位,导致设备重启并输出乱码。
  2. 变量未加volatile修饰:flag变量在中断中被修改,主循环读取时可能因编译器优化无法获取最新值,导致逻辑异常。

修复方案与代码

针对上述问题,做以下修改:

  • 用volatile修饰flag变量,确保主循环能正确读取中断修改的值;
  • 移除ISR中的delay(),将防抖逻辑移至主循环处理;
  • 中断服务函数仅执行设置标志位的最小操作,避免阻塞系统。

修复后的代码:

volatile int flag = 0;
unsigned long lastTriggerTime = 0;
const unsigned long debounceDelay = 500; // 防抖延时

void ICACHE_RAM_ATTR hallInterrupt();

void setup() {
  Serial.begin(115200);
  pinMode(D5, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(D5), hallInterrupt, FALLING);
}

void loop() {
  // 处理防抖和标志位重置
  if (flag == 1) {
    Serial.println(flag);
    // 等待防抖时间后重置标志位
    if (millis() - lastTriggerTime >= debounceDelay) {
      flag = 0;
    }
  } else {
    Serial.println(flag);
  }
  delay(500);
}

void hallInterrupt() {
  // 仅设置标志位和记录触发时间,不做阻塞操作
  flag = 1;
  lastTriggerTime = millis();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.03 20:45:22