Cirkit Designer LogoCirkit DesignerYour all-in-one circuit design IDE Launch Cirkit Designer App

Arduino-Controlled Robotic Arm with Servo Motors and Potentiometer Feedback

View and Edit Project In Cirkit DesignerImage of Arduino-Controlled Robotic Arm with Servo Motors and Potentiometer Feedback

Circuit Documentation

Summary

This circuit is designed to control multiple servos using an Arduino UNO and an Adafruit PCA9685 PWM Servo Breakout board. The servos are controlled by potentiometers and pushbuttons, with the ability to run predefined routines. The circuit is powered by a 12V battery, and the Arduino UNO communicates with the PCA9685 via I2C protocol. The PCA9685 board is used to generate PWM signals to control the servos, and the Arduino UNO reads the analog values from the potentiometers to determine the position of the servos. A toggle switch is used to control the power supply to the PCA9685 board.

Component List

Wiring Details

Arduino UNO

Rotary Potentiometers

Pushbuttons

Servos

Toggle Switches

Adafruit PCA9685 PWM Servo Breakout

12v Battery

Documented Code

#include <SoftwareWire.h>
#include <Wire.h>
#include <Adafruit_PWMServoDriver.h>

#define MIN_PULSE_WIDTH       650
#define MAX_PULSE_WIDTH       2350
#define FREQUENCY             50

Adafruit_PWMServoDriver pwm = Adafruit_PWMServoDriver();

const int pinSDA = A4;
const int pinSCL = A5;
SoftwareWire myWire(pinSDA, pinSCL);

int potMuneca = A3;
int potCodo = A2;
int potHombro = A1;
int potBase = A0;

int mano = 11;
int muneca = 12;
int codo = 13;
int hombro = 14;
int base = 15;

const int botonRutina1 = 2;
const int botonRutina2 = 3;
const int botonRutina3 = 4;

int rutinaActual = 0;

void ejecutarRutina();

void setup() {
  myWire.begin();
  Serial.begin(9600);
  delay(5000);

  pwm.begin();
  pwm.setPWMFreq(FREQUENCY);
  pwm.setPWM(11, 0, 90);

  pinMode(13,INPUT_PULLUP);
  pinMode(botonRutina1, INPUT_PULLUP);
  pinMode(botonRutina2, INPUT_PULLUP);
  pinMode(botonRutina3, INPUT_PULLUP);

  Serial.begin(9600);
}

void moveMotor(int controlIn, int motorOut) {
  int pulse_wide, pulse_width, potVal;

  potVal = analogRead(controlIn);

  pulse_wide = map(potVal, 800, 240, MIN_PULSE_WIDTH, MAX_PULSE_WIDTH);
  pulse_width = int(float(pulse_wide) / 1000000 * FREQUENCY * 4096);

  pwm.setPWM(motorOut, 0, pulse_width);
}

void loop() {
  myWire.beginTransmission(0x3C);
  myWire.write(0x00);
  myWire.endTransmission();

  if (digitalRead(botonRutina1) == LOW) {
    rutinaActual = 1;
    delay(200);
  } else if (digitalRead(botonRutina2) == LOW) {
    rutinaActual = 2;
    delay(200);
  } else if (digitalRead(botonRutina3) == LOW) {
    rutinaActual = 3;
    delay(200);
  }

  if (rutinaActual > 0) {
    ejecutarRutina();
  } else {
    moveMotor(potMuneca, muneca);
    moveMotor(potCodo, codo);
    moveMotor(potHombro, hombro);
    moveMotor(potBase, base);
  }
  int gripper = digitalRead(13);
  if(gripper == LOW) {
     pwm.setPWM(mano, 0, 180);
  } else {
     pwm.setPWM(mano, 0, 90);
  }
}

void ejecutarRutina() {
  switch (rutinaActual) {
    case 1:
      pwm.setPWM(mano, 0, 70);
      delay(100);
      pwm.setPWM(muneca, 0, 70);
      delay(100);
      pwm.setPWM(codo, 0, 70);
      delay(100);
      pwm.setPWM(hombro, 0, 70);
      delay(100);
      pwm.setPWM(base, 0, 70);
      delay(100);
      break;

    case 2:
      pwm.setPWM(mano, 0, 35);
      pwm.setPWM(muneca, 0, 35);
      pwm.setPWM(codo, 0, 45);
      pwm.setPWM(hombro, 0, 45);
      pwm.setPWM(base, 0, 45);
      break;

    case 3:
      pwm.setPWM(mano, 0, 120);
      pwm.setPWM(muneca, 0, 120);
      pwm.setPWM(codo, 0, 120);
      pwm.setPWM(hombro, 0, 120);
      pwm.setPWM(base, 0, 120);
      break;

    default:
      rutinaActual = 0;
      break;
  }

  rutinaActual = 0;
}

This code is responsible for reading the analog values from the potentiometers and mapping them to servo positions. It also includes routines that can be triggered by pushbuttons to move the servos to predefined positions. The SoftwareWire library is used to create a software I2C connection on pins A4 and A5, which are then used to communicate with the PCA9685 board. The Adafruit_PWMServoDriver library is used to control the PWM outputs for the servos. The ejecutarRutina function contains the predefined routines that can be executed when the corresponding pushbutton is pressed.