Help with 2 steppermotors controlled by potentiometers

Hi forummembers,

I'm new here on the forum. I have some experience with Arduino. I have the following problem. Maybe someone can help me. I have a controller with 2 stepper motors. They each have their TB6600 as a driver. Each motor has its own on/off switch and its own 10K potentiometer to control the speed. The speed of the motors is displayed on the screen from 0-100%. The system works very well except that the 2 potentiometers affect each other. If I adjust one, then both motors accelerate or decelerate. When I work with only one motor, everything is as it should be. The connections have been checked multiple times and I can't find any errors in them. Can someone help me figure out how to fix this problem? Thank you for any input!!

Michel

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//#include <Stepper.h>

#define directionPin1 2
#define stepPin1 3
#define potentiometerPin1 A0
#define switchPin1 7

#define directionPin2 4
#define stepPin2 5
#define potentiometerPin2 A1
#define switchPin2 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

int previousPotValue1 = 0;
int previousPotValue2 = 0;


void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Speed M1: ");
  lcd.setCursor(12, 0);
  lcd.print("  % ");
  lcd.setCursor(0, 1);
  lcd.print("Speed M2: ");
  lcd.setCursor(12, 1);
  lcd.print("  % ");

  // Serial.begin(9600);
  pinMode(switchPin1, INPUT_PULLUP);  // Schakelaar 1 heeft een pull-up weerstand
  pinMode(switchPin2, INPUT_PULLUP);  // Schakelaar 2 heeft een pull-up weerstand
  pinMode(directionPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  digitalWrite(directionPin1, LOW);
  pinMode(directionPin2, OUTPUT);
  pinMode(stepPin2, OUTPUT);
  digitalWrite(directionPin2, LOW);
}

void updateLCD(float speedPercent1) {
  lcd.setCursor(10, 0);
  lcd.print(speedPercent1, 0);
}
void updateLCD1(float speedPercent2) {
  lcd.setCursor(10, 1);
  lcd.print(speedPercent2, 0);
}
void loop() {

  // Stepper motor 1
  int potValue1 = analogRead(potentiometerPin1);
  int potValue2 = analogRead(potentiometerPin2);


  if (digitalRead(switchPin1) == LOW) {

    float speedPercent1 = map(potValue1, 0, 1023, 100, 10);  // Calculate speed percentage for motor 1
    //Check if potentiometer 1 value has changed by more than 2%
    if (abs(potValue1 - previousPotValue1) > 10) {
      updateLCD(speedPercent1);
      previousPotValue1 = potValue1;
    }
    int delayTime1 = map(potValue1, 0, 1023, 100, 1000);  // Adjust these values according to your motor and preference

    digitalWrite(stepPin1, HIGH);
    delayMicroseconds(delayTime1);
    digitalWrite(stepPin1, LOW);
    // delayMicroseconds(delayTime1);

  } else {
    digitalWrite(stepPin1, LOW);
  }

  // Stepper motor 2

  if (digitalRead(switchPin2) == LOW) {

    int potValue2 = analogRead(potentiometerPin2);


    float speedPercent2 = map(potValue2, 0, 1023, 100, 10);  // Calculate speed percentage for motor 2

    // Check if potentiometer 2 value has changed by more than 2%
    if (abs(potValue2 - previousPotValue2) > 10) {
      updateLCD1(speedPercent2);
      previousPotValue2 = potValue2;
    }

    int delayTime2 = map(potValue2, 0, 1023, 100, 1000);  // Adjust these values according to your motor and preference

    digitalWrite(stepPin2, HIGH);
    delayMicroseconds(delayTime2);
    digitalWrite(stepPin2, LOW);
    // delayMicroseconds(delayTime2);
  } else {
    digitalWrite(stepPin2, LOW);
  }
}

I would try 0.1uF ceramic caps from each pot wiper to ground to help bypass noise and crosstalk to ground. This effectively lowers the input impedance as well..

Also, a dummy read to set up the ADC may help. Do a read of the channel and discard it, then do another read for real.j

Your code looks ok. See in the simulator.

1 Like

Works for me.

