Using Joysticks

This section is about direct control of the joints via two joysticks. Here, the control signals from the user are converted directly into movements of the robot arm. If you are not interested in direct control via joysticks, you can simply skip this section.

Joystick Test

It makes sense to test each joystick before installation and determine the available range of values. Typically, the joysticks provide values between 0 and 1024 (10 bit resolution).

Just connect as follows:

Arduino      Joystick
+5V               +5V
GND               GND
A0                VRx
A1                VRy

 
/* RobotArm
 * Joystick Test
 * Can be used to check which signals (range) the joystick delivers
 * Stefan Hager 2022
 */
  
void setup() 
{
   Serial.begin(9600); 
}

void loop() {
  int xPos = analogRead(A0);  // read analog input pin A0
  int yPos = analogRead(A1);

  Serial.print("X - Axis: ");
  Serial.print(xPos);
  Serial.print("      Y - Axis: ");
  Serial.println(yPos);
     
  delay(1000);
}     

Controlling 1 Servowith a Joystick

Pinout

Arduino           Device
A0                J1 VRx
9                 servo
GND               Battery GND (Important!!!)
 

/* RobotArm
 * Joystick Servo Control Test
 * Control a servo via joystick
 * Servo uses Pin 8
 * Jostick is on A0
 * Stefan Hager 2022
 */

#include <Servo.h>

Servo myServo;  

int position = 90; // current position of the servo
int speed = 2; // change in position = speed of the servo

void setup() 
{
   Serial.begin(9600); 
   myServo.attach(8);  // connect Servo with PIN 8
   myServo.write(position);
}

void loop() 
{
  int joy_input = analogRead(A1);  // read analog input pin A0

  if(joy_input < 400)
  {
    position = position - speed;
    if(position < 0)
    { 
      position = 0;
    }
  }
  if(joy_input > 700)
    {
    position = position + speed;
    if(position > 180)
    { 
      position = 180;
    }
  }
  myServo.write(position);
  Serial.println(position);
  delay(20);

}

Full Robotarm Control with 2 Joysticks

The following program allows direct control of all axes with two joysticks. In addition, the program outputs the current position of the servos after each movement. Thus you can use these positions later for the programming of automated sequences.

Move the arm over several positions to the desired target position. At each intermediate position, note the values for the individual joints. Later, you can use the program from step 3 to move the arm to specific target positions.

The Complete Setup

Pinout

Arduino           Device
A0                J1 VRx
A1                J1 VRy
A2                J2 VRx
A3                J2 VRy
9                 Base servo
10                Shoulder servo
11                Elbow servo
12                Gripper servo 
GND               Battery GND (Important!!!)
 
/* RobotArm
 * Full Joystick Control
 * Stefan Hager 2022
 */

#include <Servo.h>

// any joystick value between LOWER_LIMIT and UPPER_LIMIT is seen as neutral position
#define LOWER_LIMIT 400
#define UPPER_LIMIT 700


// limits 
#define LOW_POS 10
#define HIGH_POS 170


// use this define to control speed of the servo movement

// create all required objects from class Servo
Servo base;  
Servo shoulder;
Servo elbow;
Servo gripper;

int speed = 1; // change in position = speed of the servo
int outputcounter = 0; // control how often you want to see the servo positions

// ***** make sure that you use the REAL start position! *****
int basePos = 90;
int shoulderPos = 90;
int elbowPos = 90;
int gripperPos = 90;
  
  
void setup() 
{
  // opens serial port, sets data rate to 9600 bps
  Serial.begin(9600); 
  // check if the servos are connected as follows:
  base.attach(9);  
  shoulder.attach(10);  
  elbow.attach(11);  
  gripper.attach(12);  

  // set the servos to start positions
  Serial.println("Moving servos into base position ... "); 
  base.write(basePos); 
  delay(1000);
  shoulder.write(shoulderPos); 
  delay(1000);
  elbow.write(elbowPos); 
  delay(1000);
  gripper.write(gripperPos); 

  Serial.println("Robotarm is ready ... "); 
}

void loop() 
{
     // check each joystick input and move according joint
     moveBase();
     moveShoulder();
     moveElbow();
     moveGripper();
     delay(20);
     printPositions();
}


// printPositions: prints position of each joint in following oder:
// B: base | S: shoulder | E: elbow | G: gripper

void printPositions()
{
  outputcounter++;
  if(outputcounter < 15)
  {
    return;
  }
  Serial.print("B: ");
  Serial.print(basePos);
  Serial.print(" | S: ");
  Serial.print(shoulderPos);
  Serial.print(" | E: ");
  Serial.print(elbowPos);
  Serial.print(" | G: ");
  Serial.println(gripperPos);
  outputcounter = 0;
}

// control base - servo with A0
void moveBase()
{
  int a0_input = analogRead(A0);  // read analog input pin A0
  if(a0_input < LOWER_LIMIT)  
  {   
    basePos = basePos - speed;
    if(basePos < LOW_POS)
    { 
      basePos = LOW_POS;
    }
  }
  if(a0_input > UPPER_LIMIT)  
  {    
     basePos = basePos + speed;
     if(basePos > HIGH_POS)
     { 
        basePos = HIGH_POS;
     }
  }
  base.write(basePos); 
}

// control shoulder - servo with A1
void moveShoulder()
{
  int a1_input = analogRead(A1);  // read analog input pin A0
  if(a1_input < LOWER_LIMIT)  
  {   
    shoulderPos = shoulderPos - speed;
    if(shoulderPos < LOW_POS)
    { 
      shoulderPos = LOW_POS;
    }
  }
  if(a1_input > UPPER_LIMIT)  
  {    
     shoulderPos = shoulderPos + speed;
     if(shoulderPos > HIGH_POS)
     { 
        shoulderPos = HIGH_POS;
     }
  }
  shoulder.write(shoulderPos); 
}

// control elbow - servo with A2
void moveElbow()
{
  int a2_input = analogRead(A2);  // read analog input pin A0
  if(a2_input < LOWER_LIMIT)  
  {   
    elbowPos = elbowPos - speed;
    if(elbowPos < LOW_POS)
    { 
      elbowPos = LOW_POS;
    }
  }
  if(a2_input > UPPER_LIMIT)  
  {    
     elbowPos = elbowPos + speed;
     if(elbowPos > HIGH_POS)
     { 
        elbowPos = HIGH_POS;
     }
  }
  elbow.write(elbowPos); 
}

// control gripper - servo with A3
void moveGripper()
{
  int a3_input = analogRead(A3);  // read analog input pin A0
  if(a3_input < LOWER_LIMIT)  
  {   
    gripperPos = gripperPos - speed;
    if(gripperPos < LOW_POS)
    { 
      gripperPos = LOW_POS;
    }
  }
  if(a3_input > UPPER_LIMIT)  
  {    
     gripperPos = gripperPos + speed;
     if(gripperPos > HIGH_POS)
     { 
        gripperPos = HIGH_POS;
     }
  }
  gripper.write(gripperPos); 
}