Accelstepper with two motors

Hello everyone,
I would like to run 2 Nema 17 Stepper motors with a CNC Shield and A4998 Drivers. The Steppers are plugged into x- and y-axes. I have found a code that makes both motors run as intended (100 Steps each) (Code below). My goal is to modify this code so at first both run for 100 steps (like in my current programm) then there should be a 10000ms delay and after that only motor A moves an additional 100 steps. Can someone help me modify this Code:

#include <AccelStepper.h>


// for the Arduino Uno + CNC shield V3

#define MOTOR_A_ENABLE_PIN 8
#define MOTOR_A_STEP_PIN 2
#define MOTOR_A_DIR_PIN 5

#define MOTOR_B_ENABLE_PIN 8
#define MOTOR_B_STEP_PIN 3
#define MOTOR_B_DIR_PIN 6




AccelStepper motorA(1, MOTOR_A_STEP_PIN, MOTOR_A_DIR_PIN); 
AccelStepper motorB(1, MOTOR_B_STEP_PIN, MOTOR_B_DIR_PIN); 

void setup()
{
  motorA.setEnablePin(MOTOR_A_ENABLE_PIN);
  motorA.setPinsInverted(false, false, true);
  motorB.setEnablePin(MOTOR_B_ENABLE_PIN);
  motorB.setPinsInverted(false, false, true);
  pinMode(MOTOR_A_ENABLE_PIN, OUTPUT);
  pinMode(MOTOR_B_ENABLE_PIN, OUTPUT);
  motorA.setAcceleration(1000);  
  motorA.move(100);
  //motorA.setMaxSpeed(100);
  

  motorB.setAcceleration(1000); 
  motorB.move(100);
  //motorB.setMaxSpeed(100);
 

  motorA.enableOutputs();
  motorB.enableOutputs();
}

void loop()
{

 motorA.run();
 motorB.run();

}

You say you found this code? How much of the code do you understand? How committed are you to learning to write code yourself?

pmaxd:
Can someone help me modify this Code:

I am happy to try to help but you need to take the first steps (sorry for the pun).

If you post the program that represents your best attempt and tell us in detail what it actually does and what you want it to do that is different it will make it much easier to focus on the parts you need help with rather than wasting time on things that you can do.

Be sure to study the extensive AccelStepper documentation.

...R
Stepper Motor Basics

Hello to both replies,

I have studied the documentation of accelstepper but my very low coding skills prevent me from truly understanding the whole thing.
The program at the top (my best attempt) defines the pins for my stepper motors first (this apparently works fine so no need in modifying this). I do not understand why i have to define the number of steps in the void.setup part of the code and then have to "run" the motor in the loop part.
I really only want a simple code that can do the following example:

motorA move 100 Steps
delay(10000)
motorA move 100 Steps
delay(10000)
motorA move 100 Steps
delay(10000)
motorA move 100 Steps
delay(10000)

motorB move 100 Steps
motorA move -400 Steps
delay(10000)
motorA move 100 steps

and so on. This should all then stop once all steps have been made (not looped)

Currently my program moves both of my steppers 100 steps with an acceleration, that is it. I guess I want to extend the program to add a sequence of more steps.

Ultimately this will be used for a reflectivity setup, where one motor turns the angle of the spectrometer and the othere turns the sample to measure the reflectivity at different angles. The delay in between necessary so the measurement can be done in between.

I would appreciate any kind of tutorial but all I have found is mostly just progress reports barely going into detail on the code.

First, forget the names "setup" and "loop". There is a lot of code that gets included with your sketch in the background to make sure the lines you write work. The microcontroller will run forever as long as it has power, so if it loops to infinity without output, until power is cut, that's fine. Setup is where you could put the code you want to run once. so you could put all the steps you just described into setup, and it would run once, then nothing until power is cut and restored..... That said, each motor has 3 pins, and what does each one do.... I will flesh out your code a bit more and you can fill in the blanks... I got rid of the library, which simply confuses a new programmer by "simplifying" the repeated lines of code into unfamiliar C++ objects...

const byte EnablePin  = 8;// same enable for both motor A and B
const byte MotorAStepPin = 2;
const byte MotorADirectionPin = 5;
const byte MotorBStepPin = 3;
const byte MotorBDirectionPin = 6;

