ESP8266 Module with RFID scanner rebooting and Soft WDT reset error

Hi all,

Have been working on configuring an RFID scanner (MFRC522) with the WEMOS board, which includes an esp8266.

I am getting the error message:

Soft WDT reset
>>>stack>>> ctx: cont
 sp: 3ffffba0 end: 3fffffc0 offset: 01b0 3ffffd50:  00000008 3ffef7cc 3ffef8f0 4020585c 3ffffd60:
  00000080 3ffe0001 0000001a 402058cc 3ffffd70:  3ffffe00 3ffffe42 3ffef7cc 40205bac 3ffffd80:
  00000020 3ffef7cc 3ffef8f0 402064db 3ffffd90:  0000000c 00000030 00000000 00000000 3ffffda0:  
0000034c 00000007 00000001 40205783 3ffffdb0:  0000001c 3ffe0001 3ffef8f0 40201cac 3ffffdc0: 
 3ffef7cc 3ffffe40 3ffffe42 40205cda 3ffffdd0:  3ffffe42 3ffffe00 00000000 00000000 3ffffde0: 
 3ffef7cc 3ffffe40 3ffffe42 40206028 3ffffdf0:  00000000 00000000 0000000f 4010057d 3ffffe00: 
 00000007 3ffef7cc 3ffef8f0 40205783 3ffffe10:  00000026 00000001 00000000 00000430 3ffffe20: 
 00000000 00000001 3ffef7cc 4020605c 3ffffe30:  00000000 00000001 3ffef7cc 40206098 3ffffe40: 
 00025c68 ffffffff 3fff266c 00000001 3ffffe50:  3ffef890 3ffef804 3ffef7cc 4020351b 3ffffe60: 
 3fff1024 3ffef804 402010e0 00000001 3ffffe70:  3ffef890 3ffef804 3fffff18 40206bd5 3ffffe80:
  3ffef890 3ffef804 3ffef7e0 40206bf4 3ffffe90:  00000005 3ffef804 3ffef7e0 40203041 3ffffea0: 
 74736f00 00000005 3ffffef0 00000005 3ffffeb0:  3ffffef0 3fff261c 00000000 40201cac 3ffffec0: 
 00000001 00000001 3fff25f4 40209696 3ffffed0:  00000001 4020107c 3fff25f4 401000e1 3ffffee0: 
 3fff25f4 3ffef820 3fff25f4 40201ce2 3ffffef0:  69667200 00000064 80000001 80fe84f0 3fffff00:  
3fff25f4 3ffef820 3ffef7e0 402033de 3fffff10:  6966722f 80000064 85ff3200 0000008f 3fffff20:  
80002064 70c62775 40100500 00005c62 3fffff30:  00000001 3ffef820 00000001 40100170 3fffff40:  
00000001 00000000 3ffef7e0 3ffef98c 3fffff50:  00000001 3ffef804 3ffef7e0 3ffef98c 3fffff60:  
00000001 3ffef804 3ffef7e0 4020385b 3fffff70:  00000000 00000000 00001388 feefeffe 3fffff80:  
00000000 00000000 00000001 40100170 3fffff90:  3fffdad0 00000000 3ffef94c 402038fc 3fffffa0:  
3fffdad0 00000000 3ffef94c 40207ce4 3fffffb0:  feefeffe feefeffe 3ffe84f0 40100f35 <<<stack<<< 

ets Jan  8 2013,rst cause:2, boot mode:(3,7) load 0x4010f000, len 1392, room 16 tail 0 chksum 0xd0 csum 0xd0 v3d128e5c ~ld 
//Then it reboots

I have no idea where all those hex values come from.
Here is my code: (look at rfid function)

/*
My first ESP8266 Module script
Connect to 192.168.4.1 when connected to esp wifi
Manages the builtin LED and connected Servo (D4/D6 on ext-shield) and RFID Scanner
*/
#include <ESP8266WiFi.h>
#include <ESP8266WebServer.h>
#include <Servo.h>
#include <MFRC522.h>

#define SS_PIN 15
#define RST_PIN 0

//Create instances?
Servo myservo;
ESP8266WebServer server(80);
MFRC522 mfrc522(SS_PIN, RST_PIN);

//SSID & Password
const char* ssid = "Toilet Paper";
const char* password = "connecttoesp";


//HTML and CSS
const String htmlMain = "myhtmlcode";
const String htmlLED = "morehtml";
const String htmlServo = "morehtml";
const String stylesCSS = "css";
//Set some variables
bool terminate = false;


//Send Functions
void sendCSS(){
  server.send(200,"text/css",stylesCSS);
}
void sendMain() {
  server.send(200, "text/html", htmlMain);
}
void sendLED() {
  String state = server.arg("state");
  
  server.send(200,"text/html", htmlLED);   
  if (state == "on"){
    digitalWrite(LED_BUILTIN, LOW); //Low = On
  }
  else if (state == "off"){
    digitalWrite(LED_BUILTIN, HIGH); //High = Off
  }
}
void sendServo() {
  //Need to implement some js to keep track of current val of slider, so does not reset every time. 
  String inputvalue = server.arg("value");
  server.send(200,"text/html",htmlServo);
  //If the value is specified, write pos given that 0 <= pos <= 180
  if (inputvalue != ""){
    int servopos = inputvalue.toInt();
    if (servopos >= 0 && servopos <=180){
      myservo.write(servopos);
    }
  }
  
}
void sendRFID(){   //Here is my RFID function **************************************************************************************
  while (!terminate){
    // Look for new cards
    if (! mfrc522.PICC_IsNewCardPresent()) 
    {
      continue;
    }
    // Select one of the cards
    if (! mfrc522.PICC_ReadCardSerial()) 
    {
      continue;
    }
    Serial.print("UID tag :");
    byte letter;
    for (byte i = 0; i < mfrc522.uid.size; i++) 
    {
      Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
      Serial.print(mfrc522.uid.uidByte[i], HEX);
    }
    delay(2000);
  }
  server.send(200,"text/plain","RFID page");
}


