Need help with code for Camera Slider with "loop mode"

Hi!
Need help with code for my modified 3 axis camera slider based on this project: https://www.youtube.com/watch?v=kdMYD4DvWus

Problem is that I want to make a “Loop Mode” button with “Loop Mode ON and OFF” in Blynk that repeat all stepper movements forever and when press the button to “OFF” mode its stops the motors.

Now its loop forever but don’t react when I turn the button “Off”. (Check “loopMode V21” in code and void sliderStart()).

Can somebody please help me?

Hardware: Arduino UNO with CNC Shield v3 and HM10 bluetooth: 3 x Nema 17.


#define BLYNK_PRINT Serial

#include <BlynkSimpleSerialBLE.h>
#include <SoftwareSerial.h>
#include <AccelStepper.h>
#include <MultiStepper.h>

#define EnableMotors 8

// Define the stepper motors and the pins the will use
AccelStepper stepper1(1, 2, 5); // (Type:driver, STEP, DIR)
AccelStepper stepper2(1, 3, 6);
AccelStepper stepper3(1, 4, 7);

MultiStepper StepperControl;  // Create instance of MultiStepper

long gotoposition[3]; // An array to store the In or Out position for each stepper motor
int currentSpeed = 1000;
int ProgrammSpeed = 3000;

int loopMode = 0;
int stopStepper = 0;

long XPointA = 0;
long YPointA = 0;
long ZPointA = 0;
long XPointB = 0;
long YPointB = 0;
long ZPointB = 0;
long XPointC = 0;
long YPointC = 0;
long ZPointC = 0;
long XPointD = 0;
long YPointD = 0;
long ZPointD = 0;
long XPointH = 0;
long YPointH = 0;
long ZPointH = 0;

char auth[] = "3y7tSgGXJhoSzbKl7HjjQgQo2aW-uTin";

WidgetLED led(V28);
WidgetLED led2(V29);
WidgetLED led3(V30); 
WidgetLED led4(V31);
SoftwareSerial SerialBLE(10, 11); // RX, TX