void setup()
{
  // setup your pins
  pinMode(EnablePin, OUTPUT);
  pinMode(MotorAStepPin, OUTPUT);
  pinMode(MotorADirectionPin, OUTPUT);
  pinMode(MotorBStepPin, OUTPUT);
  pinMode(MotorBDirectionPin, OUTPUT);
  digitalWrite(EnablePin, HIGH);//this and the next 4 lines set the initial pin state...
  digitalWrite(MotorAStepPin, HIGH);
  digitalWrite(MotorADirectionPin, HIGH);
  digitalWrite(MotorBStepPin, HIGH);
  digitalWrite(MotorBDirectionPin, HIGH);

  // do this once.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);// more complicated code will be hung on this line so learn to not use delay if you plan to expand this code.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepBClockwise();
  }
  for (unsigned int i = 0; i < 400; i++) {// notice the change in index to accomodate the 400 range... byte has max 0-255
    stepACounterClockwise()();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  // and so on...
}

void loop();// do this ever after.

void stepAClockwise() {
  // digitalWrite() pins HIGH or LOW to step motor A once in a clockwise direction.
}

void stepACounterClockwise() {
  // digitalWrite() pins HIGH or LOW to step motor A once in a counter-clockwise direction.
}

void stepBClockwise() {
  // digitalWrite() pins HIGH or LOW to step motor B once in a clockwise direction.
}

void stepBCounterClockwise() {
  // digitalWrite() pins HIGH or LOW to step motor B once in a counter-clockwise direction.
}

Thank you very much for your response and sorry for my late answer.
I have tried to find the blanks:
Right now I am looking at everything after the void loop part. I tried adding "MotorASetPin, HIGH to the digitalWrite part but I keep getting an error, that stepAclockwise is not defined in the setup part. Could you please give me some more hints, what needs to be added?

Could you please give me some more hints, what needs to be added?

You code. We can't see what you've mangled together.

So I added code after the loop part... I used LOW for the counterclockwise movement, which has been succefull for me before. I am pretty sure I am missing something in the setup part. For example do there need to be pins added to stepAClockwise() and so on? I am getting an error message of that part, that it is not defined.

const byte EnablePin  = 8;// same enable for both motor A and B
const byte MotorAStepPin = 2;
const byte MotorADirectionPin = 5;
const byte MotorBStepPin = 3;
const byte MotorBDirectionPin = 6;

void setup()
{
  // setup your pins
  pinMode(EnablePin, OUTPUT);
  pinMode(MotorAStepPin, OUTPUT);
  pinMode(MotorADirectionPin, OUTPUT);
  pinMode(MotorBStepPin, OUTPUT);
  pinMode(MotorBDirectionPin, OUTPUT);
  digitalWrite(EnablePin, HIGH);//this and the next 4 lines set the initial pin state...
  digitalWrite(MotorAStepPin, HIGH);
  digitalWrite(MotorADirectionPin, HIGH);
  digitalWrite(MotorBStepPin, HIGH);
  digitalWrite(MotorBDirectionPin, HIGH);

  // do this once.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);// more complicated code will be hung on this line so learn to not use delay if you plan to expand this code.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepBClockwise();
  }
  for (unsigned int i = 0; i < 400; i++) {// notice the change in index to accomodate the 400 range... byte has max 0-255
    stepACounterClockwise()();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  // and so on...
}

void loop();// do this ever after.

void stepAClockwise() {
  digitalWrite(MotorAStepPin, HIGH) //pins HIGH or LOW to step motor A once in a clockwise direction.
}

void stepACounterClockwise() {
  digitalWrite(MotorAStepPin, LOW) //pins HIGH or LOW to step motor A once in a counter-clockwise direction.
}

void stepBClockwise() {
  digitalWrite(MotorBStepPin, HIGH) //pins HIGH or LOW to step motor B once in a clockwise direction.
}

void stepBCounterClockwise() {
  digitalWrite(MotorAStepPin, LOW) //pins HIGH or LOW to step motor B once in a counter-clockwise direction.
}
void loop();// do this ever after.

That is a function prototype, not a function definition.

I am getting an error message of that part, that it is not defined.

Don't you think that it would be a good idea to share the error messages?

Before you do that, though, don't you think it might be a good idea to make sure that ALL of your statements that are supposed to end with a semicolon actually do?

