Search code examples
mqttsensorsesp8266resetwatchdog

Soft wdt reset on ESP8266 when using Speed Sensor


I'm on my personal project to create a esp8266 module that can read several sensor from a vehicle and it can sends data over mqtt. so I have written the code where I try to reading the speed sensor its getting wdt reset and the esp8266 resetting again

so heres my code

void setup() {
  //Initialize serial and wait for port to open:
  Serial.begin(9600);
  while (!Serial) {
    ; // wait for serial port to connect. Needed for native USB port only
  }

  lcd.init();
  lcd.backlight();
  pinMode(speedSensor,INPUT_PULLUP);

  // attempt to connect to WiFi network:
  Serial.print("Attempting to connect to WPA SSID: ");
  Serial.println(ssid);
  
  while (WiFi.begin(ssid, pass) != WL_CONNECTED) {
    lcd.setCursor(0,0);
    lcd.print("Connecting to");
    lcd.setCursor(0,1);
    lcd.print("the network");
    Serial.print(".");
    delay(5000);
  }
  lcd.clear();

  Serial.println("You're connected to the network");
  Serial.println();

  lcd.setCursor(0,0);
  lcd.print("Connected to");
  lcd.setCursor(0,1);
  lcd.print("the network");
  delay(2000);
  lcd.clear();

  // attempt to connect to the MQTT broker:
  Serial.print("Attempting to connect to the MQTT broker: ");
  Serial.println(broker);

  if (!mqttClient.connect(broker, port)) {
    Serial.print("MQTT connection failed! Error code = ");
    Serial.println(mqttClient.connectError());

    while (1);
  }

  Serial.println("You're connected to the MQTT broker!");
  Serial.println();

  // subscribe to the topic and set callback function
  mqttClient.onMessage(SwitchMotor);
  mqttClient.subscribe(topicSwitchMotor);

  lcd.setCursor(0,0);
  lcd.print("Connected to");
  lcd.setCursor(0,1);
  lcd.print("the MQTT broker");
  delay(2000);
  lcd.clear();
  
  lcd.setCursor(0,0);
  lcd.print(" Fuel :");
  lcd.setCursor(0,1);
  lcd.print(" RPM  :");

  SPI.begin();
  rfid.PCD_Init();
  Serial.println("I am waiting for card...");
  pinMode(pinRelay, OUTPUT);
  digitalWrite(pinRelay, HIGH);
}

void loop() {

  mqttClient.poll(); // check for incoming messages

  FuelSensor(); // Fuel Sensor
  SpeedMotor(); // Speed Sensor
  StartMotor(); // Start Motor with RFID
}

void SpeedMotor(){
  start_time=millis();
  end_time=start_time+1000;
  
  while(millis()<end_time){
    yield();
      if(digitalRead(speedSensor)){
          steps=steps+1; 
          while(digitalRead(speedSensor));
      }
  }

  // calculate the speed
  temp=steps-steps_old;
  steps_old=steps;
  rps=(temp/20);
  rpm=(rps*60);
  lcd.setCursor(9,1);
  lcd.print(rpm);
  lcd.print("   ");

  // publish the message
  mqttClient.beginMessage(topicSpeedRpm);
  mqttClient.print(rpm);
  mqttClient.endMessage();

  mqttClient.beginMessage(topicSpeedRps);
  mqttClient.print(rps);
  mqttClient.endMessage();
}

and this is the output from serial monitor

Attempting to connect to WPA SSID: cieciecie
...You're connected to the network

Attempting to connect to the MQTT broker: xx.xxx.xxx.xx
You're connected to the MQTT broker!

I am waiting for card...

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

>>>stack>>>

ctx: cont
sp: 3ffffde0 end: 3fffffc0 offset: 01a0
3fffff80:  3fffdad0 3ffee7bc 3ffee7c0 40201143  
3fffff90:  3fffdad0 00000000 3ffeeaa8 402016e9  
3fffffa0:  3fffdad0 00000000 3ffeeaa8 40205d5c  
3fffffb0:  feefeffe feefeffe 3ffe8600 40100e61  
<<<stack<<<

--------------- CUT HERE FOR EXCEPTION DECODER ---------------
⸮⸮Attempting to connect to WPA SSID: cieciecie
...You're connected to the network

Attempting to connect to the MQTT broker: xx.xxx.xxx.xx
You're connected to the MQTT broker!

I am waiting for card...

--------------- CUT HERE FOR EXCEPTION DECODER ---------------

Soft WDT reset

it'll soft wdt reset all over again and again

I'd already try Stack ESP execption decoder and it given this results ESP Exception decoder results

at the results its mentioning line 152 at speedMotor() function

void SpeedMotor(){
  start_time=millis();
  end_time=start_time+1000;
  
  while(millis()<end_time){
    yield(); // already use yield(); on while() loop
      if(digitalRead(speedSensor)){ // line 152
          steps=steps+1; 
          while(digitalRead(speedSensor));
      }
  }

  // calculate the speed
  temp=steps-steps_old;
  steps_old=steps;
  rps=(temp/20);
  rpm=(rps*60);
  lcd.setCursor(9,1);
  lcd.print(rpm);
  lcd.print("   ");

  // publish the message
  mqttClient.beginMessage(topicSpeedRpm);
  mqttClient.print(rpm);
  mqttClient.endMessage();

  mqttClient.beginMessage(topicSpeedRps);
  mqttClient.print(rps);
  mqttClient.endMessage();
}

and i already try too from arduino forum https://forum.arduino.cc/t/solved-esp8266-millis-crash/636543 it says try using yield(); in the while() loop but its still given the soft wdt rest

i would like to have clear answer how to use the yield(); function properly so theres no more soft wdt resetting again


Solution

  • As per the comments the issue was in this section of code:

     while(millis()<end_time){
        yield(); // already use yield(); on while() loop
          if(digitalRead(speedSensor)){ // line 152
              steps=steps+1; 
              while(digitalRead(speedSensor));
          }
      }
    

    The problem is that if digitalRead(speedSensor) returns true then a loop runs until digitalRead(speedSensor) returns false; this may run long enough to trigger the watchdog.

    while(digitalRead(speedSensor));
    

    One way of fixing this is to yield within the loop i.e.:

    while(digitalRead(speedSensor)) {
         yield(); 
    }