BLYNK_WRITE(V4)
{
  int pinAValue = param.asInt(); // assigning incoming value from pin V4 to a variable
       if(pinAValue==1){
        XPointA = stepper1.currentPosition(); // Set the IN position for steppers 1
        YPointA = stepper2.currentPosition(); // Set the IN position for steppers 2
        ZPointA = stepper3.currentPosition(); // Set the IN position for steppers 3
        Blynk.virtualWrite(V4, HIGH);
        Blynk.virtualWrite(V18, XPointA);
        Blynk.virtualWrite(V19, YPointA);
        Blynk.virtualWrite(V20, ZPointA);
        } else {
        XPointA = 0; // Set the IN position for steppers 1
        YPointA = 0; // Set the IN position for steppers 2
        ZPointA = 0; // Set the IN position for steppers 3        
        }     
}
BLYNK_WRITE(V5)
{
  int pinBValue = param.asInt(); // assigning incoming value from pin V5 to a variable
        if(pinBValue==1){
        XPointB = stepper1.currentPosition(); // Set the IN position for steppers 1
        YPointB = stepper2.currentPosition(); // Set the IN position for steppers 2
        ZPointB = stepper3.currentPosition(); // Set the IN position for steppers 3
        Blynk.virtualWrite(V5, HIGH);
        Blynk.virtualWrite(V18, XPointB);
        Blynk.virtualWrite(V19, YPointB);
        Blynk.virtualWrite(V20, ZPointB);
        }  else {
        XPointB = 0; // Set the IN position for steppers 1
        YPointB = 0; // Set the IN position for steppers 2
        ZPointB = 0; // Set the IN position for steppers 3
        Blynk.virtualWrite(V5, LOW);        
       }     
}
BLYNK_WRITE(V6)
{
  int pinCValue = param.asInt(); // assigning incoming value from pin V6 to a variable
        if(pinCValue==1){
        XPointC = stepper1.currentPosition(); // Set the IN position for steppers 1
        YPointC = stepper2.currentPosition(); // Set the IN position for steppers 2
        ZPointC = stepper3.currentPosition(); // Set the IN position for steppers 3
        Blynk.virtualWrite(V6, HIGH);
        Blynk.virtualWrite(V18, XPointC);
        Blynk.virtualWrite(V19, YPointC);
        Blynk.virtualWrite(V20, ZPointC);
        }  else {
        XPointC = 0; // Set the IN position for steppers 1
        YPointC = 0; // Set the IN position for steppers 2
        ZPointC = 0; // Set the IN position for steppers 3
        Blynk.virtualWrite(V6, LOW);
       }     
}
BLYNK_WRITE(V7)
{
  int pinDValue = param.asInt(); // assigning incoming value from pin V7 to a variable
        if(pinDValue==1){
        XPointD = stepper1.currentPosition(); // Set the IN position for steppers 1
        YPointD = stepper2.currentPosition(); // Set the IN position for steppers 2
        ZPointD = stepper3.currentPosition(); // Set the IN position for steppers 3
        Blynk.virtualWrite(V7, HIGH);
        Blynk.virtualWrite(V18, XPointD);
        Blynk.virtualWrite(V19, YPointD);
        Blynk.virtualWrite(V20, ZPointD);
        }  else {
        XPointD = 0; // Set the IN position for steppers 1
        YPointD = 0; // Set the IN position for steppers 2
        ZPointD = 0; // Set the IN position for steppers 3
        Blynk.virtualWrite(V7, LOW);        
       }     
}
BLYNK_WRITE(V9)
{
  int pinHValue = param.asInt(); // assigning incoming value from pin V9 to a variable
        if(pinHValue==1){
        stepper1.setCurrentPosition(0); // Set the IN position for steppers 1
        stepper2.setCurrentPosition(0); // Set the IN position for steppers 2
        stepper3.setCurrentPosition(0); // Set the IN position for steppers 3
        Blynk.virtualWrite(V9, HIGH);
        } 
}
BLYNK_WRITE(V8)
{
  int pinGHValue = param.asInt(); // assigning incoming value from pin V8 to a variable
        if(pinGHValue==1){
        Blynk.virtualWrite(V8, HIGH);
        gotoposition[0] = 0;
        gotoposition[1] = 0;
        gotoposition[2] = 0;
        stepper1.setMaxSpeed(4000);
        stepper2.setMaxSpeed(4000);
        stepper3.setMaxSpeed(4000);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position
        stepper1.setSpeed(0);
        stepper2.setSpeed(0);
        stepper3.setSpeed(0);
        stepper1.setMaxSpeed(6000);
        stepper2.setMaxSpeed(6000);
        stepper3.setMaxSpeed(6000);
        Blynk.virtualWrite(V18, gotoposition[0]);
        Blynk.virtualWrite(V19, gotoposition[1]);
        Blynk.virtualWrite(V20, gotoposition[2]);
        Blynk.virtualWrite(V8, LOW);
        } 
}
BLYNK_WRITE(V10)
{
  int pinSValue = param.asInt(); // assigning incoming value from pin V10 to a variable
       if(pinSValue==1) {
         Blynk.virtualWrite(V10, HIGH);
         SliderStart(); }
       else {
         Blynk.virtualWrite(V10, LOW);
       }   
}
BLYNK_WRITE(V11)
{
  int pinSAValue = param.asInt(); // assigning incoming value from pin V11 to a variable
       if(pinSAValue==1) {
        Blynk.virtualWrite(V11, HIGH);
        GoPos01();
        stepper1.setSpeed(0);
        stepper2.setSpeed(0);
        stepper3.setSpeed(0);
        Blynk.virtualWrite(V11, LOW);
        stepper1.setMaxSpeed(6000);
        stepper2.setMaxSpeed(6000);
        stepper3.setMaxSpeed(6000); 
       }
}
BLYNK_WRITE(V12)
{
  int pinSBValue = param.asInt(); // assigning incoming value from pin V12 to a variable
       if(pinSBValue==1) {
        Blynk.virtualWrite(V12, HIGH);
        GoPos02();
        stepper1.setSpeed(0);
        stepper2.setSpeed(0);
        stepper3.setSpeed(0); 
        Blynk.virtualWrite(V12,LOW);
        stepper1.setMaxSpeed(6000);
        stepper2.setMaxSpeed(6000);
        stepper3.setMaxSpeed(6000);
       }
}
BLYNK_WRITE(V13)
{
  int pinSCValue = param.asInt(); // assigning incoming value from pin V13 to a variable
       if(pinSCValue==1) { 
        Blynk.virtualWrite(V13, HIGH);
        GoPos03(); 
        stepper1.setSpeed(0);
        stepper2.setSpeed(0);
        stepper3.setSpeed(0);
        Blynk.virtualWrite(V13, LOW);
        stepper1.setMaxSpeed(6000);
        stepper2.setMaxSpeed(6000);
        stepper3.setMaxSpeed(6000);
       }
}
BLYNK_WRITE(V14)
{
  int pinSDValue = param.asInt(); // assigning incoming value from pin V14 to a variable
       if(pinSDValue==1) { 
        Blynk.virtualWrite(V14, HIGH);
        GoPos04();
        stepper1.setSpeed(0);
        stepper2.setSpeed(0);
        stepper3.setSpeed(0);
        Blynk.virtualWrite(V14, LOW);
        stepper1.setMaxSpeed(6000);
        stepper2.setMaxSpeed(6000);
        stepper3.setMaxSpeed(6000);
       } 
}
BLYNK_WRITE(V1)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V1 to a variable
   currentSpeed = pinValue;
   currentSpeed = map(currentSpeed, 0, 100, 0, 2000);
}
BLYNK_WRITE(V15)
{
  int pinValue = param.asInt(); // assigning incoming value from pin V15 to a variable
   ProgrammSpeed = pinValue;
   ProgrammSpeed = map(ProgrammSpeed, 0, 100, 0, 6000);
}
BLYNK_WRITE(V0)
{
  int sliderValue = param.asInt(); // assigning incoming value from pin V0 to a variable
    // Slider potentiometer
    // If potentiometer is turned left, move slider left
  if (sliderValue > 600) {
    sliderValue = map(sliderValue, 600, 1024, 0, 6000);
    stepper1.setSpeed(sliderValue); // Increase speed as turning
  }
  // If potentiometer is turned right, move slider right
  else if (sliderValue < 400 ) {
    sliderValue = map(sliderValue, 400, 0, 0, 6000);
    stepper1.setSpeed(-sliderValue); // Increase speed as turning
  }
  // If potentiometer in middle, no movement
  else {
    stepper1.setSpeed(0);
  } 
}
BLYNK_WRITE(V3) {
  int x = param[0].asInt();
  int y = param[1].asInt();
  // Joystick X - Pan movement
  // if Joystick is moved left, move stepper 2 or pan to left
  if (x > 60) {
    x = map(x, 60, 100, 0, currentSpeed);
  stepper2.setSpeed(-x);
  }
  // if Joystick is moved right, move stepper 2 or pan to right
  else if (x < 40) {
    x = map(x, 40, 0, 0, currentSpeed);
    stepper2.setSpeed(x);
  }
  // if Joystick stays in middle, no movement
  else {
    stepper2.setSpeed(0);
  }

  //Joystick Y - Tilt movement
  if (y > 60) {
    y = map(y, 60, 100, 0, currentSpeed);    
    stepper3.setSpeed(y);
  }
  else if (y < 40) {
    y = map(y, 40, 0, 0, currentSpeed);
    stepper3.setSpeed(-y);
  }
  else {
    stepper3.setSpeed(0);
  }  
}
BLYNK_WRITE(V17)
{
  loopMode = param.asInt(); // assigning incoming value from pin V17 to a variable
  if(loopMode==1) { 
    Blynk.virtualWrite(V17, HIGH);
    }
  else {
    Blynk.virtualWrite(V17, LOW);
    loopMode=0;
  }      
}
BLYNK_WRITE(V21)
{
  stopStepper = param.asInt(); // assigning incoming value from pin V21 to a variable
  if(stopStepper==1) {
    Blynk.virtualWrite(V21, HIGH);
    }
  else {
    Blynk.virtualWrite(V21, LOW);
    stopStepper=0;
  }      
}

