Arduino + joystick + dc motor + servo motor

Hello everyone,

I am a beginner of Arduino. I am doing a claw machine project using an arduino uno, 2 x joystick modules, 2 x L298N motor shields, 3 dc motors, 1 servo motor and 1 power supply of 12V, 2A to archieve.

I have first written the following codes for using 2 x joystick modules, 2 x L298N motor shields and 3 dc motors to control the x and y axis as well as the up and down motion of the claw (everything works fine):

//Joystick Pins
int x1_key = A0;
int y1_key = A1;

int y2_key = A3;
int x1_pos;
int y1_pos;

int y2_pos;
//Motor Pins
int EN_A = 3;      //Enable pin for first motor
int IN1 = 2;       //control pin for first motor
int IN2 = 4;       //control pin for first motor
int IN3 = 5;        //control pin for second motor
int IN4 = 7;        //control pin for second motor
int EN_B = 6;      //Enable pin for second motor
int EN_C = 9;      //Enable pin for first motor
int IN5 = 10;       //control pin for first motor
int IN6 = 11;       //control pin for first motor

//Initializing variables to store data
int motor_speed;
int motor_speed1;
int motor_speed2;

void setup ( ) {
Serial.begin (9600); //Starting the serial communication at 9600 baud rate
//Initializing the motor pins as output

pinMode(EN_A, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(EN_B, OUTPUT);
pinMode(IN5, OUTPUT);
pinMode(IN6, OUTPUT);
pinMode(EN_C, OUTPUT);
//Initializng the joystick pins as input
pinMode (x1_key, INPUT);
pinMode (y1_key, INPUT);

pinMode (y2_key, INPUT);

}
void loop () {
x1_pos = analogRead (x1_key) ;  //Reading the horizontal movement value
y1_pos = analogRead (y1_key) ;  //Reading the vertical movement value

y2_pos = analogRead (y2_key) ;  //Reading the vertical movement value


if (x1_pos < 400){     //Rotating the left motor in clockwise direction
motor_speed = map(x1_pos, 400, 0, 0, 100);   //Mapping the values to 0-255 to move the motor
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(EN_A, motor_speed);
}
else if (x1_pos>400 && x1_pos <600){  //Motors will not move when the joystick will be at center
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

else if (x1_pos > 600){    //Rotating the left motor in anticlockwise direction
motor_speed = map(x1_pos, 600, 1023, 0, 100);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(EN_A, motor_speed);
}

if (y1_pos < 400){         //Rotating the right motor in clockwise direction
motor_speed1 = map(y1_pos, 400, 0, 0, 100);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(EN_B, motor_speed1);
}
else if (y1_pos>400 && y1_pos <600){
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}

else if (y1_pos > 600){        //Rotating the right motor in anticlockwise direction
motor_speed1 = map(y1_pos, 600, 1023, 0, 100);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(EN_B, motor_speed1);
}



if (y2_pos < 400){         //Rotating the right motor in clockwise direction
motor_speed2 = map(y2_pos, 400, 0, 0, 100);
digitalWrite(IN5, HIGH);
digitalWrite(IN6, LOW);
analogWrite(EN_C, motor_speed2);
}
else if (y2_pos>400 && y2_pos <600){
digitalWrite(IN5, LOW);
digitalWrite(IN6, LOW);
}

else if (y2_pos > 600){        //Rotating the right motor in anticlockwise direction
motor_speed2 = map(y2_pos, 600, 1023, 0, 100);
digitalWrite(IN5, LOW);
digitalWrite(IN6, HIGH);
analogWrite(EN_C, motor_speed2);
}

}

And then when i add the codes for the rest servo motor (x2 axis), the servo motor works but the dc motor controlling the up and down motion shows no response. Is there a way that i can fix the error?

#include <Servo.h>
Servo myservo;  // create servo object to control a servo
int pos = 5;    // variable to store the servo position and set zero
//Joystick Pins
int x1_key = A0;
int y1_key = A1;
int x2_key = A2;
int y2_key = A3;
int x1_pos;
int y1_pos;
int x2_pos;
int y2_pos;
//Motor Pins
int EN_A = 3;      //Enable pin for first motor
int IN1 = 2;       //control pin for first motor
int IN2 = 4;       //control pin for first motor
int IN3 = 5;        //control pin for second motor
int IN4 = 7;        //control pin for second motor
int EN_B = 6;      //Enable pin for second motor
int EN_C = 9;      //Enable pin for first motor
int IN5 = 10;       //control pin for first motor
int IN6 = 11;       //control pin for first motor

//Initializing variables to store data
int motor_speed;
int motor_speed1;
int motor_speed2;

void setup ( ) {
Serial.begin (9600); //Starting the serial communication at 9600 baud rate
//Initializing the motor pins as output
myservo.attach(12);  // attaches the servo on pin 12 to the servo object
pinMode(EN_A, OUTPUT);
pinMode(IN1, OUTPUT);
pinMode(IN2, OUTPUT);
pinMode(IN3, OUTPUT);
pinMode(IN4, OUTPUT);
pinMode(EN_B, OUTPUT);
pinMode(IN5, OUTPUT);
pinMode(IN6, OUTPUT);
pinMode(EN_C, OUTPUT);
//Initializng the joystick pins as input
pinMode (x1_key, INPUT);
pinMode (x2_key, INPUT);
pinMode (y1_key, INPUT);
pinMode (y2_key, INPUT);

}
void loop () {
x1_pos = analogRead (x1_key) ;  //Reading the horizontal movement value
y1_pos = analogRead (y1_key) ;  //Reading the vertical movement value
x2_pos = analogRead (x2_key) ;  //Reading the horizontal movement value
y2_pos = analogRead (y2_key) ;  //Reading the vertical movement value

if (x1_pos < 400){     //Rotating the left motor in clockwise direction
motor_speed = map(x1_pos, 400, 0, 0, 100);   //Mapping the values to 0-255 to move the motor
digitalWrite(IN1, LOW);
digitalWrite(IN2, HIGH);
analogWrite(EN_A, motor_speed);
}
else if (x1_pos>400 && x1_pos <600){  //Motors will not move when the joystick will be at center
digitalWrite(IN1, LOW);
digitalWrite(IN2, LOW);
}

else if (x1_pos > 600){    //Rotating the left motor in anticlockwise direction
motor_speed = map(x1_pos, 600, 1023, 0, 100);
digitalWrite(IN1, HIGH);
digitalWrite(IN2, LOW);
analogWrite(EN_A, motor_speed);
}

if (y1_pos < 400){         //Rotating the right motor in clockwise direction
motor_speed1 = map(y1_pos, 400, 0, 0, 100);
digitalWrite(IN3, LOW);
digitalWrite(IN4, HIGH);
analogWrite(EN_B, motor_speed1);
}
else if (y1_pos>400 && y1_pos <600){
digitalWrite(IN3, LOW);
digitalWrite(IN4, LOW);
}

else if (y1_pos > 600){        //Rotating the right motor in anticlockwise direction
motor_speed1 = map(y1_pos, 600, 1023, 0, 100);
digitalWrite(IN3, HIGH);
digitalWrite(IN4, LOW);
analogWrite(EN_B, motor_speed1);
}

if(x2_pos < 400){
  for (pos = pos; pos <= 55; pos += 1) { // goes from 0 degrees to 180 degrees
    // in steps of 1 degree
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
} else if (x2_pos>400 && x2_pos <600){
myservo.write(pos); } else{
for (pos = pos; pos >= 5; pos -= 1) { // goes from 180 degrees to 0 degrees
    myservo.write(pos);              // tell servo to go to position in variable 'pos'
    delay(15);                       // waits 15ms for the servo to reach the position
  }
}

if (y2_pos < 400){         //Rotating the right motor in clockwise direction
motor_speed2 = map(y2_pos, 400, 0, 0, 100);
digitalWrite(IN5, HIGH);
digitalWrite(IN6, LOW);
analogWrite(EN_C, motor_speed2);
}
else if (y2_pos>400 && y2_pos <600){
digitalWrite(IN5, LOW);
digitalWrite(IN6, LOW);
}

else if (y2_pos > 600){        //Rotating the right motor in anticlockwise direction
motor_speed2 = map(y2_pos, 600, 1023, 0, 100);
digitalWrite(IN5, LOW);
digitalWrite(IN6, HIGH);
analogWrite(EN_C, motor_speed2);
}

}

Thank you everyone.

Please read and use the topic "How to get the best out if this forum".
You missed posting the links the datasheets for all motors used. The wiring might be interesting too.
A guess is that the power supply is not up to the task. DC motors usually pull 5 to 10 times the normal current when starting. This is found as "stall current" in the datasheet.

The specification for the dc motors are DC Gearbox Motor - TT Motor - 200RPM - 3 to 6VDC : ID 3777 : $2.95 : Adafruit Industries, Unique & fun DIY electronics and kits

The specification is extracted below:

  • Rated Voltage: 3~6V
  • Continuous No-Load Current: 150mA +/- 10%
  • Min. Operating Speed (3V): 90+/- 10% RPM
  • Min. Operating Speed (6V): 200+/- 10% RPM
  • Stall Torque (3V): 0.4kg.cm
  • Stall Torque (6V): 0.8kg.cm
  • Gear Ratio: 1:48
  • Body Dimensions: 70 x 22 x 18mm
  • Wires Length: 200mm & 28 AWG
  • Weight: 30.6g

The schematic diagram:

The servo motor is SG90.
Specification: http://www.ee.ic.ac.uk/pcheung/teaching/DE1_EE/stores/sg90_datasheet.pdf

Thank you very much.

When i added the codes for servo motor, only the dc motor controlling the up and down motion for the claw does not work while the two dc motors controlling the x-axis and y-axis of the machine work properly so that I am really confused.

Also when i remove all servo motor's code, the dc motor controlling the up and down motion works properly again.

These blocking for loops in the servo part will make other things unresponsive. While the code is stuck in that for loop it isn't reading the joystick or doing anything else. I don't know how far the servo is having to move, but from 0 to 55 would take almost a second that your program is blind.

What is the load of the DC motor? No load, 150 mA can be like 750 - 1500 mA stall current.
If I'm correct the controller is powered by 12 volt to Vin. Just forget running any servo, and a speaker, from the Arduino 5 volt. It's overload several times.

Thank you Delta_G,

I have tried to amend the code to

if(x2_pos < 400){
myservo.write(55);
delay(15);
pos = 55;
}
else if (x2_pos>400 && x2_pos <600){
myservo.write(pos); }
else{
myservo.write(5);
delay(15);
pos = 5;
}

But the dc motor controlling the up and down motion of the claw is still unresponsive.

Thank you Railroader.

But the dc motors and servo motor will operate separately (only control 1 dc motor at a time) and so the max current drawn shall be 1500mA?

You diagram shows the Arduino supplying 5V power to the servo. This is a no-no, the Arduino can only power an led or two, NOT a servo.
Also, the breadboards can't handle motor currents or long without damage.

Thank you madmark2150.

what should i do for supplying the servo 5V and also the breadboard?

Use a separate +5 for the servo & Arduino. You can use a buck converter to get +5 from the existing +12 as long as its rated for the stall current of the servo motor plus enough to run the cpu.
Stall current = start current.
Use a terminal shield and 18ga wires for the motors for a permanent installation.


Terminal Shield for a Mega2560

shall i skip the breadboard and power the L298N directly from the power source?

Separately or not, You absolutely should not feed them from the Arduino 5 volt pin. The tiny conducting lines on the board are not sized for such current nor is the little naked 5 volt converter onboard.

Yes, power the L298 from the 12 volt power supply directly.

Thank you.

Have you checked the Servo library documentation?

I haven’t checked. Let me check the documentation.

Thank you, Seperlden.

Thank you Railroader.

Just checked the library, I downloaded it from library manager (Servo by Michael Margolis) before and the documentation should be ok but the either the dc motor does not work or the servo motor does not work.

I separated the power supply for L298N and servo motor but the dc motor for controlling up and down motion of the claw still does not work...