So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By Gokhan E
#87762 Hi i have a code like this. I am sending step values via mqtt to control my blinds
If i dont use disable watchdog then i get crash around step no 100 and if i use watchdog i get error around step no 1300.
How can i solve it?


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

wdt reset
load 0x4010f000, len 3456, room 16
tail 0
chksum 0x84
csum 0x84
va5432625
~ld


Code: Select all#include <ESP8266WiFi.h>
#include <PubSubClient.h>
#include <AccelStepper.h>

#define Motor1_Dir 5
#define Motor1_Step 4

const char* ssid = "xxx";
const char* password = "xxx";
const char* mqtt_server = "xxx";
const char* mqttUser = "xxx";
const char* mqttPassword = "xxx";

int value;
bool flag1;

AccelStepper stepper(1, Motor1_Step, Motor1_Dir);

WiFiClient espClient;
PubSubClient client(espClient);


void setup_wifi()
{
  delay(10);
  Serial.println();
  Serial.print("Connecting to ");
  Serial.println(ssid);

  WiFi.mode(WIFI_STA);
  WiFi.begin(ssid, password);

  while (WiFi.status() != WL_CONNECTED)
  {
    delay(500);
    Serial.print(".");
  }
  randomSeed(micros());
  Serial.println("");
  Serial.println("WiFi connected");
  Serial.println("IP address: ");
  Serial.println(WiFi.localIP());
}


void callback(char* topic, byte* payload, unsigned int length)
{
  Serial.print("Message arrived [");
  Serial.print(topic);
  Serial.print("] ");

value = 0;
  int tensValue = 1;
  for (int i = length - 1; i >=0; i--) // iterate backwards
  {
    value += (payload[i] - '0') * tensValue ;
    tensValue = tensValue * 10;
  }
  flag1 = true;



 
//  for (int i = 0; i < length; i++)
//  {
//   Serial.print((char)payload[i]);
 // value = (char)payload [length -1];
 //   flag1 = true;
//  }
//  Serial.println();
//  Serial.print("Mesaj Geldi");
}


void reconnect()
{
  while (!client.connected())
  {
    Serial.print("Attempting MQTT connection...");
   
    if (client.connect("alkan"))
    {
      Serial.println("connected");
      client.subscribe("Alkan/perde");
    }
    else
    {
      Serial.print("failed, rc=");
      Serial.print(client.state());
      Serial.println(" try again in 3 seconds");
      delay(3000);
    }
  }
}


void setup()
{
  Serial.begin(115200);
 
  setup_wifi();
 
  client.setServer(mqtt_server, 1883);
  client.setCallback(callback);

  stepper.setMaxSpeed(200);
  stepper.setAcceleration(100); 
//  stepper.setSpeed(200);   
}



void loop()
{
  if (!client.connected())
  {
    reconnect();
  }
  client.loop();
  {

     if( flag1 ==  true )
        {
//        stepper.enableOutputs();
//        Serial.println("1");
//        ESP.wdtFeed();
//        yield();
        ESP.wdtDisable();
        stepper.moveTo(value);
        stepper.runToPosition();
//        yield();
//        ESP.wdtFeed();                       
//        Serial.println("2");
        Serial.println();
        Serial.println("Stop at:");
        delay(100);
        Serial.print(value);
        Serial.println();
        flag1 = false;
//        stepper.disableOutputs();
//        Serial.println("3");
        ESP.wdtEnable(1000);
        }
  }
}
User avatar
By pangolin
#87804 The watchdog's main purpose is to to tell you when there are errors in your code, so turning it off is a surefire way to hide the problem. The ESP8266 has two watchdog timers: software and hardware. You can delay the firing of the software timer, but you cannot delay or prevent the hardware watchdog timer from firing. It will do this when the software watchdog has been delayed for too long.

The watchdog is telling you that your code has run for too long without letting other tasks like the background WiFi run. There are very few situations where a user needs to do anything at all with the watchdog and is most cases it is a sign that your code is bad / wrong / taking too long.

The first clue is "AccelStepper library for Arduino" The ESP8266 is not an Arduino! This is a common problem when people use the wrong library, especially those written for Arduino devices which do not have WiFi and therefore do not need to worry about "locking out" the WiFi hardware. "Wrong" here means not specifically written / ported for ESP8266.

Any such library which contains a long "while X" loop which executes for more than about 20mS will cause a watchdog reset on ESP8266. I suspect this is the case here as stepping the motor will need a repeated loop.

You have two options: 1) use an ESP8266-specific stepper library 2) "Hack" accelstepper to be ESP8266-compliant: it may be as simple as putting a yield inside the stepper loop.

Either way, you must remove any wdt calls from your sketch - 99% they are just an indicator that the code is incorrect and all they do is just delay and/or mask the problem until the HW WDT fires - as your example proves.
User avatar
By pangolin
#87806 Looks like I was right: Documentation for accelstepper says:
Code: Select allrunToPosition()
void AccelStepper::runToPosition   (      )   
Moves the motor (with acceleration/deceleration) to the target position and blocks until it is at position. Dont use this in event loops, since it blocks.


"Dont use this in event loops, since it blocks" is why you are getting the WDT reset. At least the library tells you not to use the call in the way you are doing, most libraries don't.

But the simple fact is you cannot use the library in the way you are trying to do. You need a non-blocking version of this library, if one exists