Go Down

Topic: Power problem driving 4 x stepper motors from Arduino Uno (Read 146 times) previous topic - next topic

mattclubb

Nov 15, 2018, 10:56 am Last Edit: Nov 15, 2018, 01:50 pm by mattclubb Reason: Reformatted
I have 4 x 28BYJ-45 5V Motors with their accompanying ULN2003 driver boards connected to and Arduino Uno.

When I connect all 4 motors they tend to judder on occasion.
It is more stable with 3 but I need to run 4.

They are activated on a light sensor and at times all 4 may be running, but only for a quarter-turn.

I have the Uno running on a 12V mains supply.
The driver cards have a separate 12V supply running all 4.

It seems like a power issue but is there any way round this?

Many thanks
Matt

Here is my code:

Code: [Select]
#include <AccelStepper.h>
#define HALFSTEP 8

// motor pins
#define motorPin1  4     // IN1 on the ULN2003 driver 1
#define motorPin2  5     // IN2 on the ULN2003 driver 1
#define motorPin3  6     // IN3 on the ULN2003 driver 1
#define motorPin4  7     // IN4 on the ULN2003 driver 1

#define motorPin5  8     // IN1 on the ULN2003 driver 2
#define motorPin6  9     // IN2 on the ULN2003 driver 2
#define motorPin7  10    // IN3 on the ULN2003 driver 2
#define motorPin8  11    // IN4 on the ULN2003 driver 2

#define motorPin9  A1     // IN1 on the ULN2003 driver 3
#define motorPin10 A2     // IN2 on the ULN2003 driver 3
#define motorPin11 A3    // IN3 on the ULN2003 driver 3
#define motorPin12 A4    // IN4 on the ULN2003 driver 3

#define motorPin13 2     // IN1 on the ULN2003 driver 4
#define motorPin14 3     // IN2 on the ULN2003 driver 4
#define motorPin15 12     // IN3 on the ULN2003 driver 4
#define motorPin16 13     // IN4 on the ULN2003 driver 4


// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
AccelStepper stepper2(HALFSTEP, motorPin5, motorPin7, motorPin6, motorPin8);
AccelStepper stepper3(HALFSTEP, motorPin9, motorPin11, motorPin10, motorPin12);
AccelStepper stepper4(HALFSTEP, motorPin13, motorPin15, motorPin14, motorPin16);

int stepperSpeed = 500; //speed of the stepper (steps per second)

// For the light sensor
int sensorPin = A0;    // select the input pin for the potentiometer
//int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor

const int sensorMin = 10;      // photosensor minimum, discovered through experiment
const int sensorMax = 600;    // photosensor maximum, discovered through experiment



void setup() {

 // initialize serial communication at 9600 bits per second:
 //Serial.begin(9600);

 delay(1000); //sime time to put the robot down after swithing it on

 stepper1.setMaxSpeed(2000.0);
 stepper1.move(1);
 stepper1.setSpeed(stepperSpeed);

 stepper2.setMaxSpeed(2000.0);
 stepper2.move(1);
 stepper2.setSpeed(stepperSpeed);

 stepper3.setMaxSpeed(2000.0);
 stepper3.move(1);
 stepper3.setSpeed(stepperSpeed);

 stepper4.setMaxSpeed(2000.0);
 stepper4.move(1);
 stepper4.setSpeed(stepperSpeed);
 
}

void loop() {
/*
 if (digitalRead(0) == HIGH){
   stepper1.move(10);
   stepper1.setSpeed(stepperSpeed);
   stepper1.run();
   
 }
*/  
 // read the sensor:
 int sensorReading = analogRead(A0);
 // map the sensor range to a range of four options:
 int range = map(sensorReading, sensorMin, sensorMax, 0, 4);
 
 // read the value from the sensor:
 sensorValue = analogRead(sensorPin);
 

 //Serial.println(sensorValue);

switch (range) {
   case 0:   // No light
     
     stepper1.moveTo(1024); //Open
     stepper1.setSpeed(stepperSpeed);
     stepper1.runSpeedToPosition();

     stepper2.moveTo(1024); //Open
     stepper2.setSpeed(stepperSpeed);
     stepper2.runSpeedToPosition();

     stepper3.moveTo(1024); //Open
     stepper3.setSpeed(stepperSpeed);
     stepper3.runSpeedToPosition();

     stepper4.moveTo(1024); //Open
     stepper4.setSpeed(stepperSpeed);
     stepper4.runSpeedToPosition();
     
     break;
   
   case 1:    // Low Light
     
     stepper1.moveTo(0); //Closed
     stepper1.setSpeed(stepperSpeed);
     stepper1.runSpeedToPosition();

     stepper2.moveTo(1024); // Open
     stepper2.setSpeed(stepperSpeed);
     stepper2.runSpeedToPosition();

     stepper3.moveTo(1024); //Open
     stepper3.setSpeed(stepperSpeed);
     stepper3.runSpeedToPosition();

     stepper4.moveTo(1024); //Open
     stepper4.setSpeed(stepperSpeed);
     stepper4.runSpeedToPosition();
     
     break;
   case 2:    // Medium Light
     //Serial.println("dim");
     //if (Shade1Closed == true){
       
     //OpenShade1(); //Open Shade 1
     //}


     stepper1.moveTo(0); //Closed
     stepper1.setSpeed(stepperSpeed);
     stepper1.runSpeedToPosition();

     stepper2.moveTo(0); //Closed
     stepper2.setSpeed(stepperSpeed);
     stepper2.runSpeedToPosition();

     stepper3.moveTo(1024); //Open
     stepper3.setSpeed(stepperSpeed);
     stepper3.runSpeedToPosition();

     stepper4.moveTo(1024); //Open
     stepper4.setSpeed(stepperSpeed);
     stepper4.runSpeedToPosition();
     
     break;
   case 3:    // High light

     stepper1.moveTo(0); //Closed
     stepper1.setSpeed(stepperSpeed);
     stepper1.runSpeedToPosition();

     stepper2.moveTo(0); //Closed
     stepper2.setSpeed(stepperSpeed);
     stepper2.runSpeedToPosition();

     stepper3.moveTo(0); //Closed
     stepper3.setSpeed(stepperSpeed);
     stepper3.runSpeedToPosition();

     stepper4.moveTo(1024); //Open
     stepper4.setSpeed(stepperSpeed);
     stepper4.runSpeedToPosition();

     break;
     
   case 4:    // Maximum light

     stepper1.moveTo(0); //Closed
     stepper1.setSpeed(stepperSpeed);
     stepper1.runSpeedToPosition();
     
     stepper2.moveTo(0); //Closed
     stepper2.setSpeed(stepperSpeed);
     stepper2.runSpeedToPosition();

     stepper3.moveTo(0); //Closed
     stepper3.setSpeed(stepperSpeed);
     stepper3.runSpeedToPosition();

     stepper4.moveTo(0); //Closed
     stepper4.setSpeed(stepperSpeed);
     stepper4.runSpeedToPosition();
     
     break;
 }
 
 delay(3);        // delay in between reads for stability
}

Robin2

To make it easy for people to help you please modify your post and use the code button </>
Code: [Select]
so your code looks like this and is easy to copy to a text editor. See How to use the Forum

Your code is too long for me to study quickly without copying to a text editor.

Also please use the AutoFormat tool to indent your code for easier reading.


What precisely do you mean by "they tend to judder on occasion"

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

mattclubb

Sorry about that. I've reformatted the message now.

So when they judder it looks like the drivers are only getting some of the inputs, the motors sound like they're moving 1 step at a time with a short delay between, and they don't turn the full numbers of steps, therefore finishing out of position.

As soon as you remove any 1 motor & driver from the Uno the motors run smoothly.

MorganS

It may be a power issue. What happens when you disconnect one motor but leave its instructions in the code?

Note: never disconnect a stepper while the power is on. Always turn off the power before adjusting the connections.

The delay at the end is going to seriously limit the maximum speed available to your motors. Remove it.  You asked for a speed of 2000 steps per second but you're never calling any of the run...() functions more often than about 300 times per second, so it can't step any faster than that. The delay may also be the source of the inconsistency.
"The problem is in the code you didn't post."

mattclubb

When I leave the instructions in the code but it disconnect it the problem is just the same. (Always with the power off!)

The 3ms delay was recommended from an example I used. I will try removing it.

Speed isn't really a requirement, positioning is more important so perhaps I will try removing the delay and reducing the speed.

Thank you

Robin2

As soon as you remove any 1 motor & driver from the Uno the motors run smoothly.
Does that mean that you disconnect the motor and driver without making any change to the code?

If so I would suspect a hardware problem - perhaps an inadequate motor power supply. I presume you have tried disconnecting different motors.

In your program you have stepper1.setSpeed(stepperSpeed); in several places but the value of stepperSpeed is not changed so it would not be needed anywhere except in setup()

I also suggest you move the lines with runSpeedToPosition() out of the CASE tests and put them as the last thing in loop()