void setup()
{
  SerialBLE.begin(9600);
  Blynk.begin(SerialBLE, auth);

  stepper1.setMaxSpeed(6000);
  stepper1.setSpeed(0);
  stepper2.setMaxSpeed(6000);
  stepper2.setSpeed(0);
  stepper3.setMaxSpeed(6000);
  stepper3.setSpeed(0);
    // Create instances for MultiStepper - Adding the 3 steppers to the StepperControl instance for multi control
  StepperControl.addStepper(stepper1);
  StepperControl.addStepper(stepper2);
  StepperControl.addStepper(stepper3);
  Blynk.virtualWrite(V4, LOW);
  Blynk.virtualWrite(V5, LOW);
  Blynk.virtualWrite(V6, LOW);
  Blynk.virtualWrite(V7, LOW);
  Blynk.virtualWrite(V8, LOW);
  Blynk.virtualWrite(V9, LOW);
  Blynk.virtualWrite(V10, LOW);
  Blynk.virtualWrite(V11, LOW);
  Blynk.virtualWrite(V12, LOW);
  Blynk.virtualWrite(V13, LOW);
  Blynk.virtualWrite(V14, LOW);
  Blynk.virtualWrite(V1, 50);
  Blynk.virtualWrite(V0, 512);
  Blynk.virtualWrite(V15, 50);
  Blynk.virtualWrite(V16, 50);
  led.off();
  led2.off();
  led3.off();
  led4.off();
}
void loop()
{
  Blynk.run();
  // Execute the above commands - run the stepper motors
  stepper1.runSpeed();
  stepper2.runSpeed();
  stepper3.runSpeed();
}
void GoPos01() {
        led.on();
        // Place the OUT position into the Array
        gotoposition[0] = XPointA;
        gotoposition[1] = YPointA;
        gotoposition[2] = ZPointA;
        Blynk.virtualWrite(V18, gotoposition[0]);
        Blynk.virtualWrite(V19, gotoposition[1]);
        Blynk.virtualWrite(V20, gotoposition[2]);
        stepper1.setMaxSpeed(ProgrammSpeed);
        stepper2.setMaxSpeed(ProgrammSpeed);
        stepper3.setMaxSpeed(ProgrammSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position
        delay(1000);
        led.off();      
}
void GoPos02() {
        led2.on();
        // Place the OUT position into the Array
        gotoposition[0] = XPointB;
        gotoposition[1] = YPointB;
        gotoposition[2] = ZPointB;
        Blynk.virtualWrite(V18, gotoposition[0]);
        Blynk.virtualWrite(V19, gotoposition[1]);
        Blynk.virtualWrite(V20, gotoposition[2]);
        stepper1.setMaxSpeed(ProgrammSpeed);
        stepper2.setMaxSpeed(ProgrammSpeed);
        stepper3.setMaxSpeed(ProgrammSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position 
        delay(1000);
        led2.off();  
}
void GoPos03() {
        led3.on();
        // Place the OUT position into the Array
        gotoposition[0] = XPointC;
        gotoposition[1] = YPointC;
        gotoposition[2] = ZPointC;
        Blynk.virtualWrite(V18, gotoposition[0]);
        Blynk.virtualWrite(V19, gotoposition[1]);
        Blynk.virtualWrite(V20, gotoposition[2]);
        stepper1.setMaxSpeed(ProgrammSpeed);
        stepper2.setMaxSpeed(ProgrammSpeed);
        stepper3.setMaxSpeed(ProgrammSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position  
        delay(1000);
        led3.off();   
}
void GoPos04() {
        led4.on();
        // Place the OUT position into the Array
        gotoposition[0] = XPointD;
        gotoposition[1] = YPointD;
        gotoposition[2] = ZPointD;
        Blynk.virtualWrite(V18, gotoposition[0]);
        Blynk.virtualWrite(V19, gotoposition[1]);
        Blynk.virtualWrite(V20, gotoposition[2]);
        stepper1.setMaxSpeed(ProgrammSpeed);
        stepper2.setMaxSpeed(ProgrammSpeed);
        stepper3.setMaxSpeed(ProgrammSpeed);
        StepperControl.moveTo(gotoposition); // Calculates the required speed for all motors
        StepperControl.runSpeedToPosition(); // Blocks until all are in position
        delay(1000);
        led4.off();        
}
void SliderStart() {
    Blynk.virtualWrite(V10, HIGH);
    do {
    if (XPointA || YPointA || ZPointA !=0) GoPos01();
    if (XPointB || YPointB || ZPointB !=0) GoPos02();
    if (XPointC || YPointC || ZPointC !=0) GoPos03();
    if (XPointD || YPointD || ZPointD !=0) GoPos04(); 
    } while (loopMode==1);
    stepper1.setSpeed(0);
    stepper2.setSpeed(0);
    stepper3.setSpeed(0);
    stepper1.setMaxSpeed(6000);
    stepper2.setMaxSpeed(6000);
    stepper3.setMaxSpeed(6000);
    Blynk.virtualWrite(V10, LOW);
}

I’m not quite sure what you mean by “loopmode” here. V21 will run just once, when you press the button widget attached to pin V21. It won’t keep running in a loop.

You’ve added a variable called stopStepper, but it’s not used anywhere in your code except in the BLYNK_WRITE(V21) callback. I would have expected you to have one or more p;laces within your code where you check the value of stopStepper and take different actions based on it’s value.

Pete.

Hi Pete. What I mean by “loop mode” is that the 3 steppers move from position 1-4 (gotopos01-04()) stored in an array (check sliderstart()) and when is finished it start again. Its looping now when “loopmode”button is activated (V17) but I can’t stop the loop. That’s the problem! Is there something who block the code, so the hardware to respons. Shall I set something in void loop() to check what value variable “loopmode” is? I’m a newbie in coding, so I really need your help with this :slight_smile:

So was the V21 a typo and should have read V17 ?

Can you explain the reasoning behind the Blynk.virtualWrite(V17, HIGH) and Blynk.virtualWrite(V17, LOW) commands in this V17 callback?

You do this in other callbacks too, and I can’t understand the logic behind it.

Pete.

Well, in the blynk app, I’ve made 3 buttons, one who I called “loop mode” (V17), “stop steppers” (V21) and a button called “program start” (V10, who call sliderstart()). What I want is when I press “program start” and button “loop mode” is ON; is that sliderstart() will run forever and when I press the “loop mode” off button it goes out of loop. Is it possible? or do i need a “stop stepper” button who’s stop the loop or turn off the steppers? Maybe I’ve been missing something!?

You didn’t answer my question about the Blynk.virtualWrite(V17, HIGH) and Blynk.virtualWrite(V17, LOW) commands.

If you look at your BLYNK_WRITE(V17) callback function, what it’s actually saying is this…

If the button widget attached to V17 is on, then turn the button widget attached to V17 on. Otherwise, turn the button widget attached to V17 off.

Hopefully, you can see that because the button widget is already on or off, you don’t need to re-confirm this status in a Blynk.virtualWrite command.
As a result, you V17 code can be trimmed-down to this…

BLYNK_WRITE(V17)
{
 loopMode = param.asInt(); // assigning incoming value from pin V17 to a variable
 if(loopMode==1)
  {
    // do nothing
  }
 else 
  {
    loopMode=0;
  }
}

As the loopMode global variable isn’t used anywhere else in the code (other than where it’s declared at the top of your sketch, the callback function doesn’t actually achieve anything.

I’d suggest that you take out the unnecessary parts of the other BLYNK_WRITE callbacks that you’ve added and it may give you some clarity.

Pete.

Hi again!
There is no logical reason for Blynk.virtualWrite(V17, HIGH) and Blynk.virtualWrite(V17, LOW) commands, I was just testing.

If you look at the end of the code, “loopMode” is used:

[Unformatted code removed by moderator]

The problem is when I press the “Loop Mode” button OFF and loopMode variable get value “0” it don’t stop or goes out of “do - while” code.

When you post code to the forum it needs to be correctly formatted with triple backticks.

You’re correct, loopMode is used elsewhere, it’s the stopStepper variable that isn’t - my mistake.

However, if you’re going to use a variable, such as loopMode as a flag elsewhere else in your code, you need a method of setting it to both true and false.

Pete.

I have now removed stopStepper from the code.
I thought I used loopMode as a flag with the “Loop Mode” button in “switch” mode in the blynk app. When selected value = 1 and not selected value = 0.

But you’ve chosen to do that in a while loop, which will never exit that loop unless loopMode changes, and that change is outside of that loop, so will never be processed whilst looping.

Pete.

Ok, but how do I get that code inside the loop then, so it stops the loop when “loop mode” is off? Sorry to bother you with simple questions :slight_smile: