Blynk.run() command causes stepper to stop working

Hello, I’m working on a project that uses blynk and a stepper motor. When I use the stepper motor on a sketch with “Blynk.run()” commented out, the stepper works wonderfully, but when I uncomment it, the stepper works erratically. I’m using a SparkFun Redboard and a 28BYJ-48 stepper with driver.

Any help is appreciated!

Here is my code (it is really messy as I’ve been tinkering with a few things)

    int moveOn = 0;
    int moveOff = 0;
    
    int button1 = 2;
    int button2 = 7;
    
    
    
    
    
    #define BLYNK_PRINT Serial    // Comment this out to disable prints and save space
    
    // These are the interrupt and control pins for СС3000
    #define ADAFRUIT_CC3000_IRQ   3
    #define ADAFRUIT_CC3000_VBAT  5
    #define ADAFRUIT_CC3000_CS    10
    
    #include <SPI.h>
    #include <Adafruit_CC3000.h>
    #include <BlynkSimpleCC3000.h>
    
    #define IN1  8
    #define IN2  9
    #define IN3  11
    #define IN4  12
    
    int Side = false;
    int Steps = 0;
    boolean Direction = true;// gre
    unsigned long last_time;
    unsigned long currentMillis ;
    int steps_left = 1024;
    long time;
    
    
    // You should get Auth Token in the Blynk App.
    // Go to the Project Settings (nut icon).
    char auth[] = "xxxx";
    
    void setup()
    {
      Serial.begin(9600);
      Blynk.begin(auth, "xxxx", "xxxx", WLAN_SEC_WPA2);
    
      pinMode(IN1, OUTPUT);
      pinMode(IN2, OUTPUT);
      pinMode(IN3, OUTPUT);
      pinMode(IN4, OUTPUT);
    
      pinMode(button1, INPUT_PULLUP);
      pinMode(button2, INPUT_PULLUP);
    }
    
    
    BLYNK_WRITE(V0)
    {
      moveOn = param.asInt();
      Blynk.virtualWrite(V2, HIGH);
      Blynk.virtualWrite(V3, LOW);
    }
    
    BLYNK_WRITE(V1)
    {
      moveOff = param.asInt();
      Blynk.virtualWrite(V3, HIGH);
      Blynk.virtualWrite(V2, LOW);
    }
    
    void loop()
    {
      //Blynk.run();
      Serial.println(moveOn);
      if (digitalRead(button1) == LOW && Side == true) {
        steps_left = 512  ;
        Side = false;
        while (steps_left > 0) {
          Direction = true;
          currentMillis = micros();
          if (currentMillis - last_time >= 1000) {
            stepper(1);
            time = time + micros() - last_time;
            last_time = micros();
            steps_left--;
          }
        }
      }
    
      if (digitalRead(button2) == LOW && Side == false) {
        steps_left = 512;
        Side = true;
        while (steps_left > 0) {
          Direction = false;
          currentMillis = micros();
          if (currentMillis - last_time >= 1000) {
            stepper(1);
            time = time + micros() - last_time;
            last_time = micros();
            steps_left--;
          }
        }
      }
    }

void stepper(int xw) {
  for (int x = 0; x < xw; x++) {
    switch (Steps) {
      case 0:
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, HIGH);
        break;
      case 1:
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, HIGH);
        break;
      case 2:
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, LOW);
        break;
      case 3:
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, HIGH);
        digitalWrite(IN4, LOW);
        break;
      case 4:
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, LOW);
        break;
      case 5:
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, HIGH);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, LOW);
        break;
      case 6:
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, LOW);
        break;
      case 7:
        digitalWrite(IN1, HIGH);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, HIGH);
        break;
      default:
        digitalWrite(IN1, LOW);
        digitalWrite(IN2, LOW);
        digitalWrite(IN3, LOW);
        digitalWrite(IN4, LOW);
        break;
    }
    SetDirection();
  }
}
void SetDirection() {
  if (Direction == 1) {
    Steps++;
  }
  if (Direction == 0) {
    Steps--;
  }
  if (Steps > 7) {
    Steps = 0;
  }
  if (Steps < 0) {
    Steps = 7;
  }
}

@akaminetzkyp

I don’t have a lot of experience with stepper motors but what happens at stepper(1) ?
stepper() is not declared in your code and without looking at that part is it hard to troubleshoot anything so you may not get many responses from other users who may know more.

Also, I see your pin selection 8, 9, 11 and 12. I don’t use the CC3000 shield but make sure nothing is conflicting with the shield pins. Here’s what I see on https://learn.sparkfun.com/tutorials/cc3000-hookup-guide:

“The pins used by the shield are as follows:
2 (INT) is the interrupt pin that the CC3000 uses to notify the Arduino that it has data.
7 (EN) is the enable pin that the Arduino uses to turn the CC3000 off and on.
8 (SDCS) is the chip select for the SD card.
10 (CS) is the chip select for the CC3000.
11 (MOSI) is the SPI communication line from the Arduino to the CC3000.
12 (MISO) is the SPI communication line from the CC3000 to the Arduino.
13 (SCK) is the SPI clock line.”

Interesting… I’m using a “Keyes” CC3000, so the pins are different. I forgot posting another tab, will post it in a minute. I’m trying to change everything to another library.

Thank you very much or your help.

Hi,

In order to drive the stepper motor consistently, the delay between to steps should be constant (or controlled to increase or decrease the speed). I guess when you use Blynk.run() the amount of time it takes might not be consistent in each call. So you find the stepper motor movement is not smooth.

Best solution to drive Stepper Motors is to generate the delay between steps using a HW timer. Set a timer value to the timer, when the time is elapsed it will fire a interrupt. In the Interrupt service routine advance to the next step of stepper motor based on the direction.

This way the delay between the 2 steps is always constant no matter how much time is taken by Blynk.run() or your other code. HW always keeps the exact time, provided interrupts are not disabled.

Unfortunately, I have no experience on how to do it in Aurdino API, but I can explain at register level :wink:

1 Like