I'd probably make the UI more responsive by moving the pot reading and screen updating out of the on/off conditionals so you could see the adjustments as you move the pots:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
//#include <Stepper.h>
#define directionPin1 2
#define stepPin1 3
#define potentiometerPin1 A0
#define switchPin1 7
#define directionPin2 4
#define stepPin2 5
#define potentiometerPin2 A1
#define switchPin2 6
LiquidCrystal_I2C lcd(0x27, 16, 2);
int previousPotValue1 = 0;
int previousPotValue2 = 0;
//-----------------------------------------------------------------
void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Speed M1: ");
  lcd.setCursor(12, 0);
  lcd.print("  % ");
  lcd.setCursor(0, 1);
  lcd.print("Speed M2: ");
  lcd.setCursor(12, 1);
  lcd.print("  % ");
  // Serial.begin(9600);
  pinMode(switchPin1, INPUT_PULLUP);  // Schakelaar 1 heeft een pull-up weerstand
  pinMode(switchPin2, INPUT_PULLUP);  // Schakelaar 2 heeft een pull-up weerstand
  pinMode(directionPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  digitalWrite(directionPin1, LOW);
  pinMode(directionPin2, OUTPUT);
  pinMode(stepPin2, OUTPUT);
  digitalWrite(directionPin2, LOW);
  //Serial.begin(115200);
}
//-----------------------------------------------------------------
void updateLCD(float speedPercent1) {
  lcd.setCursor(10, 0);
  lcd.print(speedPercent1, 0);
  lcd.print(" ");
}
//-----------------------------------------------------------------
void updateLCD1(float speedPercent2) {
  lcd.setCursor(10, 1);
  lcd.print(speedPercent2, 0);
  lcd.print(" ");
}
//-----------------------------------------------------------------
void loop() {
  // Stepper motor 1
  int potValue1 = analogRead(potentiometerPin1);
  int potValue2 = analogRead(potentiometerPin2);

  float speedPercent1 = map(potValue1, 0, 1023, 100, 10);  // Calculate speed percentage for motor 1
  //Serial.println(speedPercent1);
  //Check if potentiometer 1 value has changed by more than 2%
  if (abs(potValue1 - previousPotValue1) > 10) {
    updateLCD(speedPercent1);
    previousPotValue1 = potValue1;
  }
  int delayTime1 = map(potValue1, 0, 1023, 100, 1000);  // Adjust these values according to your motor and preference

  float speedPercent2 = map(potValue2, 0, 1023, 100, 10);  // Calculate speed percentage for motor 2
  // Check if potentiometer 2 value has changed by more than 2%
  if (abs(potValue2 - previousPotValue2) > 10) {
    updateLCD1(speedPercent2);
    previousPotValue2 = potValue2;
  }
  int delayTime2 = map(potValue2, 0, 1023, 100, 1000);  // Adjust these values according to your motor and preference

  if (digitalRead(switchPin1) == LOW) {
    digitalWrite(stepPin1, HIGH);
    delayMicroseconds(delayTime1);
    digitalWrite(stepPin1, LOW);
    // delayMicroseconds(delayTime1);
  } else {
    digitalWrite(stepPin1, LOW);
  }
  // Stepper motor 2
  if (digitalRead(switchPin2) == LOW) {
    digitalWrite(stepPin2, HIGH);
    delayMicroseconds(delayTime2);
    digitalWrite(stepPin2, LOW);
    // delayMicroseconds(delayTime2);
  } else {
    digitalWrite(stepPin2, LOW);
  }
}

See the issue?

No? I think the LiquidCrystal_I2C lcd(0x27, 16, 2); defines the I2C address as 0x27, and the 16 columns by 2 rows display size, not a pin number.

Ah rats! I thought I found it.

We really need to see your circuit and how the pots are connected.

1 Like

Thank you for providing your solution, I will be back in my workshop tomorrow and can continue working on my project. I will definitely try out your tips.

Kind regards, Michel"

Thank you for providing your solution, I will be back in my studio tomorrow and can continue working on my project.

I will definitely try out your tips.
Kind regards,
Michel

Hello forum members,

I think I have found a solution.
The issue was with the potentiometers.
The values of the 2 wipers were being summed together.
If one potentiometer was at, for example, 7k and the other at 5k, then there would be 12k between the 2 wipers. In that manner, they were influencing each other.
Naturally, the Arduino would react incorrectly to this.
This was due to the way they were connected to the Arduino.
Tomorrow, back at the workshop, I will connect them only between the Vcc and the wipers.

Hopefully, this should work.

Regards, Michel

Did you try:

int potValue1 = analogRead(potentiometerPin1);   
    potValue1 = analogRead(potentiometerPin1);
int potValue2 = analogRead(potentiometerPin2); 
    potValue2 = analogRead(potentiometerPin2);

?

did you read post #2 from @groundFungus ?

and just now #12 from @JCA34F?

Also have you told us WHICH arduino you are using?

Hi,

I've tried all the recommendations and none of them have worked.
I've completely started over, this time using pulse encoders (to avoid the issue of compounded wiper values).
The result is exactly the same. When I rotate one of the encoders, the second motor accelerates or decelerates along with it.

I believe it has to do with the tb6600.
I've tried attaching two new others to it, with exactly the same result.

regards

Michel

arduino uno R3 and a second try with a mega2560

