Stepper control with buttons - simultaneous buttons press issue

Hi All,

I have two 28BYJ-48 5VDC steppers connected to ULN2003AN driver boards which are controlled by Arduino Uno and 4 buttons, two for each stepper direction control.
Buttons are wired as displayed in image below:

Both driver board power pins are connected to same ground and 5V.
Pins 2 to 4 for X axis motor, Pins 5 to 9 for Y axis motor.

I used widely spread code to run them, which just turns the stepper back and forth, and customized it

int XMotorPin2 = 2;	// Blue   - 28BYJ48 pin 1
int XMotorPin3 = 3;	// Pink   - 28BYJ48 pin 2
int XMotorPin4 = 4;	// Yellow - 28BYJ48 pin 3
int XMotorPin5 = 5;	// Orange - 28BYJ48 pin 4

int YMotorPin6 = 6;	// Blue   - 28BYJ48 pin 1
int YMotorPin7 = 7;	// Pink   - 28BYJ48 pin 2
int YMotorPin8 = 8;	// Yellow - 28BYJ48 pin 3
int YMotorPin9 = 9;	// Orange - 28BYJ48 pin 4

int XM  = 12;           // X axis Minus pin
int XP  = 13;           // Z axis Plus pin
int YM  = 11;           // Y axis Minus pin
int YP  = 10;           // Y axis Plus pin

int XMState  = 0;       // X axis Minus pin initial state
int XPState  = 0;       // X axis Plus pin initial state
int YMState  = 0;       // Y axis Minus pin initial state
int YPState  = 0;       // Y axis Plus pin initial state

int XMotorSpeed = 1200; // X axis Delay/Speed between stepper pin initialization
int YMotorSpeed = 1200; // X axis Delay/Speed between stepper pin initialization
int Xlookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001}; // X axis Stepper driver board pin seaquence for one step
int Ylookup[8] = {B01000, B01100, B00100, B00110, B00010, B00011, B00001, B01001}; // Y axis Stepper driver board pin seaquence for one step

void setup() {
  pinMode(XMotorPin2, OUTPUT);
  pinMode(XMotorPin3, OUTPUT);
  pinMode(XMotorPin4, OUTPUT);
  pinMode(XMotorPin5, OUTPUT);  
  pinMode(YMotorPin6, OUTPUT);
  pinMode(YMotorPin7, OUTPUT);
  pinMode(YMotorPin8, OUTPUT);
  pinMode(YMotorPin9, OUTPUT);
  pinMode(XM,  OUTPUT);
  pinMode(XP,  OUTPUT);
  pinMode(YM,  OUTPUT);
  pinMode(YP,  OUTPUT); 
  digitalWrite(XM,  LOW);
  digitalWrite(XP,  LOW);
  digitalWrite(YM,  LOW);
  digitalWrite(YP,  LOW);
}

void loop() {
  XMState = digitalRead(XM);
  XPState = digitalRead(XP);
  YMState = digitalRead(YM);
  YPState = digitalRead(YP);

  if (XMState == HIGH) {
    Xanticlockwise();
  }
  if (XPState  == HIGH) {
    Xclockwise();
  }
  if (YMState == HIGH) {
    Yanticlockwise();
  }
  if (YPState  == HIGH) {
    Yclockwise();
  }
}

void Xanticlockwise() {
  for(int x = 0; x < 8; x++) {
    XsetOutput(x);
    delayMicroseconds(XMotorSpeed);
  }
}

void Xclockwise() {
  for(int x = 7; x >= 0; x--) {
    XsetOutput(x);
    delayMicroseconds(XMotorSpeed);
  }
}

void Yanticlockwise() {
  for(int y = 0; y < 8; y++) {
    YsetOutput(y);
    delayMicroseconds(YMotorSpeed);
  }
}

void Yclockwise() {
  for(int y = 7; y >= 0; y--) {
    YsetOutput(y);
    delayMicroseconds(YMotorSpeed);
  } 
}

void XsetOutput(int Xout) {
  digitalWrite(XMotorPin2, bitRead(Xlookup[Xout], 0));
  digitalWrite(XMotorPin3, bitRead(Xlookup[Xout], 1));
  digitalWrite(XMotorPin4, bitRead(Xlookup[Xout], 2));
  digitalWrite(XMotorPin5, bitRead(Xlookup[Xout], 3));
}

void YsetOutput(int Yout) {
  digitalWrite(YMotorPin6, bitRead(Ylookup[Yout], 0));
  digitalWrite(YMotorPin7, bitRead(Ylookup[Yout], 1));
  digitalWrite(YMotorPin8, bitRead(Ylookup[Yout], 2));
  digitalWrite(YMotorPin9, bitRead(Ylookup[Yout], 3));
}

So all works, well sort of, I am able to control one motor at the time just fine, can do clockwise and then anticlockwise. If I would press one buttons for each stepper then one of the steppers appear to be running but with half the speed it was doing originally and the other would do the same or just stall.

Is this caused by the loop as it tries to execute both if conditions in sequence thus causing twice the delay?
Is there a way to avoid this side effect?

Sorry if my definitions look messy.

Thanks in advance.

  pinMode(XM,  OUTPUT);
  pinMode(XP,  OUTPUT);
  pinMode(YM,  OUTPUT);
  pinMode(YP,  OUTPUT);

Switches don't normally get driven. What ARE you thinking?

Why are you not using the Stepper, or AccelStepper, library?

I am able to control one motor at the time just fine

The key there is "one at a time". Your code for stepping is blocking, so pressing more than one switch (you do NOT have buttons - buttons keep shirts closed) will NOT make two motors move at the same time.

If I would press one buttons for each stepper then one of the steppers appear to be running but with half the speed it was doing originally and the other would do the same or just stall.

This isn't a coding problem. You have an inadequate power supply - one that is not capable of providing enough current to move both motors at the same time.

You need to completely reorganize your code so that both motors can make a step in every iteration of loop() and whether they do or not (and the direction) is determined by the values in some global variables that have been updated by the switches.

If it was my project all I would have in loop() would be

void loop() {
   readSwitches();
   moveMotors();
}

And please go back to edit your original post and correct the spelling mistake in the title. It should be "simultaneous"

...R

PaulS:
Switches don't normally get driven. What ARE you thinking?

Yup, got that wrong, realized in the morning when reviewed it. As for code itself, I think you are right, it is because its done as per function block, but it is not the power as there is external power supply with enough Amps.
Will look into mentioned libraries.

Thanks Robin2, corrected it :slight_smile: As for the loop, that does make sense, will re-piece everything and will see how it goes.

but it is not the power as there is external power supply with enough Amps.

What voltage is it, and how many amps? Stepper motors are power-hungry critters.

Those delays() in loops do not help but 10 or so ms for every move isn't killer.

You should also learn about arrays and not using ints to hold pin numbers.