How to modify the code for stepper motor control , make it simpler.

I have following code, which move stepper motor to 4 positions, how to modify the code for stepper motor control , make it simpler. i.e. only let code run based on the motor data table:
(use Array??)

Steps Dir Delay(After that position)

Position1 125 HIGH 1000
Position2 225 LOW 1800
Position3 325 HIGH 1200
Position4 208 HIGH 900

Thank!

Current Code:

int pushbuttonpin =7;            //Pin for momentary push button switch or sensor
int val = 0;                    //Integer for reading push button switch status
int dirpin = 3;                 //pin for DIR
int steppin = 2;                //pin for STEP

void setup()
{
  Serial.begin(9600);
   pinMode(pushbuttonpin, INPUT);     //Declare push button switch pin as input
   pinMode(dirpin, OUTPUT);           //Declare dirpin as output
   pinMode(steppin, OUTPUT);          //Declare steppin as output
 }
 void loop()
{
  int i; 
  val = digitalRead(pushbuttonpin);   //Read push button switch pin status
  if (val == HIGH)
    { 
     digitalWrite(dirpin, HIGH);   // Set the direction pin to move forward
     delay(500);                     //Give it some time

      for (i = 0; i<125; i++)         // Step Forward 125 steps
        {
          digitalWrite(steppin, LOW);      // Start out with step pin low
          delayMicroseconds(3000);          // Delay controls speed and Torque. 
          digitalWrite(steppin, HIGH);     // Now switch it high
          delayMicroseconds(3000);          // Delay controls speed and Torque you need at least a 680 delay
        }
   
   //----------------------------------------------------------------------------------------------------------
   delay(1000); //stop at 1st. position for a while
   //----------------------------------------------------------------------------------------------------------
     
     digitalWrite(dirpin, LOW);
     delay(500); 
      for (i = 0; i<225; i++)         // Step Backward to position #2
        {
          digitalWrite(steppin, LOW);      
          delayMicroseconds(3000);          
          digitalWrite(steppin, HIGH);     
          delayMicroseconds(3000);          
        }
   
   //----------------------------------------------------------------------------------------------------------
   delay(1800); //stop at 2nd. position for a while
   //----------------------------------------------------------------------------------------------------------
      digitalWrite(dirpin, HIGH);
     delay(500); 
      for (i = 0; i<325; i++)         // Step Forward to position #3
        {
          digitalWrite(steppin, LOW);      
          delayMicroseconds(3000);          
          digitalWrite(steppin, HIGH);     
          delayMicroseconds(3000);          
        }
   
   //----------------------------------------------------------------------------------------------------------
   delay(1200); //stop at 3rd. position for a while
   //----------------------------------------------------------------------------------------------------------  
       digitalWrite(dirpin, HIGH);
     delay(500); 
      for (i = 0; i<208; i++)         // Step Forward to position #4
        {
          digitalWrite(steppin, LOW);      
          delayMicroseconds(3000);          
          digitalWrite(steppin, HIGH);     
          delayMicroseconds(3000);          
        }
   
   //----------------------------------------------------------------------------------------------------------
   delay(900); //stop at 4th. position for a while
   //---------------------------------------------------------------------------------------------------------- 
      
   
    } 
}

Please edit your post and add code tags around the code part

type
** **[code]** **
before the code
type
** **[/code]** **
after the code

And read the how to use this forum" sticky.

Tables translate to either classes or structs; below example code using a struct.

Define a struct first that contains the information that you need; the below has one extra member for the delay while moving the stepper (not sure if it’s useful).

struct POSITION
{
  int startposition;
  int endposition;
  unsigned long positiondelay;  // position delay in us
};

And next declare an array of positions

POSITION positions[] =
{
  {0, 33, 1000},
  {34, 66, 2000},
  {66, 99, 1000},
  {99, 255, 1000},
};

Next you can write a function for the moving

/*
  move stepper
  IN:
    index in position array
*/
void move(int index)
{
  for (int stepCnt = positions[index].startposition; stepCnt < positions[index].endposition; stepCnt++)
  {
    digitalWrite(steppin, LOW);
    delayMicroseconds(3000);
    digitalWrite(steppin, HIGH);
    delayMicroseconds(3000);
  }

  delay(positions[index].positiondelay);
}

And you can call the function in loop()

void loop()
{
  // which step
  static int step = 0;
  // move
  move(step++);

  // if all steps done, start from beginning
  if (step == sizeof(positions) / sizeof(positions[0]))
  {
    step = 0;
  }
}

You can add extra variables to the struct, e.g. the delay that you use in the for loop (according to your comment in the code it controls the torque).

sterretje:

/*

void move(int index)
{
  for (int stepCnt = positions[index].startposition; stepCnt < positions[index].endposition; stepCnt++)
  {

That looks suspiciously like a blocking move!

How can the advocate of structs be recommending that ? :slight_smile:

…R

Simple :smiley: I know nothing about servos and how critical their timing is :slight_smile:

sterretje, your idea is very helpful, I changed my original code, many errors, Could you help me?

Thank you very much!

int pushbuttonpin =7;            //Pin for momentary push button switch or sensor
 int val = 0;                    //Integer for reading push button switch status
 int dirpin = 3;                 //pin for DIR
 int steppin = 2;                //pin for STEP
 //-------------------------------------------------------------------
struct POSITION
{
  int steps;
  int dirs;
  unsigned long positiondelay;  // position delay in us
}

POSITION positions[] =
{
  {125,HIGH,1000},
  {225,LOW,1800},
  {325,HIGH,1200},
  {208,HIGH,900},
}
 
 void setup()
 {
   Serial.begin(9600);
    pinMode(pushbuttonpin, INPUT);     //Declare push button switch pin as input
    pinMode(dirpin, OUTPUT);           //Declare dirpin as output
    pinMode(steppin, OUTPUT);          //Declare steppin as output
  }

  
  void loop()
 {
   int i; 
   val = digitalRead(pushbuttonpin);   //Read push button switch pin status
   if (val == HIGH)

   
     { 
      digitalWrite(dirpin, dirs);   // Set the direction pin to move forward or backward
      delay(500);                     //Give it some time

       for (i = 0; i<steps; i++)         
         {
           digitalWrite(steppin, LOW);      // Start out with step pin low
           delayMicroseconds(3000);          // Delay controls speed and Torque. 
           digitalWrite(steppin, HIGH);     // Now switch it high
           delayMicroseconds(3000);          // Delay controls speed and Torque you need at least a 680 delay
         }
    
    //----------------------------------------------------------------------------------------------------------
    delay(positiondelay); //stop at the position for a while
    //----------------------------------------------------------------------------------------------------------
      
     
    digitalWrite(dirpin, LOW);         //Change direction to reverse & back to home position
      delay(500); 
       for (i = 0; i<1300; i++)         // Step  to home position
         {
           digitalWrite(steppin, LOW);      
           delayMicroseconds(3000);          
           digitalWrite(steppin, HIGH);     
           delayMicroseconds(3000);          
         }
    //---------------------------------------------------------------------------------------------------------- 
    
     } 
 }

You should post your errors. Anyway, you're missing two semicolons and 'dirs', 'positiondelay' and 'steps' are not variables that you can use directly (they are part of the struct).

Further the 'positions' variable is an array (of structs) so you need to indicate an array element first and next the variable inside that element; look at how I did it in the move() function.

You also do not seem to grasp the idea. Your loop() code still contains all steps while my suggested code only calls one function; I did overlook the direction in your original code though.

Hi sterretje, Thank u for your info.

Since stepper motor is open-loop, just need Steps & Dir, Why do you use startposition & endposition?

I assume a misunderstanding from my side.

Richard905:
Steps Dir Delay(After that position)

Position1 125 HIGH 1000
Position2 225 LOW 1800
Position3 325 HIGH 1200
Position4 208 HIGH 900

If you use the Stepper library you can simplify your code to:

    stepper.step(125);
    delay(1000);
    stepper.step(-225);  // Negative number for reverse stepping
    delay(1800);
    stepper.step(325);
    delay(1200);
    stepper.step(208);
    delay(900);

johnwasser:
If you use the Stepper library you can simplify your code to:

    stepper.step(125);

delay(1000);
    stepper.step(-225);  // Negative number for reverse stepping
    delay(1800);
    stepper.step(325);
    delay(1200);
    stepper.step(208);
    delay(900);

johnwasser: The reason I want to use "Array" : Stepper Motor could move 100 and more positions, code will be very long!

Richard905:
Since stepper motor is open-loop, just need Steps & Dir, Why do you use startposition & endposition?

If you are referring to this line of code from Reply #2

for (int stepCnt = positions[index].startposition; stepCnt < positions[index].endposition; stepCnt++)

the start and end positions are just used to determine the number of steps

If you simply store the number of steps in your struct then that line could be

for (int stepCnt = 0; stepCnt < positions[index].numSteps; stepCnt++)

I mentioned in Reply #3 that using FOR causes the Arduino to be blocked until the FOR completes. The concept of using a struct could easily be used with the non-blocking movement in the second example in this Simple Stepper Code

…R
Stepper Motor Basics

Richard905:
johnwasser: The reason I want to use "Array" : Stepper Motor could move 100 and more positions, code will be very long!

Sorry. I thought you just wanted 'simpler'. You already have examples of using arrays. You can simplify those examples by using the Stepper library. You won't need to store 'Direction' since the sign of the number of steps selects direction. Each movement has just 'steps' and 'delay'.

Hi sterretje: I decided to give up my original code, the following code is based on yours, it passed & run.
{0, 1000, 1000},
{1000, 2000, 1000},
{2000, 1000, 1000},
{1000, 2000, 1000},
The 3rd step should be reverse? but didn’t, run on direction only, loop will not end.

By the way, I need use one momentary switch to trigger the cycle, the stop until push the switch again.
I want add " val = digitalRead(pushbuttonpin); //Read push button switch pin status
if (val == HIGH)" , Where should I add in your code.(tried different places, no luck).

Thanks!

int pushbuttonpin =7;            //Pin for momentary push button switch or sensor
int val = 0;                    //Integer for reading push button switch status
int dirpin = 3;                 //pin for DIR
int steppin = 2;                //pin for STEP

void setup()
{
  Serial.begin(9600);
   pinMode(pushbuttonpin, INPUT);     //Declare push button switch pin as input
   pinMode(dirpin, OUTPUT);           //Declare dirpin as output
   pinMode(steppin, OUTPUT);          //Declare steppin as output
 }


struct POSITION
{
  int startposition;
  int endposition;
  unsigned long positiondelay;  // position delay in us
};

POSITION positions[] =
{
  {0, 1000, 1000},
  {1000, 2000, 1000},
  {2000, 1000, 1000},
  {1000, 2000, 1000},
};

/*
  move stepper
  IN:
    index in position array
*/
void move(int index)
  {
  
  for (int stepCnt = positions[index].startposition; stepCnt < positions[index].endposition; stepCnt++)
  {
    digitalWrite(steppin, LOW);
    delayMicroseconds(3000);
    digitalWrite(steppin, HIGH);
    delayMicroseconds(3000);
  }

  delay(positions[index].positiondelay);
}

