I have some arduino code I adapted from a simple 2 button 2 relay code I found online. I just multiplied everything so I could have 5 buttons/5relays. I am using a NodeMCU (ESP-12E) for this.

I have not changed anything, and now trying to upload it to other boards, and the same existing board I used before. Same results every time.

I have verified arduino is updated, the board manager link is up to date, and verified the code. Drivers re-installed. I have tried using different boards such as nodemcu 0.9, generic esp8266 module etc. Code is verified, no error messages upon upload.

But every single time I get this error in the serial monitor over and over:

 ets Jan  8 2013,rst cause:4, boot mode:(3,6)

wdt reset
load 0x4010f000, len 1392, room 16 
tail 0
chksum 0xd0
csum 0xd0

And here is the code I am using: (But please keep in mind this WORKS and has worked before)


int button1 = 4;
int button2 = 13;
int button3 = 12;
int button4 = 15;
int button5 = 10;

int rl1 = 5;
int rl2 = 0;
int rl3 = 14;
int rl4 = 16;
int r15 = 9;

//States for Relay and Button (1)

int state1 = HIGH;      // the current state of the output pin
int reading1;           // the current reading from the input pin
int previous1 = LOW;    // the previous reading from the input pin

//States for Relay and Button (2)

int state2 = HIGH;      // the current state of the output pin
int reading2;           // the current reading from the input pin
int previous2 = LOW;    // the previous reading from the input pin

//States for Relay and Button (3)

int state3 = HIGH;      // the current state of the output pin
int reading3;           // the current reading from the input pin
int previous3 = LOW;    // the previous reading from the input pin

//States for Relay and Button (4)

int state4 = HIGH;      // the current state of the output pin
int reading4;           // the current reading from the input pin
int previous4 = LOW;    // the previous reading from the input pin

//States for Relay and Button (5)

int state5 = HIGH;      // the current state of the output pin
int reading5;           // the current reading from the input pin
int previous5 = LOW;    // the previous reading from the input pin

// the follow variables are long's because the time, measured in miliseconds,
// will quickly become a bigger number than can be stored in an int.
long time1 = 0;          // the last time the output pin was toggled
long time2 = 0;
long time3 = 0;
long time4 = 0;
long time5 = 0;

long debounce1 = 60;   // the debounce time, increase if the output flickers
long debounce2 = 60;
long debounce3 = 60;
long debounce4 = 60;
long debounce5 = 60;

void setup()
  pinMode(button1, INPUT);
  pinMode(button2, INPUT);
  pinMode(button3, INPUT);
  pinMode(button4, INPUT);
  pinMode(button5, INPUT);

  pinMode(rl1, OUTPUT);
  pinMode(rl2, OUTPUT);
  pinMode(rl3, OUTPUT);
  pinMode(rl4, OUTPUT);
  pinMode(r15, OUTPUT);


void loop() {

  reading1 = digitalRead(button1);
  reading2 = digitalRead(button2);
  reading3 = digitalRead(button3);
  reading4 = digitalRead(button4);
  reading5 = digitalRead(button5);

  // if the input just went from LOW and HIGH and we've waited long enough
  // to ignore any noise on the circuit, toggle the output pin and remember
  // the time
  //Condition Relay 1
  if (reading1 == HIGH && previous1 == LOW && millis() - time1 > debounce1) {
    if (state1 == HIGH)
      state1 = LOW;
      state1 = HIGH;

    time1 = millis();   

  //Condition Relay 2
    if (reading2 == HIGH && previous2 == LOW && millis() - time2 > debounce2) {
    if (state2 == HIGH)
      state2 = LOW;
      state2 = HIGH;

    time2 = millis();   

  //Condition Relay 3
    if (reading3 == HIGH && previous3 == LOW && millis() - time3 > debounce3) {
    if (state3 == HIGH)
      state3 = LOW;
      state3 = HIGH;

    time3 = millis();   

  //Condition Relay 4
    if (reading4 == HIGH && previous4 == LOW && millis() - time4 > debounce4) {
    if (state4 == HIGH)
      state4 = LOW;
      state4 = HIGH;

    time4 = millis();   

  //Condition Relay 5
    if (reading5 == HIGH && previous5 == LOW && millis() - time5 > debounce5) {
    if (state5 == HIGH)
      state5 = LOW;
      state5 = HIGH;

    time5 = millis();   

  digitalWrite(rl1, state1);
  digitalWrite(rl2, state2);
  digitalWrite(rl3, state3);
  digitalWrite(rl4, state4);
  digitalWrite(r15, state5);

  previous1 = reading1;
  previous2 = reading2;
  previous3 = reading3;
  previous4 = reading4;
  previous5 = reading5;

If I google this error I get a myriad of results that so far have not helped me. Any help or insight on how I can better understand this error, where to start, and what I need to do to get this "simple" sketch working would be awesome. I'm at my wits end and all I want is a simple lighting panel to work.

  • that looks like a status message, not an error message
    – jsotola
    Commented Mar 5, 2020 at 4:34
  • But with this, it reboots over and over and shows the message each time. Commented Mar 5, 2020 at 4:35
  • that does not mean that it is an error message .... it may be boot status messages ... looks like the chip is in a wrong state ... could be something wrong with your breadboard, if you are using one ... or the watchdog timer is set incorrectly
    – jsotola
    Commented Mar 5, 2020 at 4:44
  • I think it is a brown out
    – Juraj
    Commented Mar 5, 2020 at 5:08
  • Did it ever work with 5 relays?
    – orithena
    Commented Mar 5, 2020 at 10:11

3 Answers 3


First thing to realize for you is that the externally set status of three of the GPIO pins determine the boot mode for the ESP8266 used on your NodeMCU. So you must take care to check that your external wiring will not interfere with the boot mode:

  • GPIO15/D8 must be LOW on boot (i.e. no external pull-up resistors may be connected between D8 and 3.3V)
  • GPIO2/D4 must be HIGH on boot (i.e. no external pull-down resistors may be connected between D4 and GND)
  • GPIO0/D3 must be free of pull-up/down resistors so that the USB-to-serial chip can switch between RUN and FLASH mode.

Also, holding GPIO16/D0 LOW for an extended amount of time while running may have unintended side effects like triggering the watchdog, especially if the board manufacturer decided to add the deep sleep wakeup resistor between D0 and RST (you most certainly have a NodeMCU clone, so this might actually be possible).

So it might very well be that you need to reverse the button logic on GPIO15/D8 (i.e. connect the button between D8 and 3.3V). It also might be that the pin numbering on your NodeMCU is confusing; better use the D0-D10 constants.

Depending on the type of your relays, your relays may act as a pull-up/down resistor, too, further adding to the confusion.

I'd try this sketch without anything connected (no buttons, no relays) and when it works, I'd add buttons and relays one by one until you find the culprit. Sometimes it might be sufficient to swap a relay and a button, sometimes you need to reverse the logic on a button.

I would say that using any ESP8266 with that many input/output lines requires very careful consideration on where to connect what. The GPIO pins on an Arduino Nano are not involved in boot mode nor watchdog, so at least there you'd not get any interference.

  • Hello, thank you for the detailed response. I do not have anything attached to the nodemcu so that unfortunately rules out any of the gpio issues. What I don't get is how this exact code is on another nodemcu with no issues, but I've uploaded it to 3+ other boards and gotten this constant crash/boot cycle now. Commented Mar 7, 2020 at 3:28

According to Esp8266 documentation this is a software reset. After a fast peek, I didn't find delay() or yield() in your code. The esp8266 needs to attend some time to WiFi related background tasks, and it is does when your arduino code delays or yields the processor.

  • i was going to suggest adding a sleep(1). great minds think alike...
    – dandavis
    Commented Mar 5, 2020 at 20:01
  • 2
    AFAIK a yield() is implicit in every repetition of loop()
    – StarCat
    Commented Mar 6, 2020 at 14:23
  • Why would this work on another nodemcu without that, though? And where would I put the delay() part of the code? Commented Mar 7, 2020 at 3:29

For anyone that has a similar issue, I figured it out. GPIO 9 could not be used for a relay/output for whatever reason. Wish I knew why. Switched it to GPIO2 (D4) and the reboots stopped.

  • Pins 6-11 on most NodeMCUs are used for connecting the on-board SPI Flash memory and are not recommended for use as general I/O pins.
    – StarCat
    Commented Mar 7, 2020 at 7:12
  • @starcat I understand that but I just find it strange pin 9 worked in the past, nothing changed, then now it magically doesn't. Commented Mar 7, 2020 at 18:20
  • 1
    @Coltography Found the culprit. GPIO9 and GPIO10 are not usable on boards that use Quad-IO Flash SPI access (which needs 4 data lines instead of 2 on Dual-IO Flash). It seems that some NodeMCU boards do use DIO, some other use QIO -- and on those QIO boards, messing with the Flash SPI pins seem to trigger the watchdog, which then reboots the chip. Here's the schematics with commentary on GPIO9: esp8266.com/wiki/lib/exe/fetch.php?media=schematic_esp-12e.png -- and here's the issue in the Arduino ESP8266 core: github.com/esp8266/Arduino/issues/1446
    – orithena
    Commented Mar 9, 2020 at 9:30

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.