Accelstepper function

I am playing around with the Accelerstepper examples with a view to a future project. I am trying to get the stepper to turn 3000 CW steps in one direction the 500 CCW and then stop. I have tried using booleans but to no avail. What i get is the stepper moves 3000 steps CW then 500 steps CCW, then 500 steps CCW continuously. Any insight would be much appreciated.

void setup()
{  
  stepper1.setCurrentPosition(0);
  stepper1.setMaxSpeed(1000.0);
  stepper1.setAcceleration(800.0);
  stepper1.move(3000);
    
}

void loop()
{
  // Change direction at the limits
  if (runstepper)
  {
    if (stepper1.distanceToGo() != 0)
    {
      stepper1.run();
    }
    else
    {
      stepper1.move(-500);
    }
    //runstepper = false;
  }
  else
  {
    stepper1.stop();
  }
}

I adapted a code that I wrote a while back to accomplish your goal.

#include <AccelStepper.h>

const unsigned int NUM_STEPS = 2;

unsigned int xArray[NUM_STEPS] = {3000, 2500};
unsigned int xSpeeds[NUM_STEPS] = {500, 500};

const byte enablePin = 8;

AccelStepper x_stepper(AccelStepper::DRIVER, 2, 5);

void setup()
{
   Serial.begin(115200);
   pinMode(enablePin, OUTPUT);
   digitalWrite(enablePin, LOW);
   x_stepper.setAcceleration(2000);
   x_stepper.setMaxSpeed(200);
   x_stepper.setSpeed(200);
   x_stepper.setCurrentPosition(0);
}

void loop()
{
   static unsigned int index = 0;
   if (x_stepper.run() == 0)
   {
      Serial.println(index);
      x_stepper.moveTo(xArray[index]);
      x_stepper.setMaxSpeed(xSpeeds[index]);
      index++;
      if (index > NUM_STEPS)
      {
         while(1);  // stop forever
      }
   }
}

Does this work without the "while" as this is blocking and will mess up other functions?

The while(1) is an endless loop so nothing will happen until the board is reset.

That is what I had to go by. There is nothing there to suggest that anything else is to happen.

You could replace the while with a flag and make the execution of the sequence conditional on the state of the flag.

I tried already works a treat. Thanks a lot

Does this do what you want?

#include <AccelStepper.h>

AccelStepper stepper1(AccelStepper::DRIVER, 4, 5);

void setup()
{
  stepper1.setCurrentPosition(0);
  stepper1.setMaxSpeed(1000.0);
  stepper1.setAcceleration(800.0);

  // move 3000 CW steps
  stepper1.move(3000);
  stepper1.runToPosition();

  // then 500 CCW
  stepper1.move(-500);
  stepper1.runToPosition();

  // then stop.
}

void loop()
{

}

Then, please, post your code so that someone else that comes across this thread may benefit.

Yes that does but as the code is in the setup it would as the setup only runs once.

Solution for info.

#include <AccelStepper.h>

const unsigned int NUM_STEPS = 2;

unsigned int xArray[NUM_STEPS] = {3000, 2500};
unsigned int xSpeeds[NUM_STEPS] = {500, 500};

const byte enablePin = 8;

boolean RunFunction = true;

//AccelStepper x_stepper(AccelStepper::1, 11, 12);
AccelStepper x_stepper(1, 11, 12);

void setup()
{
   Serial.begin(115200);
   pinMode(enablePin, OUTPUT);
   digitalWrite(enablePin, LOW);
   x_stepper.setAcceleration(2000);
   x_stepper.setMaxSpeed(200);
   x_stepper.setSpeed(200);
   x_stepper.setCurrentPosition(0);
}

void loop()
{
  if (RunFunction)
  {
   static unsigned int index = 0;
   if (x_stepper.run() == 0)
   {
      Serial.println(index);
      x_stepper.moveTo(xArray[index]);
      x_stepper.setMaxSpeed(xSpeeds[index]);
      index++;
      if (index > NUM_STEPS)
      {
         //while(1);  // stop forever
         //x_stepper.stop(); this works as well
         RunFunction = false;
      }
   }
  }
}
1 Like

If you want it to run only once in loop:

void loop()
{
  static boolean runOnce = true;
  
  if (runOnce)
  {
  stepper1.move(3000);
  stepper1.runToPosition();
  stepper1.move(-500);
  stepper1.runToPosition();
  runOnce = false;
  }
}

I suggest that you make the index variable global instead of static local. You will have to set index to 0 and the flag to true to run the sequence again.

Ok thanks. Very elegant code.

Isn't runToPosition(); blocking?

Yes, it is blocking. Did you want it to happen once in loop() without blocking?

Yes I did because there will be other functions in the loop

#include <AccelStepper.h>

AccelStepper stepper1(AccelStepper::DRIVER, 4, 5);

enum {Idle, Move3000CW, Move500CCW} StepperState;

void setup()
{
  stepper1.setCurrentPosition(0);
  stepper1.setMaxSpeed(1000.0);
  stepper1.setAcceleration(800.0);

  // move 3000 CW steps
  stepper1.move(3000);
  StepperState = Move3000CW;
}

void loop()
{
  switch (StepperState)
  {
    case Idle: break;

    case Move3000CW:
      stepper1.run();
      if (stepper1.distanceToGo() == 0)
      {
        stepper1.move(-500);
        StepperState = Move500CCW;
      }
      break;

    case Move500CCW:
      stepper1.run();
      if (stepper1.distanceToGo() == 0)
      {
        StepperState = Idle;
      }
      break;
  }
}