void loop()
{
  // which step
  static int step = 0;
  // move
  move(step++);

  // if all steps done, start from beginning
  if (step == sizeof(positions) / sizeof(positions[0]))
  {
    step = 0;
  }
}

Richard905:
The 3rd step should be reverse? but didn’t, run on direction only, loop will not end.

You have no code to test for that or to operate the direction pin

You need to do that before the FOR loop.

…R

[coce]

int pushbuttonpin = 7;           //Pin for momentary push button switch or sensor
int val = 0;                    //Integer for reading push button switch status
int dirpin = 3;                 //pin for DIR
int steppin = 2;                //pin for STEP

void setup()
{
  Serial.begin(9600);
  pinMode(pushbuttonpin, INPUT);     //Declare push button switch pin as input
  pinMode(dirpin, OUTPUT);           //Declare dirpin as output
  pinMode(steppin, OUTPUT);          //Declare steppin as output
}


struct POSITION
{
  unsigned steps;
  boolean direction;
  unsigned long positiondelay;  // position delay in us
};

POSITION positions[] =
{
  {125,      HIGH,              1000},
  {225,      LOW,               1800},
  {325,      HIGH,               1200},
  {208,      HIGH,               900}
};

/*
  move stepper
  IN:
    index in position array
*/
void move(struct POSITION &position) {
  digitalWrite(dirpin, position.direction);
  for (unsigned step = 0; step < position.steps; step++) {
    digitalWrite(steppin, LOW);
    delayMicroseconds(3000);
    digitalWrite(steppin, HIGH);
    delayMicroseconds(3000);
  }

  delay(position.positiondelay);
}

void loop() {
  // which step
  static unsigned step = 0;
  // move
  move(positions[step++]);

  // if all steps done, start from beginning
  if (step == sizeof(positions) / sizeof(positions[0])) {
    step = 0;
  }
}

Added pushbutton.

int pushbuttonpin = 7;           //Pin for momentary push button switch or sensor
int dirpin = 3;                 //pin for DIR
int steppin = 2;                //pin for STEP

struct POSITION {
  unsigned steps;
  boolean direction;
  unsigned long positiondelay;  // position delay in us
};

POSITION positions[] = {
  {125,      HIGH,              1000},
  {225,      LOW,               1800},
  {325,      HIGH,               1200},
  {208,      HIGH,               900}
};

void setup() {
  Serial.begin(9600);
  pinMode(pushbuttonpin, INPUT);     //Declare push button switch pin as input
  pinMode(dirpin, OUTPUT);           //Declare dirpin as output
  pinMode(steppin, OUTPUT);          //Declare steppin as output
}

