4 stepper motors to be controlled with 4 potis individually

Hi together

I am working on a project in which I am trying to set the speed of 4 individual stepper motors by 4 potentiometers, each assigned to one single stepper motor. I have managed to wire everything correctly and it worked perfectly with one potentiometer and one stepper motor.
Now that I have put everything together with 4 stepper motors, 4 A4988 and 4 potentiometers, all of the stepper motors are only responding to the first potentiometer (A0).

Here is my code, which I have collected from various examples on the Internet and which worked fine for 1 stepper and 1 poti, but my logical multiplication of all variables and function does not seem to work properly.

const int step1 = 7;
const int dir1 = 8;
const int step2	= 5;
const int dir2 = 6;
const int step3 = 3;
const int dir3 = 4;
const int step4 = 1;
const int dir4 = 2;

int poti1, poti2, poti3, poti4, poti1map, poti2map, poti3map, poti4map;

void setup() {
   pinMode(step1, OUTPUT);
   pinMode(dir1, OUTPUT);
   pinMode(step2, OUTPUT);
   pinMode(dir2, OUTPUT);
   pinMode(step3, OUTPUT);
   pinMode(dir3, OUTPUT);
   pinMode(step4, OUTPUT);
   pinMode(dir4, OUTPUT);

   digitalWrite(dir1, HIGH);
   digitalWrite(dir2, HIGH);
   digitalWrite(dir3, HIGH);
   digitalWrite(dir4, HIGH);
}
void loop() {

   poti1map = speed1Up();
   digitalWrite(step1, HIGH);
   delayMicroseconds(poti1map);
   digitalWrite(step1, LOW);
   delayMicroseconds(poti1map);

   poti2map = speed2Up();
   digitalWrite(step2, HIGH);
   delayMicroseconds(poti2map);
   digitalWrite(step2, LOW);
   delayMicroseconds(poti2map);

   poti3map = speed3Up();
   digitalWrite(step3, HIGH);
   delayMicroseconds(poti3map);
   digitalWrite(step3, LOW);
   delayMicroseconds(poti3map);

   poti4map = speed4Up();
   digitalWrite(step4, HIGH);
   delayMicroseconds(poti4map);
   digitalWrite(step4, LOW);
   delayMicroseconds(poti4map);
}

int speed1Up() {
   int poti1 = analogRead(A0);
   int new1Custom = map(poti1, 0, 1023, 300, 4000);
   return new1Custom;
}

int speed2Up() {
   int poti2 = analogRead(A1);
   int new2Custom = map(poti2, 0, 1023, 300, 4000);
   return new2Custom;
}

int speed3Up() {
   int poti3 = analogRead(A2);
   int new3Custom = map(poti3, 0, 1023, 300, 4000);
   return new3Custom;
}

int speed4Up() {
   int poti4 = analogRead(A3);
   int new4Custom = map(poti4, 0, 1023, 300, 4000);
   return new4Custom;
}

My final question would be: As I want the stepper motors to stop when the Potentiometers are at 0, I know that I have to define ditigalwrite(stepX; LOW) and the delaymicroseconds() to be at infinitely high, but is there a code for that or do I define it in the int speedXUp() Function?

Thanks for your help in advance!

delayMicroseconds is a blocking command. What that means is that for the length of time you have requested, the arduino will do nothing, nada, zilch, wammel. It is literally doing nothing. If you image that your first stepper motor is set to a very slow speed then it will be impossible for your other steppers to go any faster.

Have a look at this tutorial and try to understand how to remove delay and work with timers instead -

Also, there's a library called AccelStepper which is excellent and should be used instead.

As @JWScotSat has said, using the AccelStepper library may be the simplest solution.

If you want to write your own code and not use a library the second example in this Simple Stepper Code illustrates how to use non-blocking code. Note also that the pulse width is fixed (and short) and the speed is controlled by the interval between steps.

To get the motors to stop when the potentiometer is at zero just check the pot value and don't call the step code if it is 0.

...R
Stepper Motor Basics

First of all, thank you for your answers and your help.

I have looked into the AccelStepper library and it indeed helped me to simplify my code and at least move every stepper Motor seperately by the respective pot.