I've started over again and now have this code.
I'm using accelstepper.h.
I'll install it in my project tomorrow and see if it works.
I'll keep you updated.

Thanks for all your efforts so far!"

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>

#define directionPin1 2
#define stepPin1 3
#define potentiometerPin1 A0
#define switchPin1 7

#define directionPin2 4
#define stepPin2 5
#define potentiometerPin2 A1
#define switchPin2 6

LiquidCrystal_I2C lcd(0x27, 16, 2);

AccelStepper stepper1(AccelStepper::DRIVER, stepPin1, directionPin1);
AccelStepper stepper2(AccelStepper::DRIVER, stepPin2, directionPin2);

int previousPotValue1 = 0;
int previousPotValue2 = 0;

void setup() {
  lcd.init();
  lcd.backlight();
  lcd.setCursor(0, 0);
  lcd.print("Speed M1: ");
  lcd.setCursor(12, 0);
  lcd.print("  % ");
  lcd.setCursor(0, 1);
  lcd.print("Speed M2: ");
  lcd.setCursor(12, 1);
  lcd.print("  % ");

  pinMode(switchPin1, INPUT_PULLUP);
  pinMode(switchPin2, INPUT_PULLUP);

  stepper1.setMaxSpeed(1000); // Set max speed in steps per second
  stepper2.setMaxSpeed(1000);

  stepper1.setAcceleration(500); // Set acceleration in steps per second^2
  stepper2.setAcceleration(500);

  stepper1.setCurrentPosition(0);
  stepper2.setCurrentPosition(0);
}

void updateLCD(float speedPercent, int motor) {
  lcd.setCursor(10, motor);
  lcd.print(speedPercent, 0);
  lcd.print(" ");
}

void loop() {
  // Stepper motor 1
  if (digitalRead(switchPin1) == LOW) {
    int potValue1 = analogRead(potentiometerPin1);
    float speedPercent1 = map(potValue1, 0, 1023, 100, 10);
    if (abs(potValue1 - previousPotValue1) > 10) {
      updateLCD(speedPercent1, 0);
      previousPotValue1 = potValue1;
    }
    int speed1 = map(potValue1, 0, 1023, 10, 1000); // Map potentiometer value to speed
    stepper1.setSpeed(speed1);
    stepper1.runSpeed();
  } else {
    stepper1.stop();
  }

  // Stepper motor 2
  if (digitalRead(switchPin2) == LOW) {
    int potValue2 = analogRead(potentiometerPin2);
    float speedPercent2 = map(potValue2, 0, 1023, 100, 10);
    if (abs(potValue2 - previousPotValue2) > 10) {
      updateLCD(speedPercent2, 1);
      previousPotValue2 = potValue2;
    }
    int speed2 = map(potValue2, 0, 1023, 10, 1000); // Map potentiometer value to speed
    stepper2.setSpeed(speed2);
    stepper2.runSpeed();
  } else {
    stepper2.stop();
  }
}

Do you have your pots wired up just like that Wokwi sim? With nothing but the wipers connected?

If that's the case, they are just floating inputs and will give random results.

The GNDs on the pots should be connected to the GND pin and their VCCs should be connected to the 5V pin. Like this:

image

The 100% speed = 10steps/sec and 10%=1000steps/sec code makes my head hurt.

your diagram doesnt show the motors and drivers. We are still guessing.

Hi forummembers,

I managed to get my project working. The goal was to control 2 stepper motors separately using potentiometers.
On the display, I needed to see the speed of both motors, ranging from 0-100%.
The speed wasn't crucial. The idea was for motor 2 to spin faster than motor 1 (to stretch a synthetic thread).
In the attachment, you can find my code as well as a link to Wokwi.
All the necessary capacitors and pull-up resistors are mounted in my project. I couldn't draw them in Wokwi.
There are probably still improvements possible.
Feel free to keep me updated.
The dip switches of the tb6600 are set to S1 S2 S3 (6400) Off and S4S5S65 ON (0.5amp).
Sorry for the slow responses, but this was a side project amidst all my other work, so there wasn't much time to reply.

Maybe there are still mistakes, forgive me, it's my second project, I still need to learn some things.

Kind regards

Michel

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <AccelStepper.h>

LiquidCrystal_I2C lcd(0x27, 16, 2);

// motor 2

#define directionPin2 2
#define stepPin2 3
#define enPin2 4
#define switchPin1 6  //toggle switch motor 2  on   oranje
#define switchPin2 5  //toggle switch motor 2  off  Bruin
#define potentiometerPin2 A1

AccelStepper stepper2(AccelStepper::DRIVER, stepPin2, directionPin2);

// MOTOR 1