This is the error message:
Arduino: 1.8.9 (Windows Store 1.8.21.0) (Windows 10), Board: "Arduino/Genuino Uno"

C:\Users\David\Documents\Arduino\sketch_jun05a\sketch_jun05a.ino: In function 'void setup()':

sketch_jun05a:23:20: error: 'stepAClockwise' was not declared in this scope

stepAClockwise();

^

sketch_jun05a:27:20: error: 'stepAClockwise' was not declared in this scope

stepAClockwise();

^

sketch_jun05a:31:20: error: 'stepAClockwise' was not declared in this scope

stepAClockwise();

^

sketch_jun05a:35:20: error: 'stepAClockwise' was not declared in this scope

stepAClockwise();

^

sketch_jun05a:39:20: error: 'stepBClockwise' was not declared in this scope

stepBClockwise();

^

sketch_jun05a:42:27: error: 'stepACounterClockwise' was not declared in this scope

stepACounterClockwise();

^

sketch_jun05a:46:20: error: 'stepAClockwise' was not declared in this scope

stepAClockwise();

^

C:\Users\David\Documents\Arduino\sketch_jun05a\sketch_jun05a.ino: At global scope:

sketch_jun05a:53:24: error: expected unqualified-id before '{' token

void stepAClockwise(); {

^

sketch_jun05a:57:31: error: expected unqualified-id before '{' token

void stepACounterClockwise(); {

^

sketch_jun05a:61:24: error: expected unqualified-id before '{' token

void stepBClockwise(); {

^

sketch_jun05a:65:31: error: expected unqualified-id before '{' token

void stepBCounterClockwise(); {

^

exit status 1
'stepAClockwise' was not declared in this scope

And added Semicolons:

const byte EnablePin  = 8;// same enable for both motor A and B
const byte MotorAStepPin = 2;
const byte MotorADirectionPin = 5;
const byte MotorBStepPin = 3;
const byte MotorBDirectionPin = 6;

void setup()
{
  // setup your pins
  pinMode(EnablePin, OUTPUT);
  pinMode(MotorAStepPin, OUTPUT);
  pinMode(MotorADirectionPin, OUTPUT);
  pinMode(MotorBStepPin, OUTPUT);
  pinMode(MotorBDirectionPin, OUTPUT);
  digitalWrite(EnablePin, HIGH);//this and the next 4 lines set the initial pin state...
  digitalWrite(MotorAStepPin, HIGH);
  digitalWrite(MotorADirectionPin, HIGH);
  digitalWrite(MotorBStepPin, HIGH);
  digitalWrite(MotorBDirectionPin, HIGH);

  // do this once.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);// more complicated code will be hung on this line so learn to not use delay if you plan to expand this code.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepBClockwise();
  }
  for (unsigned int i = 0; i < 400; i++) {// notice the change in index to accomodate the 400 range... byte has max 0-255
    stepACounterClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  // and so on...
}

void loop();// do this ever after.

void stepAClockwise(); {
  digitalWrite(MotorAStepPin, HIGH); //pins HIGH or LOW to step motor A once in a clockwise direction.
}

void stepACounterClockwise(); {
  digitalWrite(MotorAStepPin, LOW); //pins HIGH or LOW to step motor A once in a counter-clockwise direction.
}

void stepBClockwise(); {
  digitalWrite(MotorBStepPin, HIGH); //pins HIGH or LOW to step motor B once in a clockwise direction.
}

void stepBCounterClockwise(); {
  digitalWrite(MotorAStepPin, LOW); //pins HIGH or LOW to step motor B once in a counter-clockwise direction.
}
void loop();// do this ever after.

That is STILL wrong

void stepAClockwise(); {

That semicolon doesn't belong there, either.

Alright, obviously I am not very skilled at coding. Do you mind telling me why there are no semicolons needed in those places?

const byte EnablePin  = 8;// same enable for both motor A and B
const byte MotorAStepPin = 2;
const byte MotorADirectionPin = 5;
const byte MotorBStepPin = 3;
const byte MotorBDirectionPin = 6;

void setup()
{
  // setup your pins
  pinMode(EnablePin, OUTPUT);
  pinMode(MotorAStepPin, OUTPUT);
  pinMode(MotorADirectionPin, OUTPUT);
  pinMode(MotorBStepPin, OUTPUT);
  pinMode(MotorBDirectionPin, OUTPUT);
  digitalWrite(EnablePin, HIGH);//this and the next 4 lines set the initial pin state...
  digitalWrite(MotorAStepPin, HIGH);
  digitalWrite(MotorADirectionPin, HIGH);
  digitalWrite(MotorBStepPin, HIGH);
  digitalWrite(MotorBDirectionPin, HIGH);

  // do this once.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);// more complicated code will be hung on this line so learn to not use delay if you plan to expand this code.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepBClockwise();
  }
  for (unsigned int i = 0; i < 400; i++) {// notice the change in index to accomodate the 400 range... byte has max 0-255
    stepACounterClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  // and so on...
}

void loop()// do this ever after.

void stepAClockwise() {
  digitalWrite(MotorAStepPin, HIGH); //pins HIGH or LOW to step motor A once in a clockwise direction.
}

void stepACounterClockwise() {
  digitalWrite(MotorAStepPin, LOW); //pins HIGH or LOW to step motor A once in a counter-clockwise direction.
}

void stepBClockwise() {
  digitalWrite(MotorBStepPin, HIGH); //pins HIGH or LOW to step motor B once in a clockwise direction.
}

void stepBCounterClockwise() {
  digitalWrite(MotorAStepPin, LOW); //pins HIGH or LOW to step motor B once in a counter-clockwise direction.
}

Do you mind telling me why there are no semicolons needed in those places?

Because they are functions. You're setup() function does not have a semicolon after the void setup() line or after the { or the }. That should be your model for your functions.

The only exceptions to blocks (functions, blocks after if statements, etc.) not needing semicolons to close are struct and class definition blocks.

void loop()// do this ever after.

Still wrong. loop() MUST have a body, even if it is empty.

I added "{}" to the void loop. And it seems like I am getting somewhere. There are no new error messages, however the steppermotors are not doing anything.

const byte EnablePin  = 8;// same enable for both motor A and B
const byte MotorAStepPin = 2;
const byte MotorADirectionPin = 5;
const byte MotorBStepPin = 3;
const byte MotorBDirectionPin = 6;

void setup()
{
  // setup your pins
  pinMode(EnablePin, OUTPUT);
  pinMode(MotorAStepPin, OUTPUT);
  pinMode(MotorADirectionPin, OUTPUT);
  pinMode(MotorBStepPin, OUTPUT);
  pinMode(MotorBDirectionPin, OUTPUT);
  digitalWrite(EnablePin, HIGH);//this and the next 4 lines set the initial pin state...
  digitalWrite(MotorAStepPin, HIGH);
  digitalWrite(MotorADirectionPin, HIGH);
  digitalWrite(MotorBStepPin, HIGH);
  digitalWrite(MotorBDirectionPin, HIGH);

  // do this once.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);// more complicated code will be hung on this line so learn to not use delay if you plan to expand this code.
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepBClockwise();
  }
  for (unsigned int i = 0; i < 400; i++) {// notice the change in index to accomodate the 400 range... byte has max 0-255
    stepACounterClockwise();
  }
  delay(10000);
  for (byte i = 0; i < 100; i++) {
    stepAClockwise();
  }
  // and so on...
}

void loop(){}// do this ever after.

void stepAClockwise() {
  digitalWrite(MotorAStepPin, HIGH); //pins HIGH or LOW to step motor A once in a clockwise direction.
}

void stepACounterClockwise() {
  digitalWrite(MotorAStepPin, LOW); //pins HIGH or LOW to step motor A once in a counter-clockwise direction.
}

void stepBClockwise() {
  digitalWrite(MotorBStepPin, HIGH); //pins HIGH or LOW to step motor B once in a clockwise direction.
}

void stepBCounterClockwise() {
  digitalWrite(MotorAStepPin, LOW); //pins HIGH or LOW to step motor B once in a counter-clockwise direction.
}

You make a stepper step by setting the step pin HIGH then LOW. It won't step until the pin goes LOW.

Concentrate on getting ONE function working, before you try to make multiple motors go both ways.

Why are you not using a library that handles all this for you?

Well I did start out with the accelstepper library (first post) but was told to switch

pmaxd:
Well I did start out with the accelstepper library (first post) but was told to switch

Which reply was that advice in?

...R

Post number 4 where somebody started the code I have been working on the last posts. I think however I am going back to the original program because at least the motors work:

#include <AccelStepper.h>


// for the Arduino Uno + CNC shield V3

#define MOTOR_A_ENABLE_PIN 8
#define MOTOR_A_STEP_PIN 2
#define MOTOR_A_DIR_PIN 5

#define MOTOR_B_ENABLE_PIN 8
#define MOTOR_B_STEP_PIN 3
#define MOTOR_B_DIR_PIN 6




AccelStepper motorA(1, MOTOR_A_STEP_PIN, MOTOR_A_DIR_PIN); 
AccelStepper motorB(1, MOTOR_B_STEP_PIN, MOTOR_B_DIR_PIN); 

void setup()
{
  motorA.setEnablePin(MOTOR_A_ENABLE_PIN);
  motorA.setPinsInverted(false, false, true);
  motorB.setEnablePin(MOTOR_B_ENABLE_PIN);
  motorB.setPinsInverted(false, false, true);
  pinMode(MOTOR_A_ENABLE_PIN, OUTPUT);
  pinMode(MOTOR_B_ENABLE_PIN, OUTPUT);
  motorA.setAcceleration(1000);  
  motorA.move(1000);
  //motorA.setMaxSpeed(100);
  

  motorB.setAcceleration(1000); 
  motorB.move(1000);
  //motorB.setMaxSpeed(100);
 

  motorA.enableOutputs();
  motorB.enableOutputs();
}

void loop()
{

 motorA.run();
 motorB.run();
 

}

With this code both my motors move the intended 1000 steps. I have been trying to add more steps so I can get a program that does a sequence of steps like described earlier. Where would I have to define that? Setup or Loop?

Stepper motor is driven by a number of wire and each step was made after a change in the wire configuration.
I do not know your kind of motor, but usually they has 4 wire and each combination of UP and DOWN of wires correspond to a specific movement of the shaft, in one of 4 possible steps. To move the shaft you need to know the actual step and change wires configuration to move to the adiacent step.

See this code:

    // definisco quale è la posizione corrente e quindi qualìè quella successiva
    PassoCorrente = PassoCorrente + p;
    if (PassoCorrente >= 4) {
      PassoCorrente=PassoCorrente-4;
      }  
    if (PassoCorrente < 0) {
      PassoCorrente=PassoCorrente+4;
      }
     switch (PassoCorrente) {   
        case 0:  // 1010
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          digitalWrite(motor_pin_3, HIGH);
          digitalWrite(motor_pin_4, LOW);
        break;
        case 1:  // 0110
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          digitalWrite(motor_pin_3, HIGH);
          digitalWrite(motor_pin_4, LOW);
        break;
        case 2:  //0101
          digitalWrite(motor_pin_1, LOW);
          digitalWrite(motor_pin_2, HIGH);
          digitalWrite(motor_pin_3, LOW);
          digitalWrite(motor_pin_4, HIGH);
        break;
        case 3:  //1001
          digitalWrite(motor_pin_1, HIGH);
          digitalWrite(motor_pin_2, LOW);
          digitalWrite(motor_pin_3, LOW);
          digitalWrite(motor_pin_4, HIGH);
        break;
      }

In first section, variable PassoCorrente contain the number that identify actual position (0,1,2 or 3), variable "p" define what motor should do: 0=no action, 1=step forward, -1=step backward.
First two "if" statement allow to restart from 0 if PassoCorrente become greater then 3 and restart from 3 if PassoCorrente become less then 0.

the "switch" structures match the PassoCorrente value and set correct configuration for wires.

This routine make one step at time, so you need to call this routine many times from your main routine to have the correct shaft movement.

If you do not want to drive your motor in this way, you can use some library but you have to read its instruction.

Carlo

pmaxd:
Post number 4 where somebody started the code I have been working on the last posts.

My reading of Reply #4 is that it shows another way of doing things but I see no evidence that it recommended against the well-established AccelStepper library.

It is much more productive to stick with one approach until you get it to work rather than chopping and changing and getting twice as confused.

Which version you wish to stick with is up to you.

And please note that the code in Reply #18 is NOT appropriate for an A4988 stepper driver.

...R