Control a stepper in a long duration cause disconnection

Hi all,
I’m using Blynk with ESP8266 standalone to control a stepper.
I find when the stepper is reaching a long distance, which takes more than 5 seconds.
The ESP will get a wdt msg and restart, then blynk disconnects.

Is this a known issue?

I noticed a post about calling blynk.run() inside a time-cost function. I don’t know if this is the root cause.

I’n not sure how you define your time cost, but the use of “delay()” could be a cause. I’d try without it. You can use millis(). That should work better, but is a bit more complicated. I’ve written a little subroutine to accomplish this:

unsigned long previousMillis = 0;
boolean state = 1;

void loop
{
      previousMillis = millis();         // Reset counter
      wait(5000);                        // Wait with interval period
      state = 1;                      // Reset waiting state
}

void wait(unsigned long interval) 
{ 
  // Compare previous millis to current one and wait until the interval has been reached in a do loop
  // Also set / reset waiting states so the loop keeps looping until the interval has been reached
  
  
  do
  {
    if((unsigned long)(millis() - previousMillis) >= interval)
    {
      previousMillis = millis();
      state = 0;
      break;
    }
  } 
  while (state = 1);
}

This way you can use the function everywhere you want to wait. I hope this helps a bit :slight_smile:

I use the stepper library shipped with arduino. Maybe I need to dig inside to see if delay is used. If there is, maybe I want to try your hacked delay. Thanks!

Stepper library also takes use of millis . When I put the step(some distance) in a while loop, with stop condition of some IO state, the ESP will begin to restart very soon during moving

That’s weird. I’m not sure what else can be wrong since I haven’t used a stepper motor yet in my projects, but I got one from an old printer.

Maybe someone else can help you for now since I’m kind of unfamiliair with this specific setup :slight_smile:

Hi…

i’m not an expert on this, but i have been working the past weeks with steppers now, and starting to get something that looks promising :smile:
The difference is that i’m using a stepper driver compared to you.

I also experienced disconnections when running a while loop, and solved it by putting a Blynk.run() inside it. http://community.blynk.cc/t/blynk-run-in-other-loops/1042

I specifically use it to run the motor while pressing a button-widget, and i’m not sure why. but sometimes it get chunky movements. i think it might be because of blynk.run sometimes taking to long due to slow connection.

If your problems isn’t solved, post your code and we can take a look :smile:

1 Like

Thanks for reply. I paste my code below.

//#define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
#include <ESP8266WiFi.h>
#include <BlynkSimpleEsp8266.h>
#include <ESP8266mDNS.h>
#include <WiFiManager.h>
#include <EEPROM.h>
#include <DHT.h>
#include <SimpleTimer.h> 
#include <Stepper.h>
   
#define STOPPIN 13  // Connect the position switch to this Pin
#define RELAYPIN 12
#define DHTPIN 14
#define STATPIN 15    
#define DHTTYPE DHT22   // DHT 22  (AM2302)
#define STEPS 200

#define PA 15  // Phase A Positive
#define NA 2   // Phase A Negative
#define PB 4
#define NB 5

// Initialize DHT sensor for normal 16mhz Arduino
DHT dht(DHTPIN, DHTTYPE, 20);

Stepper stepper(STEPS, PA, NA, PB, NB );

// You should get Auth Token in the Blynk App.
char auth[] = "xxxxxxxxxxxxxxxxxxxx";  // Got from Blynk app

SimpleTimer timer;

bool motorFlag = LOW;
bool tempFlag = LOW;
bool humiFlag = LOW;
int previous = 0;
WiFiManager wifi(0);
WidgetLED STAT(6);
WidgetTerminal terminal(5);

void setup()
{
  //Serial.begin(115200);  
  wifi.autoConnect("Blynk");
  String ssid = wifi.getSSID();
  String pass = wifi.getPassword();
  Blynk.begin(auth, ssid.c_str(), pass.c_str()); 
  while (!Blynk.connect()) 
  {
    // Wait until connected
  }
  dht.begin();  
  pinMode(RELAYPIN, OUTPUT);
  digitalWrite(RELAYPIN, LOW);
  
  stepper.setSpeed(150);
  pinMode( STOPPIN,INPUT);  
  while(digitalRead(STOPPIN))
  {
    stepper.step(STEPS);  // here I want to return back to the start point where the switch locates.. Restart issue happens
  }
  SetMotorPin(LOW);
  Email("xxxxx@sina.com", "Test from Blynk", "Connected!");
  
  terminal.println(F("Blynk v" BLYNK_VERSION ": Device started"));
  terminal.flush();
  //   Setup function to be called each 1000 milliseconds
  timer.setInterval(2000, blinkLedWidget);
}

void loop()
{
  Blynk.run();
  timer.run();
}

// Timer Trigger defined on virtual pin 0
BLYNK_WRITE(0){
  int v0 = param.asInt();  
  if(v0)
  { 
    Routine();  // Restart issue happens
    terminal.println(F("Mornint Alarm !! Sprinkler triggered by timer."));
    terminal.flush();   
  }
}

// Timer Trigger defined on virtual pin 1
BLYNK_WRITE(1){
  int v1 = param.asInt();
  if(v1)
  {
    Routine();
    terminal.println(F("Noon Alarm !! Sprinkler triggered by timer."));
    terminal.flush();  
  }
}
   