#define directionPin1 7
#define stepPin1 9
#define enPin1 8
#define switchPin3 11  // toggle switch motor 1 on  Blauw
#define switchPin4 10  // toggle switch motor 1 off  Groen
#define potentiometerPin1 A0

AccelStepper stepper1(AccelStepper::DRIVER, stepPin1, directionPin1);

int previousPotValue1 = 0;
int previousPotValue2 = 0;

bool motor1Running = false;
bool motor2Running = false;

void setup() {

  lcd.init();
  lcd.backlight();
  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print("    Stretcher  ");
  lcd.setCursor(0, 1 );
  lcd.print("Made WE62 Ugent");
  delay(6000);
  lcd.clear();

  lcd.setCursor(0, 0);
  lcd.print("Speed M1: ");
  lcd.setCursor(13, 0);
  lcd.print("  % ");
  lcd.setCursor(0, 1);
  lcd.print("Speed M2: ");
  lcd.setCursor(13, 1);
  lcd.print("  % ");

  pinMode(switchPin1, INPUT);  // Schakelaar 1 heeft een pull-up weerstand
  pinMode(switchPin2, INPUT);  // Schakelaar 2 heeft een pull-up weerstand
  pinMode(switchPin3, INPUT);  // Schakelaar 3 heeft een pull-up weerstand
  pinMode(switchPin4, INPUT);  // Schakelaar 4 heeft een pull-up weerstand

  pinMode(directionPin1, OUTPUT);
  pinMode(stepPin1, OUTPUT);
  pinMode(enPin1, OUTPUT);

  digitalWrite(directionPin1, HIGH);
  digitalWrite(enPin1, HIGH);

  pinMode(directionPin2, OUTPUT);
  pinMode(stepPin2, OUTPUT);
  pinMode(enPin2, OUTPUT);

  digitalWrite(directionPin2, LOW);
  digitalWrite(enPin2, HIGH);

  digitalWrite(switchPin1, LOW);  // Schakelaar 1 heeft een pull-up weerstand
  digitalWrite(switchPin2, LOW);  // Schakelaar 1 heeft een pull-up weerstand
  digitalWrite(switchPin3, LOW);  // Schakelaar 1 heeft een pull-up weerstand
  digitalWrite(switchPin4, LOW);  // Schakelaar 1 heeft een pull-up weerstand

  stepper1.setMaxSpeed(4000);  // Set max speed in steps per second
  stepper2.setMaxSpeed(4000);

  stepper1.setAcceleration(500);  // Set acceleration in steps per second^2
  stepper2.setAcceleration(500);

  stepper1.setCurrentPosition(0);
  stepper2.setCurrentPosition(0);
}

void updateLCD(float speedPercent, int motor) {
  lcd.setCursor(10, motor);
  lcd.print(speedPercent, 0);
  lcd.print(" ");
}

void loop() {

  // Controleer de status van de toggle switches voor motor 2
  if (digitalRead(switchPin1) == HIGH) {  // start motor 2
    motor2Running = true;
    digitalWrite(enPin2, LOW);

  } else if (digitalRead(switchPin2) == HIGH) {  // start motor 2
    motor2Running = false;
    Serial.println(switchPin2);
    digitalWrite(enPin2, HIGH);
  }

  // Controleer de status van de toggle switches voor motor 1
  if (digitalRead(switchPin3) == HIGH) {  // start motor 1
    motor1Running = true;
    digitalWrite(enPin1, LOW);

  } else if (digitalRead(switchPin4) == HIGH) {  // stop motor 1
    digitalWrite(enPin1, HIGH);
    motor1Running = false;
  }

  // Steppermotor 1
  if (motor1Running) {
    int potValue1 = analogRead(potentiometerPin1);
    float speedPercent1 = map(potValue1, 0, 1023, 100, 1);
    if (abs(potValue1 - previousPotValue1) > 10) {
      updateLCD(speedPercent1, 0);
      previousPotValue1 = potValue1;
    }
    int speed1 = map(potValue1, 1023, 0, 0, 4000);  // Map potentiometer value to speed
    stepper1.setSpeed(speed1);
    stepper1.runSpeed();
  } else {
    stepper1.stop();
  }

  // Stepper motor 2
  if (digitalRead(switchPin2) == LOW) {
    int potValue2 = analogRead(potentiometerPin2);
    float speedPercent2 = map(potValue2, 0, 1023, 100, 1);
    if (abs(potValue2 - previousPotValue2) > 10) {
      updateLCD(speedPercent2, 1);
      previousPotValue2 = potValue2;
    }
    int speed2 = map(potValue2, 1023, 0, 0, 4000);  // Map potentiometer value to speed
    stepper2.setSpeed(speed2);
    stepper2.runSpeed();
  } else {
    stepper2.stop();
  }
}