A state machine, interesting alternative. I will try it tomorrow

Ok tried the State machine version generally it works great. Just 1 small issue which i cant seem to get to work to perfection. The majority of the functions the stepper has to take will be handled with steps, and set acceleration. this part works just fine. The part cant seem to get working 100% is the BLEED function. When I set the speed to a higher speed it continues to turn at the lower set speed.

#include <Wire.h>
#include <AccelStepper.h>

#define DIR 12       //TCM2208 DRIVER PIN
#define STP 11       //TCM2208 DRIVER PIN
#define MS2 10       //TCM2208 DRIVER PIN
#define MS1 9        //TCM2208 DRIVER PIN
#define EN 8         //TCM2208 DRIVER PIN
#define P1 7         //PUMP 1 PIN
#define P3 6         //PUMP 3 PIN
#define STIR 5       //STIRRER PIN
#define REDLED 4
#define BLUELED 3
#define TMC2208 1


int DropStep;
int CalibrateSteps = 6400;
int AB = 10000;   //Standby pull back
int PB = 150;
int DropInput;
int FunctionState = 0;
int ReceivedState;
int Speed1 = 3000;
int Speed2 = 500;
int StirValue;


enum {CHECK, RUN, PULLBACK}
StepperState;

boolean ChangeState = false;

int STIRRER = 23;


//-------------------------------------------------------------------------------
AccelStepper stepper = AccelStepper(TMC2208, STP, DIR);

void setup()
{
  Serial.begin(9600); //define a baud rate
  Wire.begin(8);
  Wire.onReceive(ReceiveData);

  stepper.setCurrentPosition(0);
  stepper.setMaxSpeed(3000); 
  stepper.setAcceleration(800);
  StepperState = CHECK; 
  pinMode(EN, OUTPUT);
  digitalWrite(EN, HIGH);
}

void loop() 
{
  StirrerFunction();
  CheckState();

  if (ReceivedState == 1) //BLEED FUNCTION SHOULD BE FASTER CONTINUOS SPEED INSTEAD IT WORKS AT THE LOWER SPEED
  {
    digitalWrite(EN, LOW);
    stepper.setSpeed(-Speed1);
    stepper.runSpeed();
  }
  else
  {
    switch(StepperState)
    {
      case CHECK:
      {
        digitalWrite(EN, HIGH);
        ChangeState = true;
        break;
      }
  
      case RUN:
      {
        stepper.run();
        if (stepper.distanceToGo() == 0)
        {
          stepper.move(PB);
          StepperState = PULLBACK;
        }
        break;
      }
  
      case PULLBACK:
      {
        stepper.run();
        if (stepper.distanceToGo() == 0)
        {
          ChangeState = true;
          StepperState = CHECK;
        }
        break;
      }
    }
  }
}
     
void CheckState()
{
  DropStep = round(CalibrateSteps/DropInput);
  if (ReceivedState == 0)      //OFF
  {
    if (ChangeState)
    {
      stepper.stop();
      stepper.setCurrentPosition(0);
      FunctionState = ReceivedState;
      ChangeState = false;
    }  
  }
  else if (ReceivedState == 2)   //CALIBRATE
  {
    if (ChangeState)
    {
      digitalWrite(EN, LOW);
      stepper.setMaxSpeed(Speed2);
      stepper.setAcceleration(800);
      stepper.move(-CalibrateSteps);
      FunctionState = ReceivedState;
      ChangeState = false;
      StepperState = RUN;
    }
  }
  else if (ReceivedState == 3)   //20 DROP FUNCTION
  {
    if (ChangeState)
    {
      digitalWrite(EN, LOW);
      stepper.setMaxSpeed(Speed2);
      stepper.setAcceleration(800);
      stepper.move(-DropStep*20);
      FunctionState = ReceivedState;
      ChangeState = false;
      StepperState = RUN;
    }
  }
  else if (ReceivedState == 4)   //1 DROP FUNCTION
  {
    if (ChangeState)
    {
      digitalWrite(EN, LOW);
      stepper.setMaxSpeed(Speed2);
      stepper.setAcceleration(800);
      stepper.move(-DropStep);
      FunctionState = ReceivedState;
      ChangeState = false;
      StepperState = RUN;
    }
  }
  else if (ReceivedState == 5)   //STANDBY
  {
    if (ChangeState)
    {
      digitalWrite(EN, LOW);
      stepper.setMaxSpeed(Speed2);
      stepper.setAcceleration(800);
      stepper.move(AB);
      FunctionState = ReceivedState;
      ChangeState = false;
      StepperState = RUN;
    }
  }
  else if (ReceivedState == 6)   //PRIME
  {
    if (ChangeState)
    {
      digitalWrite(EN, LOW);
      int x = AB + (3*DropStep);
      stepper.setMaxSpeed(Speed2);
      stepper.setAcceleration(800);
      stepper.move(-x);
      FunctionState = ReceivedState;
      ChangeState = false;
      StepperState = RUN;
    }
  }
  else
  {
    //DO NOTHING
  }
}

void StirrerFunction()
{
  int PotValue = analogRead(A0);              
  StirValue = map(PotValue, 0, 1023, 0, 255); 
  if (digitalRead(STIRRER) == HIGH)
  {
    analogWrite(STIR, StirValue);
  }
  else
  {
    digitalWrite(STIR, LOW);
  }
}

void ReceiveData(int howMany)
{
  DropInput = Wire.read();
  ReceivedState = Wire.read();
}

Can't upload, sketch will try later