Multitasking - Multiple motors and conveyor belt

Hello, I need some advice. I am trying to code a setup of 4 stepper motors that are connected to a keypad and 2 DC-motors that run a conveyor belt. My goal is to be able to push a key, the correspondning stepper motor starts and the DC-motors starts as well and run for a couple of seconds after the stepper. However, I want to be able to push multiple keys while the DC-motors are running. Right now I need to wait for the DC-motors to be done before I can push another key. How can I make this happen?

I think there will be issues if I code it with a timer since the keys are waiting for an input. I don’t have any sensors.

This is my code:

#include <Keypad.h>
#include <Stepper.h>

const int stepsPerRevolution = 1024;

Stepper myStepper1(stepsPerRevolution, 22, 26, 24, 28);
Stepper myStepper2(stepsPerRevolution, 32, 36, 34, 38);
Stepper myStepper3(stepsPerRevolution, 23, 27, 25, 29);
Stepper myStepper4(stepsPerRevolution, 33, 37, 35, 39);

const int IN1 = 47;
const int IN2 = 45;
const int IN3 = 51;
const int IN4 = 49;

const int ENA = 43;
const int ENB = 53;

const byte ROWS = 4; //four rows
const byte COLS = 4; //three columns
char keys[ROWS][COLS] = {
{‘D’,‘C’,‘B’,‘A’},
{‘H’,‘G’,‘F’,‘E’},
{‘L’,‘K’,‘J’,‘I’},
{‘P’,‘O’,‘N’,‘M’}
};

byte rowPins[ROWS] = {2, 3, 4, 5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {6, 7, 8, 9}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
Serial.begin(9600);
myStepper1.setSpeed(10);
myStepper2.setSpeed(10);
myStepper3.setSpeed(10);
myStepper4.setSpeed(10);

pinMode (IN1, OUTPUT);
pinMode (IN2, OUTPUT);
pinMode (IN3, OUTPUT);
pinMode (IN4, OUTPUT);
pinMode (ENA, OUTPUT);
pinMode (ENB, OUTPUT);

}

void loop(){
// char key = keypad.getKey();
char key = keypad.waitForKey();

if (key){
Serial.println(key);
//control speed
analogWrite(ENA, 200);
analogWrite(ENB, 200);
//control direction
int onTime = 5000;
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);

// ----------------------------------Stepper1-----------------------------

    // just print the pressed key

if (key == ‘A’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper1.step(256);
delay(100);
}

// just print the pressed key
if (key == ‘E’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper1.step(512);
delay(100);
}

if (key == ‘I’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper1.step(768);
delay(100);
}

if (key == ‘M’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper1.step(1024);
delay(100);
}

//-----------------------Stepper2------------------------

if (key == ‘B’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper2.step(256);
delay(100);
}

// just print the pressed key
if (key == ‘F’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper2.step(512);
delay(100);
}

if (key == ‘J’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper2.step(768);
delay(100);
}

if (key == ‘N’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper2.step(1024);
delay(100);
}

//------------------------Stepper3--------------------

if (key == ‘C’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper3.step(256);
delay(100);
}

// just print the pressed key
if (key == ‘G’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper3.step(512);
delay(100);
}

if (key == ‘K’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper3.step(768);
delay(100);
}

if (key == ‘O’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper3.step(1024);
delay(100);
}

//------------------------Stepper4--------------------

if (key == ‘D’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper4.step(256);
delay(100);
}

// just print the pressed key
if (key == ‘H’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper4.step(512);
delay(100);
}

if (key == ‘L’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper4.step(768);
delay(100);
}

if (key == ‘P’ ){
Serial.println(key);
// step one revolution in one direction:
Serial.println(“clockwise”);
myStepper4.step(1024);
delay(100);
}

//---------DC_Motor---------

delay(onTime);
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);

}
}

Hello,
to run your sketch as a multitasking system aviod the usage of the delay() function. This funktion is blocking the continious execution of the sketch. Take a look into the IPO model to structure you project for multitasking.

when using millis() for timing, the code simply compares timestamps to determine the interval has expired. it doesn’t “block”. doing this will not prevent recognizing a keypress.

but step() does block, it doesn’t return until all the steps have been made. I don’t understand the need for a delay() after each step. there’s little you can do using the this Stepper library to avoid this

since it appears the motors are turned on whenever there is a keypress, it’s not obvious that the code needs to wait for the “motors to be done” if a keypress is pending.

it’s conceivable that the code can be modified to wait a short period (1 sec) after each keypress to allow multiple keypresses which at then queued and the operations for each keypress on the queue sequentially performed until the queue is empty

The AccelStepper library is designed to be used non-blocking, this might be a
better choice (and also because it does speed-ramping, which is needed for
best performance from a stepper).

a non-blocking version of step() raises a new problem – knowing when the final step is completed. i wouldn’t be surprised that there isn’t a function to reports that, otherwise some form of timeout is necessary

In the AccelStepper library there is a distanceToGo() method - read AccelStepper.h for all the details.