void loop() {
  // Calculate the number of steps in the array
  unsigned stepCount = sizeof positions / sizeof positions[0];

  if (digitalRead(pushbuttonpin)) {
    long totalSteps = 0;

    // Run a full cycle
    for (unsigned step = 0; step < stepCount; step++) {
      struct POSITION &position = positions[step];
      
      if (position.direction)
        totalSteps += position.steps;  // direction == HIGH, move in + direction
      else
        totalSteps -= position.steps;  // direction == LOW, move in - direction

      digitalWrite(dirpin, position.direction);

      for (unsigned i = 0; i < position.steps; i++) {
        digitalWrite(steppin, LOW);
        delayMicroseconds(3000);
        digitalWrite(steppin, HIGH);
        delayMicroseconds(3000);
      } // end for(i)

      delay(position.positiondelay);
    } // end for(step)

    // Cycle is done so Now move back to the initial position
    if (totalSteps != 0) {  // No need to move.  We're already there!
      if (totalSteps > 0) {
        digitalWrite(dirpin, LOW);  // More HIGH than LOW so go in LOW direction
      } else {
        digitalWrite(dirpin, HIGH);  // More LOW than HIGH so go in HIGH direction
        totalSteps = -totalSteps;  // Make totalSteps positive.
      }
      // Move to the initial position
      for (long i = 0; i < totalSteps; i++) {
        digitalWrite(steppin, LOW);
        delayMicroseconds(3000);
        digitalWrite(steppin, HIGH);
        delayMicroseconds(3000);
      } // end for(i)
    }
  }  // end if(button)
}

johnwasser:
Added pushbutton.

int pushbuttonpin = 7;           //Pin for momentary push button switch or sensor

int dirpin = 3;                //pin for DIR
int steppin = 2;                //pin for STEP

struct POSITION {
  unsigned steps;
  boolean direction;
  unsigned long positiondelay;  // position delay in us
};

POSITION positions = {
  {125,      HIGH,              1000},
  {225,      LOW,              1800},
  {325,      HIGH,              1200},
  {208,      HIGH,              900}
};

void setup() {
  Serial.begin(9600);
  pinMode(pushbuttonpin, INPUT);    //Declare push button switch pin as input
  pinMode(dirpin, OUTPUT);          //Declare dirpin as output
  pinMode(steppin, OUTPUT);          //Declare steppin as output
}

void loop() {
  // Calculate the number of steps in the array
  unsigned stepCount = sizeof positions / sizeof positions[0];

if (digitalRead(pushbuttonpin)) {
    long totalSteps = 0;

// Run a full cycle
    for (unsigned step = 0; step < stepCount; step++) {
      struct POSITION &position = positions[step];
     
      if (position.direction)
        totalSteps += position.steps;  // direction == HIGH, move in + direction
      else
        totalSteps -= position.steps;  // direction == LOW, move in - direction

digitalWrite(dirpin, position.direction);

for (unsigned i = 0; i < position.steps; i++) {
        digitalWrite(steppin, LOW);
        delayMicroseconds(3000);
        digitalWrite(steppin, HIGH);
        delayMicroseconds(3000);
      } // end for(i)

delay(position.positiondelay);
    } // end for(step)

// Cycle is done so Now move back to the initial position
    if (totalSteps != 0) {  // No need to move.  We’re already there!
      if (totalSteps > 0) {
        digitalWrite(dirpin, LOW);  // More HIGH than LOW so go in LOW direction
      } else {
        digitalWrite(dirpin, HIGH);  // More LOW than HIGH so go in HIGH direction
        totalSteps = -totalSteps;  // Make totalSteps positive.
      }
      // Move to the initial position
      for (long i = 0; i < totalSteps; i++) {
        digitalWrite(steppin, LOW);
        delayMicroseconds(3000);
        digitalWrite(steppin, HIGH);
        delayMicroseconds(3000);
      } // end for(i)
    }
  }  // end if(button)
}

johnwasser: above code works great! if I want to use same array control two stepper motor, of course, they don’t run at the same time.

int dirpin = 3; //pin for DIR of Stepper Motor “A”
int steppin = 2; //pin for STEP of Stepper Motor “A”
int dirpin = 5; //pin for DIR of Stepper Motor “B”
int steppin = 4; //pin for STEP of Stepper Motor “B”

POSITION positions = {
{125, HIGH, 1000}, // Stepper Motor “A” rotates
{225, LOW, 1800}, // Stepper Motor “B” rotates
{325, HIGH, 1200}, // Stepper Motor “B” rotates
{208, HIGH, 900} // Stepper Motor “A” rotates
};

How to modify the code? (don’t need move to the initial position)

Thanks again!

I would start by adding an entry in the structure for which motor to turn.