void setup() {
  delay(2000);
  //Serial
  Serial.begin(115200);
  Serial.println("Setting up Access Point");

  //Servo
  pinMode(3,OUTPUT);
  myservo.attach(2); //Attaches to GPIO2 (this actually is D4, by luck)

  //RFID
  SPI.begin();      
  mfrc522.PCD_Init();

  //Wifi SoftAP
  WiFi.softAP(ssid, password);
  delay(5000);
  Serial.print("Soft Ap IP is = ");
  Serial.println(WiFi.softAPIP());

  //Setup sites for server
  server.on("/styles.css",sendCSS);
  server.on("/", sendMain);
  server.on("/led",sendLED);
  server.on("/servo",sendServo);
  server.on("/rfid",sendRFID);

  //Start Server
  server.begin();
  Serial.println("Server successfully started.");

  //LED
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, HIGH);
}
//Handle Server requests
void loop() {
  server.handleClient();
}

I have run similar code which does not include any esp8266, and this works perfectly fine.

/*
Servo is attached at D6
From left to right:

SDA    SCK    MOSI    MISO    IRQ    GND    RST    3.3V

D10    D13    D11     D12     NONE   GND    D9     3.3V  
Note: GND is next to D13 and D12 Section
Note: 3.3V is in POWER section (pink)
 */

//RFID LOCK :)   comments are pins for just arduino+shield, current is for WEMOS with shield.
#include <SPI.h>
#include <MFRC522.h>
#include <Servo.h>
 
#define SS_PIN 15//10
#define RST_PIN 0//9

MFRC522 mfrc522(SS_PIN, RST_PIN);   // Create MFRC522 instance.
Servo myservo; //define servo name

void setup() 
{
  Serial.begin(115200);   // Initiate a serial communication (9600)
  //RFID Stuff
  SPI.begin();      
  mfrc522.PCD_Init();   // Initiate MFRC522
  Serial.println("Put your card to the reader...");
  Serial.println();
  //Servo Stuff
  myservo.attach(2); //Set pin (6)
  myservo.write(180);

}
void loop() 
{
  // Look for new cards
  if ( ! mfrc522.PICC_IsNewCardPresent()) 
  {
    return;
  }
  // Select one of the cards
  if ( ! mfrc522.PICC_ReadCardSerial()) 
  {
    return;
  }
  //Show UID on serial monitor
  Serial.print("UID tag :");
  String content= "";
  byte letter;
  for (byte i = 0; i < mfrc522.uid.size; i++) 
  {
     Serial.print(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " ");
     Serial.print(mfrc522.uid.uidByte[i], HEX);
     content.concat(String(mfrc522.uid.uidByte[i] < 0x10 ? " 0" : " "));
     content.concat(String(mfrc522.uid.uidByte[i], HEX));
  }
  Serial.println();
  Serial.print("Message : ");
  content.toUpperCase();
  if (content.substring(1) == "76 39 EC 25") //change here the UID of the card/cards that you want to give access
  {
    correctCardEntered();   //Correct Card 
  }
 
 else   {
    incorrectCardEntered();  //Incorrect Card  
  }
} 

void correctCardEntered(){
  Serial.println("Authorized access");
  Serial.println();
  myservo.write(90);
  delay(5000);
  myservo.write(180);
}
void incorrectCardEntered(){
  //Do something
  Serial.println("Access Declined");
  Serial.println();
  delay(500);
}

Thanks in advance!

Sorry missed first line of error message:
Soft WDT reset

Try to move the servo to a different pin, GPIO2 is used to set boot mode. If the servo is powered from the board, try to power it from a power supply instead.

Sorry, my bad I made it unclear, the second code works perfectly fine on the wemos.

Also, I have just miraculously found this other post with the same error msg:

I will try and put in yield(); .

You could also change the timeout of the watchdog.

Thanks Danois,

I've decided to ditch the while statement, and just have a button that can reload the page to check if a new card is present. The yield statement did work though.

The yield statement did work though.

where did you put it ? if you would have put on the first line of the section that would be executed in the while-loop it should do the trick.

 while (!terminate){
    yield();
    // Look for new cards

Basically if code gets looped and the WDT doesn't get reset at least every 2.5secs a wdt reset is executed. the wdt will be reset when either a yield() is executed, at the end of loop() (a yield() is executed) or when delay() is executed (also then a yield() is executed, not with delayMicroSeconds() though)

You could also change the timeout of the watchdog

You could do but if you want to make use of the wifi capabilities it is wise to execute scheduled tasks on a regular basis (actually the 2.5secs is quite long for a stable connection already)