steppermotor with big easy stepper shield and accelstepper library

I have a question about how to control a steppermotor with a big easy stepper shield and a accelstepper library. What i want to do is rotate the stepper 90 degrees and take a picture, this has to be repeated 4 times.

I managed to do this without using the accelstepper library, but with the accelstepper library i can make the stepper accelerate and deaccelerate witch is important for me because the stepper has to move a heavy camera. I can’t make the code with the accelstepper work… :frowning: The camera trigger part works (it makes 4 pictures) but the motor isn’t moving.

This is the code i am struggling with:

#define SHUTTER_PIN 7
#include <AccelStepper.h>
int TotalShots = 4;
long pos = 85924 / TotalShots; // 85924 is the total amound of steps te complete a rotation
AccelStepper stepper(1, 9, 8); // Define a stepper and the pins it will use

void setup() {                

  stepper.setMaxSpeed(6000);
  stepper.setAcceleration(1000);
  pinMode(SHUTTER_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("start of the program");

}

void loop()  
{ 
 delay(1000);
 for(int shot = 0; shot < TotalShots; shot++)
    {  
       {
         stepper.setCurrentPosition(0); 
         stepper.moveTo(pos);   
         stepper.run();
       }                    
    delay(1000);  
    digitalWrite(SHUTTER_PIN, LOW);
    delay(2000);  // take shot
    digitalWrite(SHUTTER_PIN, HIGH);
   } 

while(true) {} // execution does not proceed past this point  

}

This is the code that dit the trick, but without the accelstepper library:

#define SHUTTER_PIN 7
#define DIRECTION_PIN 8
#define STEPPER_PIN 9
int TotalShots = 4;
long StepsPerShot = 85924 / TotalShots; // 85924 is the total amound of steps te complete a rotation

void setup() {                

  pinMode(8, OUTPUT);     
  pinMode(9, OUTPUT);
  digitalWrite(8, LOW);
  digitalWrite(9, LOW);

}

void loop()  { 

for(int shot = 0; shot < TotalShots; shot++)
{
    for(int steps = 0; steps < StepsPerShot; steps++)
    {
      digitalWrite(STEPPER_PIN, HIGH);
      delayMicroseconds(60); // speed of the stepper         
      digitalWrite(STEPPER_PIN, LOW); 
      delayMicroseconds(60);
    }
    delay(1000);  
    digitalWrite(SHUTTER_PIN, LOW);
    delay(2000);  // take shot
    digitalWrite(SHUTTER_PIN, HIGH); 
  }


while(true) {} // execution does not proceed past this point  

}

I hope someone can point me into the right direction…

I hope someone can point me into the right direction..

Right here, barely into loop(), and you're going the wrong way already.

void loop()  
{ 
 delay(1000);

Read, study, and embrace the blink without delay mindset, without delay.

       {
         stepper.setCurrentPosition(0); 
         stepper.moveTo(pos);   
         stepper.run();
       }

Why are these curly braces here?

The run() method should start the stepper moving. It returns immediately, before the stepper has had a chance to move.

You need to then, periodically, ask the instance whether the stepper is where it needs to be BEFORE taking the picture.

You need to develop a simple sketch that moves the stepper using the library, working on that sketch until you can successfully move the motor. Only then should you worry about taking a picture.

Also, I don't see anywhere in that code where you set the acceleration, deceleration, or when the accell/decel is to happen.

The speed and accel/deaccel is set under void setup:

void setup() {                

  stepper.setMaxSpeed(6000);
  stepper.setAcceleration(1000);

When i remove the trigger rules and remove the code that repeats it 4 times the stepper is rotating 90 degrees (using acceleration en deacceleration)

void loop()  
{ 

// for(int shot = 0; shot < TotalShots; shot++)
    {  
       {
//         stepper.setCurrentPosition(0); 
         stepper.moveTo(pos);   
         stepper.run();
       }                    
//    delay(1000);  
//    digitalWrite(SHUTTER_PIN, LOW);
//    delay(2000);  // take shot
//    digitalWrite(SHUTTER_PIN, HIGH);
   } 

// while(true) {} // execution does not proceed past this point  

}

When i remove the trigger rules and remove the code that repeats it 4 times the stepper is rotating 90 degrees (using acceleration en deacceleration)

That's good. It happens, though, because now there is nothing that cares that the stepper actually gets to a specific position.

The moveTo() method is ignored on subsequent passes through loop, because the stepper is still trying to get to the initially commanded position. Once it does get there, telling it to go where it is causes nothing to happen.

The next step, for you, is to learn how to determine if the stepper is where you told it to go. If it is, you can then take the picture, and tell it to go to a new position.

Thanks, i understand what you mean but getting it done is still not easy for me.

I changed the code to:

void loop()  
{ 

for(int shot = 0; shot < TotalShots; shot++)
    { 
       for(long steps = 0; steps < pos; steps++) 
       {         
         stepper.moveTo(pos);   
         stepper.run();
         Serial.println(steps);
       }    
          Serial.println("number of shots");  
          Serial.println(shot+1);         
 //       delay(1000);
 //       digitalWrite(SHUTTER_PIN, LOW);
 //       delay(2000);  // take shot
 //       digitalWrite(SHUTTER_PIN, HIGH);
   } 

while(true) {} // execution does not proceed past this point  

}

A part of the serial print gives me the flowing output:

7158
7159 (latest step of first turn, witch is correct)
number of shots
1 (first shot)
0 (first step of the second turn)
1
and so on.

What seems correct, but when i delete the serial.println lines the stepper is just moving a few steps and than stops. Any ideas what goes wrong?

The Serial.print() lines take time. During that time, the stepper gets the opportunity to move. Without them, the for loop(s) complete so fast that the stepper never gets an opportunity to move. The infinite loop at the end then never gives the stepper an opportunity to move, either.

Any suggestions how to code this?

Any suggestions how to code this?

Look at the AccelStepper class. There is a method to determine where the stepper is. If the stepper has been told to move, and it isn't yet where it was told to go, do nothing. If it is, take a picture.

Oké, i am a step further. The stepper is reaching its position, takes a picture and goes to its next position and so on.

#define SHUTTER_PIN 7
#include <AccelStepper.h>
int TotalShots = 4;
long pos = 85924 / TotalShots; // 85924 is the total amound of steps te complete a rotation
AccelStepper stepper(1, 9, 8); // Define a stepper and the pins it will use

void setup() {                

  stepper.setMaxSpeed(4000);
  stepper.setAcceleration(4000);
  pinMode(SHUTTER_PIN, OUTPUT);
  Serial.begin(9600);
  Serial.println("start of the program");

}

void loop()  
{ 

//for (int shot=0 ; shot < TotalShots ; shot++)

    { 
       stepper.moveTo(pos);   
       stepper.run();
      
         if (stepper.distanceToGo() == 0)        
         {
            delay(1000);  
            Serial.println("number of shots"); 
   //       digitalWrite(SHUTTER_PIN, LOW);
   //       delay(2000);  // take shot
   //       digitalWrite(SHUTTER_PIN, HIGH);
            stepper.setCurrentPosition(0);
         } 
      
  }
//while(true) {} // execution does not proceed past this point
}

The next step is that it stops after 4 times.
When i remove the “//” before the rules: “for (int shot=0 ; shot < TotalShots ; shot++)” and “while(true) {} // execution does not proceed past this point”
it stops without moving the motor. I assume that it has to do with the same problem as before, that the motor has no time to reach it position. Is it not possible to complete the code after “for (int shot=0 ; shot < TotalShots ; shot++){}” before counting another shot?

Is it not possible to complete the code after “for (int shot=0 ; shot < TotalShots ; shot++){}” before counting another shot?

Yes, it is. You need a do nothing until mechanism in the loop() function, not an if mechanism.

    for(int shot=0 ; shot < TotalShots ; shot++)
    { 
       stepper.moveTo(pos);   
       stepper.run();
      
       while (stepper.distanceToGo() != 0)
       {
          // Don't do a thing. The stepper ain't there yet.
       }

       // Now, the stepper is where you want, so take a picture
       delay(1000);  
       Serial.println("number of shots"); 
//    digitalWrite(SHUTTER_PIN, LOW);
//    delay(2000);  // take shot
//    digitalWrite(SHUTTER_PIN, HIGH);

       stepper.setCurrentPosition(0);  
    }

Thanks Paul!

It is working now. I only had to change:

stepper.moveTo(pos);   
stepper.run();
      
         while (stepper.distanceToGo() != 0) 
             {}

into:

stepper.moveTo(pos);   
     
         while (stepper.distanceToGo() != 0) 
             {stepper.run();}

To make it work.

Thanks again.