Adding Second Joystick For Servo Arm Precision

Hello everyone. I am following this servo arm tutorial video for a school project. I have little to no knowledge about Arduino, let alone coding for it. Right now, my project looks exactly like the video, but I want to add a second joystick for a more precise control of the arm. So one joystick will be controlling the up-down movement and another controlling left-right. How can I achieve this?

I have attached the servos and joysticks to the pins in the image below. Thank you very much.



This is the code, with only one joystick:

//Canal de YouTube -> RobotUNO
//Proyecto: Grua con servomotores
#include <Servo.h>
//Definicion de los servos
Servo servo1;
Servo servo2;
int eje1=90;
int eje2=90;
void setup(){  
  servo1.attach(7);
  servo2.attach(6);

  servo1.write(90);
  servo2.write(90);
}
void loop(){
  //SERVO 1
  if (analogRead(0)<200 && eje1<180){
    eje1++;
    servo1.write(eje1);
  }
  if (analogRead(0)>700 && eje1>0){
    eje1--;
    servo1.write(eje1);
  }
  //SERVO 2
  if (analogRead(1)<200 && eje2<180){
    eje2++;
    servo2.write(eje2);
  }
  if (analogRead(1)>700 && eje2>0){
    eje2--;
    servo2.write(eje2);
  }
  delay(15);
}

Welcome

Why not just connect RX of one joystick to A0, and RY of the other joystick to A1 (or the other way) ?

for more precision use linear slide potentiometers.

this sketch is from beginner. such joystick modules contain two potentiometers. if you connect an output of second joystick (or any other analog source) to A1 it works as you asked.

They way you use the servos, by angle, and the way you change their setting, limits your precision to one degree out of 180.

You could help the operator by limiting those steps to only being able to happen only a few times a second. Now they fire off so fast it is not possible easy to ,and on an exact degree.

Or, you could code the joystick to make only one step each time it went into the region where a step could be taken. Perhaps a mode could be controlled by a "fine tuning" button that when pressed woukd make the joysticks react to the change, rather than the condition.

See Files/Examlkes/02.Digital/StateChangeDetection on offer in the IDE, and google for the Arduino article on the subject.

If you switched to using pulse length in your servo calls, your range would be something like 1000..2000 microseconds, and might let a better servo reach a more exact position.

Either way, degrees or pukse length, will benefit from coding that allows single steps of whatever size to be easily ordered.

a7

#include <Servo.h>

Servo servo1;
Servo servo2;

void setup() {
  servo1.attach(7);
  servo2.attach(6);
}

void loop() {
  //SERVO 1
  servo1.write(analogRead(A0) / 5.683);

  //SERVO 2
  servo2.write(analogRead(A1) / 5.683);

  delay(10);
}

It's not clear that @Peter2506 has analog joysticks. Those in the picture look awfully like joyswitches.

And if they are on centering springs, getting to and maintaining a precise position will be something of a challenge.

So @Peter2506, whatcha got there, please post a part number or a link to where you obtained them.

a7

It was a PS2 XY Joystick Module


OK, so you are losing any help the joystick would be by treating it like multiple switches.

Get the joystick to increase or decrease the servo setting value, as you are now, but use its analog nature. I can't test the code form right here just now, so this may only be close:

float preciseValue = 90.0;

# define STEP 5   // fastest motion

void setup() {
  Serial.begin(115200);
  Serial.println("Joy to the World!\n);");
}

void loop() {
  int jValue = analogRead(A0);
  int increment = map(jValue, 0, 1023, -100, 100);

  preciseValue += STEP * increment / 100.0;

  if (preciseValue < 0.0) preciseValue = 0.0;
  if (preciseValue > 180.0) preciseValue = 180.0;

  int sValue = preciseValue;

  Serial.print(jValue); Serial.print("  ");
  Serial.print(increment); Serial.print("  ");
  Serial.print(preciseValue); Serial.print("  ");
  Serial.print(sValue); Serial.print("  ");

  Serial.println("");

  delay(50);    // limit to 20 steps / second no matter
}

This maintains the intended servo position as a floating point number, and uses the joystick to slowly or rapidly accumulate movement in the direction desired.

Cheap joysticks often have a build-in deadband. If yours do not, you may need to code for one or your servo may creep one direction or another when the stick is not beong moved off center.

HTH

a7

Further out on the "I can't test this" limb is the above with one servo:

# include <Servo.h>
Servo myServo;
 
float preciseValue = 90.0;
# define STEP 5   // fastest motion

void setup() {
  Serial.begin(115200);
  Serial.println("Joy to the World!\n);");

  myServo.attach(7);
}

void loop() {
  int jValue = analogRead(A0);
  int increment = map(jValue, 0, 1023, -100, 100);

  preciseValue += STEP * increment / 100.0;

  if (preciseValue < 0.0) preciseValue = 0.0;
  if (preciseValue > 180.0) preciseValue = 180.0;

  int sValue = preciseValue;

  Serial.print(jValue); Serial.print("  ");
  Serial.print(increment); Serial.print("  ");
  Serial.print(preciseValue); Serial.print("  ");
  Serial.print(sValue); Serial.print("  ");

  Serial.println("");

  myServo.write(sValue);

  delay(50);    // linit to 20 steps / second no matter
}

a7

Hello everyone. Thank you for all your replies. I now have the complete code and my project is functioning as intended. :+1: :man_bowing:

And by previous contractual agreement, you get to post the code that was your final solution.

This will help us know how we helped you, and it will help others who may come across this thread and wonder how it all worked out.

TIA

a7

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.