user71215: I'm very new to arduino and have to work on a project for school. We have connected 3 motors (Servo, Stepper (180 degrees) and a DC motor) to an Arduino Uno, Adafruit motorshield and a pcb. With the pcb we were able to record values of the motors individually and use these values to create a playback motion. The code which we got for the playback motion is below (I've already filled in my values for the 3 motors).
This is what I want to do with the motors:
When I press a button I want to 'start' the cycle of motor motions

first the dc motor starts doing the motion based on the chosen values
When this stops after 5 seconds I want the servo motor to do it's motion
When the servo motor is done, I want the stepper motor to start doing the motion based on the chosen values for 5 seconds and then stop.

We were told not to use a delay and someone suggested to use millis() instead of delay() but since I am a beginner I have no idea where to start.
This is the code:
// With this code it is possible to play back recorded motion paths for for motors connected to the Adafruit motorshield

#include <AccelStepper.h>
#include <Wire.h>
#include <Adafruit_MotorShield.h>
#include <Servo.h> // this is a library that allows you to drive servo's.

// variables
int modeChoice = 0;

int buttons = A2;  // the three buttons share an analog pin, resitors provide different levels that point to which button is pressed
int slide = A1;    // the slide is read through one analog pin, resitors provide different levels that point to which slide position is current
int rotation = A0; // the pin for the potentiometer

int buttonPressed = 0; // a variable to remember which button is pressed, it is used to control leds and motion memory position management

int buttonValRaw = 0; // a variable to store the raw analog reading of the buttons pin
int slideValRaw = 0;  // a variable to sore the raw analog reading of the slide pin
int valButton = 0;    // a variable to store the interpreted value, the exact pointer to a button
int valSlide = 0;     // a variable to store the interpreted value, the exact pointer to a slide position
int idleState = 0;    // a variable to toggle the servo idle behavior
int resetMotion = 0;  // a variable to return the arrayPosition to 0 if a button is pushed so that the behaviour starts at the beginning
int motionVar1;       // a variable to hold a motion position
int motionVar2;       // another variable to hold a motion position

int mySensorArray[20];  // an array with 20 slots to store raw potentiometer readings (for filtering)
int sensorArrayPos = 0; // the array position of interest.



//////////////////////////////////////

int servoMotionArray_B1[50] = {95, 95, 95, 95, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // paste your 50 values in between the brackets

int DCMotionArray_B1[50] = {-85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85};

//recorded motions for position implementation
int StepperMotionArray_B1[50] = {-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200};

//////////////////////////////////////




int arrayPosition = 0;

unsigned long mainTimer = 0; // a variable to time recording and playback
int timeBetweenSamples = 100; // the time between samples.

unsigned long debounceTimer = 0; // a variable to control a timer interval for debouncing of the buttons
int lastValButton = 0; // a variable to help debouncing of the buttons
int debounceFlag = 0; // another variabel to help debouncing of the buttons



// Setup motors
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 16 steps per revolution (2048 positions) to motor port #1 (M1 and M2) -- you need to change this if your stepper is on port #2
Adafruit_StepperMotor *myStepper = AFMS.getStepper(16, 1);
// And connect a DC motor to port M3 -- you need to change this if your DC is on a different port
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);

Servo myservo1;   // servo object (employs the servo library that was included above)

// these are dedicated functions to make the steppermotor move
void forwardstep1() {
  myStepper->onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper->onestep(BACKWARD, SINGLE);
}

//create aStepper object
AccelStepper aStepper(forwardstep1, backwardstep1); // use functions to step


// setup
void setup() {
  Serial.begin(9600); // start serial communication with 9600 baud rate


  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

  myservo1.attach(9); // attach servo object to pin 9

  // turn on motor M3
  myMotor->setSpeed(0);
  myMotor->run(RELEASE);

  // setup the stepper
  aStepper.setSpeed(0); // this is used in the 'speed' implementation

  aStepper.setMaxSpeed(200.0); // these are used in the 'position' implementation
  aStepper.setAcceleration(100.0);
  aStepper.moveTo(0);

  // synchronize the first timer cycle -- because the timer is starting at zero it generates negative values in the first 100 miliseconds after starting up when going through the timer cycle, creating potential erratic bahaviour-- giving it a delay at the end of the setup loop will eradicate this behaviour
  delay(1000);
}

void doButtons() {
  if (buttonPressed != 0) {
    return;
  }
  else {
    buttonValRaw = analogRead(buttons);
    valButton = map (buttonValRaw, 49, 605, 0, 5);
    int localButtonVal = valButton;

    if (valButton > 7) {
      return;
    }

    if (debounceFlag == 0) {
      debounceTimer = millis();
      debounceFlag = 1;
    }

    if (debounceTimer < millis() - 20) {

      buttonValRaw = analogRead(buttons);
      valButton = map (buttonValRaw, 49, 605, 0, 5);

      if (valButton == localButtonVal) {
        debounceFlag = 0;

        switch (valButton) {
          case 1:
            buttonPressed = 1;
            break;
          case 2:
            buttonPressed = 2;
            break;
          case 3:
            buttonPressed = 3;
            break;
          default:
            buttonPressed = 0;
            break;
        }
      }
    }
  }
}

