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

NodeMCU ESP8266 Alexa控制GPIO无响应且触发Soft WDT Reset问题

问题背景

这段代码用于通过Alexa控制继电器,进而操控医疗椅的从属遥控器,基于ESP8266的Alexa控制示例开发,已安装Arduino IDE的ESP8266插件。

问题现象

代码可正常编译、连接WiFi,也能响应Alexa指令"recline on"(串口输出附后),但GPIO05(或其他引脚)状态无变化;接收指令2秒后触发Soft WDT Reset,设备断开网络。需求是让GPIO05保持高电平11秒,使椅子回到指定位置。

已尝试操作
  • 更换过不同GPIO引脚测试
  • 在3块同型号ESP8266板上测试,结果一致
  • 目前未连接继电器,仅做调试,后续继电器将使用独立电源
代码
#include <Arduino.h>

#include <ESP8266WiFi.h>
// #define RF_RECEIVER 5

// Assign relay inputs from ESP8266 board GPIO's
#define RELAY_PIN_1 5 //GPIO05 labeled D1 on NodeMCU 1.0 ESP-12E board

#include "fauxmoESP.h"

#define SERIAL_BAUDRATE 9600

#define ssid "************"
#define password "************"

WiFiClient client;

// Assign Alexa 'commands' to ESP8266 board GPIO's
#define RECLINE "recline"

fauxmoESP fauxmo;

/*
* Connect controller to WiFi
*/
void connectToWiFi() {
//Connect to WiFi Network
   Serial.println();
   Serial.println();
   Serial.print("Connecting to WiFi");
   Serial.println("...");
   WiFi.begin(ssid, password);
   int retries = 0;
while ((WiFi.status() != WL_CONNECTED) && (retries < 15)) {
   retries++;
   delay(500);
   Serial.print(".");
}
if (retries > 14) {
    Serial.println(F("WiFi connection FAILED"));
}
if (WiFi.status() == WL_CONNECTED) {
    Serial.println(F("WiFi connected!"));
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
}
    Serial.println(F("Setup ready"));
}

void setup() {
  // Init serial port and clean garbage
  Serial.begin(SERIAL_BAUDRATE);
  Serial.println();

  // Wi-Fi connection
  connectToWiFi();

  //pinMode(RELAY_PIN_1, OUTPUT); 

  digitalWrite(RELAY_PIN_1, HIGH);   //Set remote commands to LOW ("OFF") position for safety

  // By default, fauxmoESP creates it's own webserver on the defined port
  // The TCP port must be 80 for gen3 devices (default is 1901)
  // This has to be done before the call to enable()
  fauxmo.createServer(true); // not needed, this is the default value
  fauxmo.setPort(80); // This is required for gen3 devices

  // You have to call enable(true) once you have a WiFi connection
  // You can enable or disable the library at any moment
  // Disabling it will prevent the devices from being discovered and switched
  fauxmo.enable(true);
  // You can use different ways to invoke alexa to modify the devices state:
  // "Alexa, turn lamp two on"

  // Add virtual devices
  fauxmo.addDevice(RECLINE);

  fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
    // Callback when a command from Alexa is received. 
    // You can use device_id or device_name to choose the element to perform an action onto (relay, LED,...)
    // State is a boolean (ON/OFF) and value a number from 0 to 255 (if you say "set kitchen light to 50%" you will receive a 128 here).
    // Just remember not to delay too much here, this is a callback, exit as soon as possible.
    // If you have to do something more involved here set a flag and process it in your main loop.
        
    Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
    
    if ( (strcmp(device_name, RECLINE) == 0) ) {     // this just sets a variable that the main loop() does something about
      Serial.println("RELAY 1 switched by Alexa");
      digitalWrite(RELAY_PIN_1, HIGH);
      delay(11000);                                  // turn on for 11 seconds
      Serial.println("RELAY_PIN_1, LOW");
      }

  });
}

void loop() {
  fauxmo.handle();
}
串口输出
Serial Monitor Output:

22:03:59.655 -> Connecting to WiFi...
22:04:00.255 -> ...........WiFi connected!
22:04:06.003 -> IP address: 
22:04:06.003 -> 192.168.1.208
22:04:06.003 -> Setup ready
22:13:37.602 -> [MAIN] Device #0 (recline) state: ON value: 255
22:13:37.686 -> RELAY 1 switched by Alexa
22:13:40.469 -> 
22:13:40.469 -> --------------- CUT HERE FOR EXCEPTION DECODER ---------------
22:13:40.532 -> 
22:13:40.532 -> Soft WDT reset
22:13:40.532 -> 
22:13:40.564 -> Exception (4):
22:13:40.564 -> epc1=0x40105d12 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000000 depc=0x00000000
22:13:40.661 -> 
22:13:40.661 -> >>>stack>>>
22:13:40.661 -> 
22:13:40.661 -> ctx: sys
22:13:40.693 -> sp: 3fffeaf0 end: 3fffffb0 offset: 0160
22:13:40.725 -> 3fffec50:  00000000 0008dd1d 40205ecc 00001fcd  
22:13:40.789 -> 3fffec60:  3ffee8e4 0008dd1d 00002af8 00002af8  
REPEATS MANY MANY TIMES....
解决方案

问题根源

  1. 引脚无反应:代码中pinMode(RELAY_PIN_1, OUTPUT);被注释,GPIO5未配置为输出模式,导致digitalWrite无法改变引脚状态。
  2. Soft WDT Reset:在fauxmoESP的回调函数中直接调用delay(11000),阻塞了ESP8266的系统任务(包括WiFi心跳、看门狗喂狗),触发看门狗超时复位。回调函数要求快速执行,不能做长时间阻塞操作。

修复代码

#include <Arduino.h>
#include <ESP8266WiFi.h>
#include "fauxmoESP.h"

#define RELAY_PIN_1 5 // GPIO05对应NodeMCU 1.0的D1引脚
#define SERIAL_BAUDRATE 9600
#define ssid "************"
#define password "************"
#define RECLINE "recline"

fauxmoESP fauxmo;
bool triggerRecline = false;
unsigned long reclineStartTime = 0;
const unsigned long RECLINE_DURATION = 11000; // 11秒

void connectToWiFi() {
  Serial.println();
  Serial.println();
  Serial.print("Connecting to WiFi...");
  WiFi.begin(ssid, password);
  int retries = 0;
  while ((WiFi.status() != WL_CONNECTED) && (retries < 15)) {
    retries++;
    delay(500);
    Serial.print(".");
  }
  if (retries > 14) {
    Serial.println(F("WiFi connection FAILED"));
  }
  if (WiFi.status() == WL_CONNECTED) {
    Serial.println(F("WiFi connected!"));
    Serial.println("IP address: ");
    Serial.println(WiFi.localIP());
  }
  Serial.println(F("Setup ready"));
}

void setup() {
  Serial.begin(SERIAL_BAUDRATE);
  Serial.println();

  connectToWiFi();

  // 配置引脚为输出模式
  pinMode(RELAY_PIN_1, OUTPUT);
  digitalWrite(RELAY_PIN_1, LOW); // 初始设为低电平(安全状态)

  fauxmo.setPort(80);
  fauxmo.enable(true);
  fauxmo.addDevice(RECLINE);

  fauxmo.onSetState([](unsigned char device_id, const char * device_name, bool state, unsigned char value) {
    Serial.printf("[MAIN] Device #%d (%s) state: %s value: %d\n", device_id, device_name, state ? "ON" : "OFF", value);
    
    if (strcmp(device_name, RECLINE) == 0 && state) {
      Serial.println("RELAY 1 triggered by Alexa");
      triggerRecline = true; // 设置标志位,由主循环处理延时逻辑
    }
  });
}

void loop() {
  fauxmo.handle();

  // 主循环中处理延时逻辑,避免阻塞回调函数
  if (triggerRecline) {
    if (reclineStartTime == 0) {
      reclineStartTime = millis();
      digitalWrite(RELAY_PIN_1, HIGH); // 引脚设为高电平
      Serial.println("RELAY_PIN_1 set to HIGH");
    } else if (millis() - reclineStartTime >= RECLINE_DURATION) {
      digitalWrite(RELAY_PIN_1, LOW); // 时间到,引脚设为低电平
      Serial.println("RELAY_PIN_1 set to LOW");
      triggerRecline = false;
      reclineStartTime = 0;
    }
  }
}

修复说明

  1. 引脚模式修复:取消pinMode(RELAY_PIN_1, OUTPUT);的注释,确保GPIO5被配置为输出模式,让digitalWrite生效。
  2. 避免阻塞回调:用标志位triggerRecline和时间戳reclineStartTime替代回调中的delay,将延时逻辑放到loop()中处理,保证fauxmo.handle()能持续执行,维持WiFi连接并喂看门狗。
  3. 初始状态优化:将初始引脚状态设为低电平,符合安全逻辑,避免上电误触发。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.18 05:05:55