Yet, after several tries and many different variations of code I have only come to the following result, which
moves every stepper motor by its respective analogue input but only on a certain position of the pot, while all other positions of the pot seem to stop the stepper motor.

The goal is to have the stepper motor stay still at pot1val = 0 and accelerate accordingly when the pot1Val is increased. My question would be, if I have to map the pot1val and return it again as I did in my initial code or do how do I set the speed of the stepper motor relatively to the pot?

I have tried by implementing a variable which sets the Speed based on the pot1val, something like this:
speed1Val = pot1val*100 and using it in the stepperOne.setSpeed(speed1Val) function, but then nothing happened anymore.

I hope you guys can help me out, I have already come a good way since your first answers.

Thank you!

#include <AccelStepper.h>

int pot1Val = 0;
int pot2Val = 0;
int pot3Val = 0;
int pot4Val = 0;

AccelStepper stepperOne(1, 8, 9);
AccelStepper stepperTwo(1, 6, 7);
AccelStepper stepperThree(1, 4, 5);
AccelStepper stepperFour(1, 2, 3);

void setup() {
   stepperOne.setMaxSpeed(1000);
   stepperTwo.setMaxSpeed(1000);
   stepperThree.setMaxSpeed(1000);
   stepperFour.setMaxSpeed(1000);
}
void loop() {
   
   pot1Val = analogRead(A0);
   stepperOne.moveTo(pot1Val);
   stepperOne.setSpeed(300);
   stepperOne.runSpeedToPosition();
   
   pot2Val = analogRead(A1);
   stepperTwo.moveTo(pot2Val);
   stepperTwo.setSpeed(300);
   stepperTwo.runSpeedToPosition();
   
   pot3Val = analogRead(A2);
   stepperThree.moveTo(pot3Val);
   stepperThree.setSpeed(300);
   stepperThree.runSpeedToPosition();
   
   pot4Val = analogRead(A3);
   stepperFour.moveTo(pot4Val);
   stepperFour.setSpeed(300);
   stepperFour.runSpeedToPosition();
}

Don't use runSpeedToPosition() as that is a blocking function. Just use runSpeed()

...R

Hi Robin