It looks as if your code will execute the lines within a CASE statement several time - as long as the test is true. That's not necessary. You only need to update the position once so I suggest you have a variable that records the fact that the position has been updated so that you don't repeat it - something like
Code: [Select]
if (range <= previousRange) {
    switch (range) {
        case 0:   // No light
        // etc

    

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

Robin2

When I leave the instructions in the code but it disconnect it the problem is just the same.
This overlapped with my Reply #5.

It now seems that the problem goes away if you comment out the code for one motor but still leave the hardware connected - is that correct?

If so the changes I suggested to the code may help.

...R
Two or three hours spent thinking and reading documentation solves most programming problems.

mattclubb

Thank you all for your input. I have now resolved the problem.

I've implemented the modifications you recommended and my code is now more efficient.

The problem however was a power issue. My 12V supply wasn't enough to run the 4 stepper motors.
If I disconnected any 1 or commented any 1 out of the code things ran smoothly.
So I put one of the motors on a separate 9V supply and drove the other 3 off the 12V supply and everything works perfectly.

Thanks again
Matt

My updated code:
Code: [Select]
#include <AccelStepper.h>
#define HALFSTEP 8

// motor pins
#define motorPin1  4     // IN1 on the ULN2003 driver 1
#define motorPin2  5     // IN2 on the ULN2003 driver 1
#define motorPin3  6     // IN3 on the ULN2003 driver 1
#define motorPin4  7     // IN4 on the ULN2003 driver 1

#define motorPin5  8     // IN1 on the ULN2003 driver 2
#define motorPin6  9     // IN2 on the ULN2003 driver 2
#define motorPin7  10    // IN3 on the ULN2003 driver 2
#define motorPin8  11    // IN4 on the ULN2003 driver 2

#define motorPin9  A1     // IN1 on the ULN2003 driver 3
#define motorPin10 A2     // IN2 on the ULN2003 driver 3
#define motorPin11 A3    // IN3 on the ULN2003 driver 3
#define motorPin12 A4    // IN4 on the ULN2003 driver 3

#define motorPin13 2     // IN1 on the ULN2003 driver 4
#define motorPin14 3     // IN2 on the ULN2003 driver 4
#define motorPin15 12     // IN3 on the ULN2003 driver 4
#define motorPin16 13     // IN4 on the ULN2003 driver 4


// Initialize with pin sequence IN1-IN3-IN2-IN4 for using the AccelStepper with 28BYJ-48
AccelStepper stepper1(HALFSTEP, motorPin1, motorPin3, motorPin2, motorPin4);
AccelStepper stepper2(HALFSTEP, motorPin5, motorPin7, motorPin6, motorPin8);
AccelStepper stepper3(HALFSTEP, motorPin9, motorPin11, motorPin10, motorPin12);
AccelStepper stepper4(HALFSTEP, motorPin13, motorPin15, motorPin14, motorPin16);

int stepperSpeed = 500; //speed of the stepper (steps per second)

// For the light sensor
int sensorPin = A0;    // select the input pin for the potentiometer
//int ledPin = 13;      // select the pin for the LED
int sensorValue = 0;  // variable to store the value coming from the sensor

// these constants won't change. They are the lowest and highest readings you
// get from your sensor:
const int sensorMin = 10;      // photosensor minimum, discovered through experiment
const int sensorMax = 600;    // photosensor maximum, discovered through experiment


void setup() {

  // initialize serial communication at 9600 bits per second:
  //Serial.begin(9600);

  stepper1.setMaxSpeed(2000.0);
  stepper1.move(1);  // I found this necessary
  stepper1.setSpeed(stepperSpeed);

  stepper2.setMaxSpeed(2000.0);
  stepper2.move(1);  // I found this necessary
  stepper2.setSpeed(stepperSpeed);

  stepper3.setMaxSpeed(2000.0);
  stepper3.move(1);  // I found this necessary
  stepper3.setSpeed(stepperSpeed);

  stepper4.setMaxSpeed(2000.0);
  stepper4.move(1);  // I found this necessary
  stepper4.setSpeed(stepperSpeed);
 
}

void loop() {
 
  // read the sensor:
  int sensorReading = analogRead(A0);
  // map the sensor range to a range of four options:
  int range = map(sensorReading, sensorMin, sensorMax, 0, 4);
 
  // read the value from the sensor:
  sensorValue = analogRead(sensorPin);

  //Serial.println(sensorValue);

 switch (range) {
    case 0:   // No light
      stepper1.moveTo(1024); //Open     
      stepper2.moveTo(1024); //Open     
      stepper3.moveTo(1024); //Open   
      stepper4.moveTo(1024); //Open
      break;
    case 1:    // Low Light
      stepper1.moveTo(0); //Closed
      stepper2.moveTo(1024); //Open
      stepper3.moveTo(1024); //Open
      stepper4.moveTo(1024); //Open
      break;
    case 2:    // Medium Light
      stepper1.moveTo(0); //Closed
      stepper2.moveTo(0); //Closed
      stepper3.moveTo(1024); //Open
      stepper4.moveTo(1024); //Open
      break;
    case 3:    // High light
      stepper1.moveTo(0); //Closed
      stepper2.moveTo(0); //Closed
      stepper3.moveTo(0); //Closed
      stepper4.moveTo(1024); //Open
      break;
     
    case 4:    // Maximum light
      stepper1.moveTo(0); //Closed
      stepper2.moveTo(0); //Closed
      stepper3.moveTo(0); //Closed
      stepper4.moveTo(0); //Closed
      break;
  }

  stepper1.setSpeed(stepperSpeed);
  stepper1.runSpeedToPosition();
  stepper2.setSpeed(stepperSpeed);
  stepper2.runSpeedToPosition();
  stepper3.setSpeed(stepperSpeed);
  stepper3.runSpeedToPosition();
  stepper4.setSpeed(stepperSpeed);
  stepper4.runSpeedToPosition();
  //delay(3);        // delay in between reads for stability
}

Go Up