Arduino UNO and PCA9685 PWM Servo Controller for Joystick-Controlled Robotic Arm
View and Edit Project In Cirkit Designer
Circuit Documentation
Summary
This circuit is designed to control three micro servos using an Arduino UNO and a PCA9685 PWM Servo Breakout. The servos are controlled via two joystick modules, allowing for precise movement. The circuit is powered by a 9V battery.
Component List
Adafruit PCA9685 PWM Servo Breakout
- Description: A 16-channel PWM driver that can control up to 16 servos or LEDs.
- Pins: 5.0V, GND, PWRIN, PWM0-PWM15, VCC, SDA, SCL, OE
Arduino UNO
- Description: A microcontroller board based on the ATmega328P.
- Pins: UNUSED, IOREF, Reset, 3.3V, 5V, GND, Vin, A0-A5, SCL, SDA, AREF, D0-D13
Micro servo 9G
- Description: A small and lightweight servo motor.
- Pins: GND, +5V, PWM
Joystick module
- Description: A module with two potentiometers and a push button, used for controlling servos.
- Pins: SW, VRY, VRX, VCC, GND
9V Battery
- Description: A standard 9V battery used to power the circuit.
- Pins: -, +
Wiring Details
Adafruit PCA9685 PWM Servo Breakout
- PWRIN connected to + of 9V Battery
- GND connected to - of 9V Battery
- PWM2 connected to PWM of Micro servo 9G
- 5.0V connected to +5V of Micro servo 9G
- GND connected to GND of Micro servo 9G
- PWM1 connected to PWM of Micro servo 9G
- 5.0V connected to +5V of Micro servo 9G
- GND connected to GND of Micro servo 9G
- PWM0 connected to PWM of Micro servo 9G
- 5.0V connected to +5V of Micro servo 9G
- GND connected to GND of Micro servo 9G
- VCC connected to 5V of Arduino UNO, VCC of Joystick module, VCC of Joystick module
- SDA connected to A4 of Arduino UNO
- SCL connected to A5 of Arduino UNO
- GND connected to GND of Arduino UNO, GND of Joystick module, GND of Joystick module
Arduino UNO
- 5V connected to VCC of Adafruit PCA9685 PWM Servo Breakout, VCC of Joystick module, VCC of Joystick module
- A4 connected to SDA of Adafruit PCA9685 PWM Servo Breakout
- A5 connected to SCL of Adafruit PCA9685 PWM Servo Breakout
- GND connected to GND of Adafruit PCA9685 PWM Servo Breakout, GND of Joystick module, GND of Joystick module
- A0 connected to VRX of Joystick module
- A1 connected to VRY of Joystick module
- A2 connected to VRX of Joystick module
Micro servo 9G
- PWM connected to PWM2 of Adafruit PCA9685 PWM Servo Breakout
- +5V connected to 5.0V of Adafruit PCA9685 PWM Servo Breakout
- GND connected to GND of Adafruit PCA9685 PWM Servo Breakout
Micro servo 9G
- PWM connected to PWM1 of Adafruit PCA9685 PWM Servo Breakout
- +5V connected to 5.0V of Adafruit PCA9685 PWM Servo Breakout
- GND connected to GND of Adafruit PCA9685 PWM Servo Breakout
Micro servo 9G
- PWM connected to PWM0 of Adafruit PCA9685 PWM Servo Breakout
- +5V connected to 5.0V of Adafruit PCA9685 PWM Servo Breakout
- GND connected to GND of Adafruit PCA9685 PWM Servo Breakout
Joystick module
- VCC connected to VCC of Adafruit PCA9685 PWM Servo Breakout, 5V of Arduino UNO
- GND connected to GND of Adafruit PCA9685 PWM Servo Breakout, GND of Arduino UNO
- VRX connected to A0 of Arduino UNO
Joystick module
- VCC connected to VCC of Adafruit PCA9685 PWM Servo Breakout, 5V of Arduino UNO
- GND connected to GND of Adafruit PCA9685 PWM Servo Breakout, GND of Arduino UNO
- VRX connected to A2 of Arduino UNO
- VRY connected to A1 of Arduino UNO
9V Battery
- + connected to PWRIN of Adafruit PCA9685 PWM Servo Breakout
- - connected to GND of Adafruit PCA9685 PWM Servo Breakout
Code Documentation
#include <Servo.h>
// Servo objects
Servo shoulderServo, elbowServo, gripperServo;
// Joystick pins
const int shoulderJoystickPin = A0;
const int elbowJoystickPin = A1;
const int gripperJoystickPin = A2;
// Servo pins
const int shoulderServoPin = 9;
const int elbowServoPin = 10;
const int gripperServoPin = 11;
// Default servo positions
const int startShoulderPosition = 90;
const int startElbowPosition = 90;
const int startGripperPosition = 180;
// Dead zone settings
int deadZoneCenter = 512; // Center point of the joystick
const int deadZoneRange = 50; // Range considered as the dead zone
// Debugging toggle
const bool debugEnabled = true;
// Calibration button pin (optional, connect to a push button or jumper)
const int calibrateButtonPin = 7;
// Setup function
void setup() {
// Attach servos to pins
shoulderServo.attach(shoulderServoPin);
elbowServo.attach(elbowServoPin);
gripperServo.attach(gripperServoPin);
// Initialize servos to start positions
moveServoToPosition(shoulderServo, startShoulderPosition);
moveServoToPosition(elbowServo, startElbowPosition);
moveServoToPosition(gripperServo, startGripperPosition);
// Setup serial for debugging
if (debugEnabled) {
Serial.begin(9600);
Serial.println("System initialized.");
}
// Calibrate joystick dead zone
pinMode(calibrateButtonPin, INPUT_PULLUP); // Pull-up for button
deadZoneCenter = calibrateJoystickCenter();
if (debugEnabled) {
Serial.print("Calibrated Dead Zone Center: ");
Serial.println(deadZoneCenter);
}
}
// Main loop
void loop() {
// Check for recalibration request
if (digitalRead(calibrateButtonPin) == LOW) {
deadZoneCenter = calibrateJoystickCenter();
if (debugEnabled) {
Serial.println("Joystick recalibrated.");
}
}
// Control servos
controlServoWithJoystick(shoulderJoystickPin, shoulderServo, "Shoulder");
controlServoWithJoystick(elbowJoystickPin, elbowServo, "Elbow");
controlServoWithJoystick(gripperJoystickPin, gripperServo, "Gripper");
delay(20); // Stabilization delay
}
// Function to control a servo using joystick
void controlServoWithJoystick(int joystickPin, Servo &servo, const char *servoName) {
int joystickValue = smoothAnalogRead(joystickPin);
// Check dead zone
if (abs(joystickValue - deadZoneCenter) < deadZoneRange) {
if (debugEnabled) {
Serial.print(servoName);
Serial.println(": Joystick in dead zone, holding position.");
}
return; // Do nothing if in dead zone
}
// Map joystick value to servo angle
int servoAngle = map(joystickValue, 0, 1023, 0, 180);
moveServoToPosition(servo, servoAngle);
// Debugging
if (debugEnabled) {
Serial.print(servoName);
Serial.print(" Joystick Value: ");
Serial.print(joystickValue);
Serial.print(" -> Servo Angle: ");
Serial.println(servoAngle);
}
}
// Function to move a servo to a position
void moveServoToPosition(Servo &servo, int position) {
servo.write(position