void loop() {
  doButtons(); // this uses the buttons from the PCB, if you use your own implementation you need to reprogram this function

  if (mainTimer < millis() - timeBetweenSamples) { // sampling only once per interval.
    mainTimer = millis(); // time is rewritten to current millis starting a new interval.

    if (buttonPressed == 0) { //'idle play'
      if (idleState == 0) {
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      else if (idleState == 1){
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      motionVar2 = DCMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      if (motionVar2 < 0) {
        myMotor->run(BACKWARD);
        myMotor->setSpeed(abs(motionVar2));
      }
      else if (motionVar2 >= 0) {
        myMotor->run(FORWARD);
        myMotor->setSpeed(motionVar2);
      }
      arrayPosition++;
      if (arrayPosition > 49) {
        arrayPosition = 0;
        idleState = !idleState;
      }
    }

    if (buttonPressed == 1) { //2nd behaviour
      if (resetMotion == 0) {
        arrayPosition = 0;
        resetMotion = 1;
        myMotor->run(RELEASE); // release the DC motor, otherwise it will continue spinning at the last known RPM
      }
      motionVar1 = servoMotionArray_B3[arrayPosition];
      motionVar2 = StepperMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      aStepper.moveTo(motionVar2);
      arrayPosition++;
      if (arrayPosition > 49) {
        arrayPosition = 0;
        buttonPressed = 0;
        resetMotion = 0;
      }
    }
  }



  // one of these needs to be called to make the stepper motor work, comment out the one you do not need (position or speed)
  //aStepper.run(); //stepper position implementation
  aStepper.runSpeed(); //stepper speed implementation

}


user16780: You're almost correct already:
if (millis() - mainTimer >= timeBetweenSamples) {
  mainTimer = millis(); 
  // executing only once per interval.

  ... the action for current arrayPosition ...

  arrayPosition++;
  if (arrayPosition > 49) {
     arrayPosition = 0;
     buttonPressed = 0; // Show ends
  }   
}


71215: <p>I'm very new to arduino and have to work on a project for school. We have connected 3 motors (Servo, Stepper (180 degrees) and a DC motor) to an Arduino Uno, Adafruit motorshield and a pcb. With the pcb we were able to record values of the motors individually and use these values to create a playback motion. The code which we got for the playback motion is below (I've already filled in my values for the 3 motors).</p>
<p>This is what I want to do with the motors:</p>
<p>When I press a button I want to 'start' the cycle of motor motions</p>
<ol>
<li>first the dc motor starts doing the motion based on the chosen values</li>
<li>When this stops after 5 seconds I want the servo motor to do it's motion</li>
<li>When the servo motor is done, I want the stepper motor to start doing the motion based on the chosen values for 5 seconds and then stop.</li>
</ol>
<p>We were told not to use a delay and someone suggested to use millis() instead of delay() but since I am a beginner I have no idea where to start.</p>
<p>This is the code:</p>
<pre><code>// With this code it is possible to play back recorded motion paths for for motors connected to the Adafruit motorshield

#include &lt;AccelStepper.h&gt;
#include &lt;Wire.h&gt;
#include &lt;Adafruit_MotorShield.h&gt;
#include &lt;Servo.h&gt; // this is a library that allows you to drive servo's.

// variables
int modeChoice = 0;

int buttons = A2;  // the three buttons share an analog pin, resitors provide different levels that point to which button is pressed
int slide = A1;    // the slide is read through one analog pin, resitors provide different levels that point to which slide position is current
int rotation = A0; // the pin for the potentiometer

int buttonPressed = 0; // a variable to remember which button is pressed, it is used to control leds and motion memory position management

int buttonValRaw = 0; // a variable to store the raw analog reading of the buttons pin
int slideValRaw = 0;  // a variable to sore the raw analog reading of the slide pin
int valButton = 0;    // a variable to store the interpreted value, the exact pointer to a button
int valSlide = 0;     // a variable to store the interpreted value, the exact pointer to a slide position
int idleState = 0;    // a variable to toggle the servo idle behavior
int resetMotion = 0;  // a variable to return the arrayPosition to 0 if a button is pushed so that the behaviour starts at the beginning
int motionVar1;       // a variable to hold a motion position
int motionVar2;       // another variable to hold a motion position

int mySensorArray[20];  // an array with 20 slots to store raw potentiometer readings (for filtering)
int sensorArrayPos = 0; // the array position of interest.



//////////////////////////////////////

int servoMotionArray_B1[50] = {95, 95, 95, 95, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; // paste your 50 values in between the brackets

int DCMotionArray_B1[50] = {-85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85, -85};

//recorded motions for position implementation
int StepperMotionArray_B1[50] = {-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200,-200};

//////////////////////////////////////




int arrayPosition = 0;

unsigned long mainTimer = 0; // a variable to time recording and playback
int timeBetweenSamples = 100; // the time between samples.

unsigned long debounceTimer = 0; // a variable to control a timer interval for debouncing of the buttons
int lastValButton = 0; // a variable to help debouncing of the buttons
int debounceFlag = 0; // another variabel to help debouncing of the buttons



// Setup motors
// Create the motor shield object with the default I2C address
Adafruit_MotorShield AFMS = Adafruit_MotorShield();
// Connect a stepper motor with 16 steps per revolution (2048 positions) to motor port #1 (M1 and M2) -- you need to change this if your stepper is on port #2
Adafruit_StepperMotor *myStepper = AFMS.getStepper(16, 1);
// And connect a DC motor to port M3 -- you need to change this if your DC is on a different port
Adafruit_DCMotor *myMotor = AFMS.getMotor(3);

Servo myservo1;   // servo object (employs the servo library that was included above)

// these are dedicated functions to make the steppermotor move
void forwardstep1() {
  myStepper-&gt;onestep(FORWARD, SINGLE);
}
void backwardstep1() {
  myStepper-&gt;onestep(BACKWARD, SINGLE);
}

//create aStepper object
AccelStepper aStepper(forwardstep1, backwardstep1); // use functions to step


// setup
void setup() {
  Serial.begin(9600); // start serial communication with 9600 baud rate


  AFMS.begin();  // create with the default frequency 1.6KHz
  //AFMS.begin(1000);  // OR with a different frequency, say 1KHz

  myservo1.attach(9); // attach servo object to pin 9

  // turn on motor M3
  myMotor-&gt;setSpeed(0);
  myMotor-&gt;run(RELEASE);

  // setup the stepper
  aStepper.setSpeed(0); // this is used in the 'speed' implementation

  aStepper.setMaxSpeed(200.0); // these are used in the 'position' implementation
  aStepper.setAcceleration(100.0);
  aStepper.moveTo(0);

  // synchronize the first timer cycle -- because the timer is starting at zero it generates negative values in the first 100 miliseconds after starting up when going through the timer cycle, creating potential erratic bahaviour-- giving it a delay at the end of the setup loop will eradicate this behaviour
  delay(1000);
}

void doButtons() {
  if (buttonPressed != 0) {
    return;
  }
  else {
    buttonValRaw = analogRead(buttons);
    valButton = map (buttonValRaw, 49, 605, 0, 5);
    int localButtonVal = valButton;

    if (valButton &gt; 7) {
      return;
    }

    if (debounceFlag == 0) {
      debounceTimer = millis();
      debounceFlag = 1;
    }

    if (debounceTimer &lt; millis() - 20) {

      buttonValRaw = analogRead(buttons);
      valButton = map (buttonValRaw, 49, 605, 0, 5);

      if (valButton == localButtonVal) {
        debounceFlag = 0;

        switch (valButton) {
          case 1:
            buttonPressed = 1;
            break;
          case 2:
            buttonPressed = 2;
            break;
          case 3:
            buttonPressed = 3;
            break;
          default:
            buttonPressed = 0;
            break;
        }
      }
    }
  }
}

void loop() {
  doButtons(); // this uses the buttons from the PCB, if you use your own implementation you need to reprogram this function

  if (mainTimer &lt; millis() - timeBetweenSamples) { // sampling only once per interval.
    mainTimer = millis(); // time is rewritten to current millis starting a new interval.

    if (buttonPressed == 0) { //'idle play'
      if (idleState == 0) {
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      else if (idleState == 1){
        motionVar1 = servoMotionArray_B1[arrayPosition];
      }
      motionVar2 = DCMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      if (motionVar2 &lt; 0) {
        myMotor-&gt;run(BACKWARD);
        myMotor-&gt;setSpeed(abs(motionVar2));
      }
      else if (motionVar2 &gt;= 0) {
        myMotor-&gt;run(FORWARD);
        myMotor-&gt;setSpeed(motionVar2);
      }
      arrayPosition++;
      if (arrayPosition &gt; 49) {
        arrayPosition = 0;
        idleState = !idleState;
      }
    }

    if (buttonPressed == 1) { //2nd behaviour
      if (resetMotion == 0) {
        arrayPosition = 0;
        resetMotion = 1;
        myMotor-&gt;run(RELEASE); // release the DC motor, otherwise it will continue spinning at the last known RPM
      }
      motionVar1 = servoMotionArray_B3[arrayPosition];
      motionVar2 = StepperMotionArray_B1[arrayPosition];
      myservo1.write(motionVar1);
      aStepper.moveTo(motionVar2);
      arrayPosition++;
      if (arrayPosition &gt; 49) {
        arrayPosition = 0;
        buttonPressed = 0;
        resetMotion = 0;
      }
    }
  }



  // one of these needs to be called to make the stepper motor work, comment out the one you do not need (position or speed)
  //aStepper.run(); //stepper position implementation
  aStepper.runSpeed(); //stepper speed implementation

}
</code></pre>
 16780: <p>You're almost correct already:</p>
<pre><code>if (millis() - mainTimer &gt;= timeBetweenSamples) {
  mainTimer = millis(); 
  // executing only once per interval.

  ... the action for current arrayPosition ...

  arrayPosition++;
  if (arrayPosition &gt; 49) {
     arrayPosition = 0;
     buttonPressed = 0; // Show ends
  }   
}
</code></pre>