// Read temparature from DHT sensor and write the data to virtual pin 3
BLYNK_READ(3){  
  String sent = "NaN";
  if(tempFlag)
  {
    float t = dht.readTemperature();
    char charVal[4];
    dtostrf(t, 4, 1, charVal);
    sent = String(charVal) + " ℃";
  }
  Blynk.virtualWrite(3, sent);
}

// Read humidity from DHT sensor and write the data to virtual pin 4
BLYNK_READ(4){
  String sent = "NaN";
  if(humiFlag)
  {    
    float h = dht.readHumidity();
    char charVal[4];    
    dtostrf(h, 4, 1, charVal);
    sent = String(charVal) + " %";
  }
  Blynk.virtualWrite(4, sent );
}

// Monitor data on serial port to virtual pin 5
BLYNK_WRITE(5)
{
  // Send it back
  String rec = param.asStr();
  if(rec == "t")
  {
    tempFlag=HIGH;
    terminal.println(F("Temperature Enabled"));
    }
  else if(rec == "h")
  {
    humiFlag=HIGH;
    terminal.println(F("Humidity Enabled"));
  }
  else if(rec == "ht")
  {    
    tempFlag=HIGH;
    humiFlag=HIGH;
    terminal.println(F("Temperature & Humidity Enabled"));
  }
  else if(rec == "nht")
  {
    tempFlag=LOW;
    humiFlag=LOW;
    terminal.println(F("Temperature & Humidity Disabled"));
  }
  else
  {
    terminal.write(param.getBuffer(), param.getLength());
    terminal.println();
  }
  terminal.flush();  
}

// Blink LED widget , comment this part to improve performance
void blinkLedWidget()
{
  if (STAT.getValue()) {
    STAT.off();
  } else {
    STAT.on();
  }
}

// Update status to virtual pin 7
BLYNK_WRITE(7) {
  int v7 = param.asInt();
  bool blink = digitalRead( STOPPIN );
  String msg;
  if(motorFlag)
  {
    if (blink) {
      msg = "Run";
      stepper.step(previous-v7);      
      } 
    else {
     msg = "Stop";
     previous = 0;
     stepper.step(previous-v7);
     }
     previous = v7;
  }
  else
  {     
     msg = "Idle";
     SetMotorPin(LOW);
  } 
  Blynk.virtualWrite(2, msg);
}

// Update status to virtual pin 8
BLYNK_WRITE(8) {
  int v8 = param.asInt();
  motorFlag = bool(v8);
  if(!motorFlag)
  {
    SetMotorPin(LOW);
    Blynk.virtualWrite(2, "Idle");
  }
}

void Email( char *Addr, char *subject, char *content)
{
  Blynk.email(Addr, subject, content);
} 

void SetMotorPin(bool flag)
{
  digitalWrite( PA , flag);
  digitalWrite( NA , flag);
  digitalWrite( PB , flag);
  digitalWrite( NB , flag); 
}

void Routine()
{
  while(digitalRead(STOPPIN))
  {
    stepper.step(STEPS);   //Restart issue happens
  }
  digitalWrite(RELAYPIN, HIGH);
  digitalWrite(RELAYPIN, LOW);
  stepper.step(-3000);  //Restart issue happens
  digitalWrite(RELAYPIN, HIGH);
  digitalWrite(RELAYPIN, LOW);
  stepper.step(3000); //Restart issue happens
  SetMotorPin(LOW);
}

@juncaofish

Hi. As i told you i havn’t tried to work with the stepper.h library because i use a stepper driver.
But your problem looks like mine, the steps take up to long time.

The while loop. You just want it to run until hitting the some switch, right?
if so you could probably do it with the code:

while(digitalRead(STOPPIN))
   {
     Blynk.run();
     stepper.step(5); // try with a low number of steps  to avoid each stepper.step() taking to long
   }

the other isue is when you want to move precisely 3000 steps.
maybe this will work.

int j = 0
while(j < 3000)
  {
    Blynk.run();
    stepper.step(5); // again avoid to many steps
    j = j+5
  }

The movement might get a little chunky depending you connection to blynk server. thats my experience anyway. Keep in mind that i haven’t tested it. but i think the idea should work :slight_smile:

@Pavel I saw you followed this thread :slight_smile: Do you have any better ideas/ workarounds? Or maybe some solution blynk-side :slight_smile:

Thanks for your detailed feedback. I’m guessing that the wdt issue is caused easily if we failed in calling Blynk.run() inside active thread. So your solution might work. Will try later after work. Thanks again.

Also I use slider on virtual pin 7. When I tap a long distance to reach, wdt issue happens too. So should I put Blynk.run() inside BLYNK_WRITE(7) {} ? It may cause another heap memory problem, as I saw in another post…

The slider issue i dont have a solution for. The blynk.run() shouldn’t go inside BLYNK_WRITE(). I haven’t had any luck with it, also referring to the link i posted erlier.
Depending on how you want to use the slider, maybe the slider could write a variable and then a function who runs the stepping stuff and reading the value from the slider through the variable. This way you can still put Blynk.run () inside the function. and every time the slider-state is changed the variable is rewritten and the function is called again.