Thank you for your help, but when I just took out the function runSpeedToPosition(), I got no reaction from the Steppers at all. Right now, I have managed to make the Motors rotate at any Point from the Potentiometer (by adding , yet rather sporadically and sometimes it seems like it is skipping and vibrating to hard.

For now I have looked over all the examples from the AccelStepper library, of which one example was the one I used below and just multiplied. I have also looked over every possibility and tried many variations, but never got further than the below code. The stepper Motor is still not fluent in its motion and stops while I am turning the pot instead of just accelerating. Also, it does not accelerate at all, as wherever the pot is positioned, the Speed of the motor is the same.

I would be grateful if anybody could help me out and give me at least an idea of where to go from here, as I cannot find any further information on what I am doing wrong or where I can take it a step further.

Thanks in advance!

#include <AccelStepper.h>

#define POT_1 A0
#define POT_2 A1
#define POT_3 A2
#define POT_4 A3

int pot1Val, pot2Val, pot3Val, pot4Val;

AccelStepper stepperOne(1, 8, 9);
AccelStepper stepperTwo(1, 6, 7);
AccelStepper stepperThree(1, 4, 5);
AccelStepper stepperFour(1, 2, 3);

void setup() {
   stepperOne.setMaxSpeed(4000.0);
   stepperOne.setAcceleration(300.0);

   stepperTwo.setMaxSpeed(4000.0);
   stepperTwo.setAcceleration(300.0);
   
   stepperThree.setMaxSpeed(4000.0);
   stepperThree.setAcceleration(300.0);
   
   stepperFour.setMaxSpeed(4000.0);
   stepperFour.setAcceleration(300.0);
}
void loop() {
   
   int pot1Val = analogRead(POT_1);
   stepperOne.moveTo(pot1Val);
   stepperOne.setSpeed(300);
   stepperOne.runSpeedToPosition();
   
   int pot2Val = analogRead(A1);
   stepperTwo.moveTo(pot2Val);
   stepperTwo.setSpeed(500);
   stepperTwo.runSpeedToPosition();
   
   int pot3Val = analogRead(A2);
   stepperThree.moveTo(pot3Val);
   stepperThree.setSpeed(300);
   stepperThree.runSpeedToPosition();
   
   int pot4Val = analogRead(A3);
   stepperFour.moveTo(pot4Val);
   stepperFour.setSpeed(300);
   stepperFour.runSpeedToPosition();
}

I'm confused... you wrote "I am trying to set the speed of 4 individual stepper motors by 4 potentiometers," but every place you call .setSpeed() you pass the constant '300'?!? Shouldn't the speed you set have something to do with the pot position?

Aside from reading the pots and setting the speeds I think the only lines you need in loop() are:

   stepperOne.runSpeed();
   stepperTwo.runSpeed();

   stepperThree.runSpeed();
   stepperFour.runSpeed();

ifdocsay:
I would be grateful if anybody could help me out and give me at least an idea of where to go from here,

The program in Reply #5 is still using runSpeedToPosition() so I can't see why your attempt with runSpeed() failed.

When you use runSpeed() you must call it repeatedly - probably at least twice as often as your motor needs to make steps. Each time runSpeed() is called the Library will figure out whether (or not) it is time for the next step.

...R

Hi Robin, Johnwasser

I am very grateful for your help and information. Because I somehow was surprised that it did not work with .runSpeed(), I started checking my wiring again and saw that I mixed up some of them, my bad. Thank you for staying with me.

Now, it is working as expected and I have found this code to work. Yet, in order to develop my skills and learn for the future, as I want to improve the project and add some LEDs (for which I will be consulting the Blink without Delay post), but for now, are there any more remarks for the code?

I have been told that I can also work with reading the position of the pot with IF statements instead of mapping the pot. Would that improve my code?

#include <AccelStepper.h>

#define POT_1 A0
#define POT_2 A1
#define POT_3 A2
#define POT_4 A3

int pot1Val, pot2Val, pot3Val, pot4Val;

AccelStepper stepperOne(1, 9, 8);
AccelStepper stepperTwo(1, 7, 6);
AccelStepper stepperThree(1, 5, 4);
AccelStepper stepperFour(1, 3, 2);

void setup() {
   stepperOne.setMaxSpeed(1000.0);
   stepperOne.setAcceleration(100.0);

   stepperTwo.setMaxSpeed(4000.0);
   stepperTwo.setAcceleration(300.0);
   
   stepperThree.setMaxSpeed(4000.0);
   stepperThree.setAcceleration(300.0);
   
   stepperFour.setMaxSpeed(4000.0);
   stepperFour.setAcceleration(300.0);
}
void loop() {
   
   int pot1Val = analogRead(POT_1);
   int pot1Speed = map(pot1Val, 0, 1023, 0, 100);
   stepperOne.setSpeed(pot1Speed);
   stepperOne.runSpeed();

   int pot2Val = analogRead(POT_2);
   int pot2Speed = map(pot2Val, 0, 1023, 0, 1000);
   stepperTwo.setSpeed(pot2Speed);
   stepperTwo.runSpeed();
   
   int pot3Val = analogRead(POT_3);
   int pot3Speed = map(pot3Val, 0, 1023, 0, 1000);
   stepperThree.setSpeed(pot3Speed);
   stepperThree.runSpeed();
   
   int pot4Val = analogRead(POT_4);
   int pot4Speed = map(pot4Val, 0, 1023, 0, 1000);
   stepperFour.setSpeed(pot4Speed);
   stepperFour.runSpeed();
}

One more question: I will be working with trial and error to determine a possibility to make the first stepper motor rotate only once every 10min or so. I will also microstep it to 1/16th so that it will be smoother, but right now, it is rather loud and vibrates while rotating slowly. Is there any way to avoid this and let it run more smoothly?

A small point ... setMaxSpeed and setAcceleration are only useful when you use run() rather than runSpeed(). However run() really only works for movements of a specific number of steps.

...R

   int pot2Speed = map(pot2Val, 0, 1023, 0, 1000);
   stepperTwo.setSpeed(pot2Speed);

The argument to .setSpeed(steps_per_second) is type 'float'. The map() function only works in integers. so it would be slightly more accurate to write this as:

   float pot2Speed = (pot2Val * 1000.0) / 1024.0;
   stepperTwo.setSpeed(pot2Speed);