Issue while controlling 2 step motors simultaneously (without library)

Hello,

I'm working on a strong pan/tilt for my camera. For manual use (using a 2 joysticks-controller) i would like to control pan and tilt simultaneously.

Here's the code :

void loop(){
  
pHB = analogRead(HB);  //Reads the inputs
pGD = analogRead(GD);

//Direction processing and "map" of my joystick position, in order to get time. (used next for uptime and downtime of the pulse, so the bigger the number, slower is the motor.)

if (pHB > 512){dirY = true;delayTimey = map(pHB, 550, 1024, 1000,5);} 
if (pHB <= 512){dirY = false;delayTimey = map(pHB, 450, 0, 1000,5);}

if (pGD > 512){dirX = true;delayTimex = map(pGD, 550, 1024, 1000,5);}
if (pGD <= 512){dirX = false;delayTimex = map(pGD, 450, 0, 1000,5);}

//Stop joystick position
if(pHB > 450 && pHB <550) {stopy = true;}else{stopy = false;}
if(pGD > 450 && pGD <550) {stopx = true;}else{stopx = false;}

//Sets the direction to the pin
digitalWrite(Y_DIR, dirY);
digitalWrite(X_DIR, dirX);

//Writes pulses to the driver.

    if(stopx == 0){digitalWrite(X_STP, HIGH);}

    delayMicroseconds(delayTimex); 

    digitalWrite(X_STP, LOW);

    delayMicroseconds(delayTimex);

    if(stopy == 0){digitalWrite(Y_STP, HIGH);}

    delayMicroseconds(delayTimey); 

    digitalWrite(Y_STP, LOW);

    delayMicroseconds(delayTimey); 


}

All is working quite fine, but I have an issue with the speed control : speed of the stepper is not really "linear".

I'm aware that my code is very looptime-sensitive, so I tried to equilibrate treatment for X and Y motors.

When I control one motor at a time (joystick fully pushed), motor tops at ~50% of its speed.
When I control two motors simultaneously, (joystick fully pushed in a corner), both motors reach 100% of their speed.

A video is the best explanation :

Stepmotor code issue

Troubleshooting :
-Battery voltage is ok, even under load.
-Drivers are ok.
-Joysticks are on a good 0-1023 zone, midpoint 500-510.

I think the map() function could be the culprit, I think it could slow something somewhere, but it's out of my reach.

What do you guys think ?

Thanks for you help.

Ethan

Have a look at the non-blocking code in the second example in this Simple Stepper Code

The map() function is slow but I suspect it is the delay()s that are the cause of the problem

For the future, please always post a complete program.

...R
Stepper Motor Basics

Thanks for you fast answer and sorry for the code.

I made a modification, it kind of do what I want.

#define EN        8  

//Direction pin
#define X_DIR     5 
#define Y_DIR     6
#define Z_DIR     7

//Step pin
#define X_STP     2
#define Y_STP     3 
#define Z_STP     4 

int GD = A9;
int HB = A8;

int m0x = 35;
int m1x = 37;
int m2x = 39;

int m0y = 29;
int m1y = 31;
int m2y = 33;

int delayTimex = 0;
int delayTimey = 0;

int pHB = 0;
int pGD = 0;

bool dirY = false;
bool dirX = false;

bool stopx = 0;
bool stopy = 0;

void setup(){

Serial.begin(9600);

  pinMode(m0x, OUTPUT);
  pinMode(m1x, OUTPUT);
  pinMode(m2x, OUTPUT);

  pinMode(m0y, OUTPUT);
  pinMode(m1y, OUTPUT);
  pinMode(m2y, OUTPUT);
  
  digitalWrite(m0x, LOW);
  digitalWrite(m1x, LOW);
  digitalWrite(m2x, HIGH);

  digitalWrite(m0y, LOW);
  digitalWrite(m1y, LOW);
  digitalWrite(m2y, HIGH);
  
  pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT);

  pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT);

  pinMode(Z_DIR, OUTPUT); pinMode(Z_STP, OUTPUT);

  pinMode(EN, OUTPUT);

  digitalWrite(EN, LOW);

}

void loop(){
  
pHB = analogRead(HB);
pGD = analogRead(GD);
/*
Serial.println(pHB);
Serial.println(pGD);
Serial.println("______");
*/
if (pHB > 512){dirY = true;delayTimey = map(pHB, 550, 1024, 1000,5);}
if (pHB <= 512){dirY = false;delayTimey = map(pHB, 450, 0, 1000,5);}

if (pGD > 512){dirX = true;delayTimex = map(pGD, 550, 1024, 1000,5);}
if (pGD <= 512){dirX = false;delayTimex = map(pGD, 450, 0, 1000,5);}

if(pHB > 450 && pHB <550) {stopy = true;}else{stopy = false;}
if(pGD > 450 && pGD <550) {stopx = true;}else{stopx = false;}

digitalWrite(Y_DIR, dirY);
digitalWrite(X_DIR, dirX);

    if(stopx == 0){digitalWrite(X_STP, HIGH);}
    digitalWrite(X_STP, LOW);
    
    if(stopy == 0){digitalWrite(Y_STP, HIGH);}
    digitalWrite(Y_STP, LOW);
    
delayMicroseconds(delayTimex);
delayMicroseconds(delayTimey);

}

Thanks to your link, i deleted two useless lines and the problem stopped. But i need to keep a delay somewhere to control my motors speed. (Unique speed for both motor, I can't see a way to do individual speed for both of them, apart from having two processing cores)
On the last two lines, I see a strange behavior.
When i delete delayMicroseconds(delayTimex); the X motor does not sense any delay. And vice versa.
I've never seen this kind of behavior.

ethanios:
But i need to keep a delay somewhere to control my motors speed.

You need an interval but you should not implement it with delay() or delayMicroseconds()

...R