Introduction: CANDY/TOY CLAW MACHINE

El proyecto que se realizará será una máquina electrónica recoge dulces. Se recomienda tener experiencia previa trabajando con ensambles mecánicos, conexiones electrónicas, programación de software y modelado 3D.

Step 1: Material a Utilizar

  • Perfiles de aluminio 20x20mm 12
  • Esquina interna tipo L 90* 2020 14
  • Tornillos (tipo allen) 8mm 100
  • Hoja de acrilico 3mm 1200x900mm 1
  • Madera MDF 3
  • Cople flexible 5mm a 8mm 2
  • Tornillo lineal Husillo 8mm 2
  • Tornillos (Hexagonal M5) Paq. 24 pza T
  • Tuercas (para M5) Paq. 24 pza
  • Guía lineal eje acelerado 4
  • Chumacera 8mm KP08 2
  • Rodamiento Lineal 8mm 4
  • Soporte para eje lineal 8mm 8
  • Hilo 1
  • Tornillo (Hexagonal M4) 8
  • Tornillo (Estrella M2) 8
  • Garra Impresa 3D 1
  • Sensor Limit Switch SS0501A 3
  • Arduino Mega R3 con cable USB 1
  • Joystick X-Y ARD-358 1
  • Stepper Motor driver A4988 2
  • Stepper Motor Nema 17 con cables 2
  • Motor reductor 1:48 Doble eje 1
  • Fuente de voltaje 12V /6A 1
  • Jumpers MH-HM Paq. 50 pza
  • Cable
  • Resistencias 10k ohms
  • 3 Resistencias 68 ohms
  • CNC shield driver 1
  • Puente H L2982 1 1

Step 2: Funcionamiento General

La máquina desarrollada debe estar conectada a 120V para su funcionamiento. La máquina cuenta con dos modos de operación: manual y automático. Cada uno de estos modos de operación cuenta con un push button para activar el modo deseado por el usuario. También hay un tercer push button para accionar la garra únicamente cuando se encuentra en modo manual.

Si el usuario se encuentra en modo automático, puede interrumpir la función manual para maniobrar libremente la garra.

Para el movimiento en x y se utilizó un mecanismo de rosca que es actuado por los Nema 17. Para el movimiento en z se utilizó un motor reductor y a través de un delay nos fue posible controlar la altura a la que se desplaza.

Step 3: Ensamble Del Marco

Primeramente ensamblamos la parte superior e inferior del marco metálico. Se requiere unir los perfiles de aluminio 20x20 de 30 cm con una esquina interna tipo L 90* 2020.

Después de tener la parte inferior y superior es necesario unirlos con los perfiles de aluminio 20 x 20 de 50 cm. Para ensamblar la parte inferior con la superior también se utilizara una esquina interna tipo L 90* 2020.

Después de tener el marco de aluminio ya ensamblado es necesario agregar el mecanismo de movimiento x y, así como la base de acrílico de donde se sujetara la garra. A la base de acrílico es necesario colocar los soportes para eje lineal 8mm y también los motores Nema 17 que serán quienes muevan la garra en x y. Seguido de esto se acoplaron los rodamientos lineales para poder colocar la otra base de acrilico en donde se moverá en el eje restante.

Step 4: DISEÑO DE CUBRE MOTOR

El siguiente diseño es utilizado para sujetar y cubrir los motores Nema 17.

Step 5: DISEÑO DE GARRA

Step 6: DISEÑO DEL TABLERO

El siguiente diseño se utilizara para montar los botones de automático, manual, accionar garra y el joystick para el movimiento de la máquina.

Step 7: CORTES DE ACRILICOS

Se utilizara para sujetar la garra y los tornillos sin fin, en los cuales se moverá x y.

Step 8: CONEXIONES ELECTRICAS

Las conexiones eléctricas necesarias se muestran en la siguiente figura:

Tip: Las conexiones de alimentación de los motores deben llevar un cable de mayor calibre a los jumpers.

Step 9: PROGRAMACION

A continuación se muestra el código de programación utilizado para controlar la máquina electrónica recoge dulces.

// Incluímos la librería para poder controlar el servo
#include // Declaramos la variable para controlar el servo Servo servoMotor;

//Enable CNC board pin #define EN 8

//Direction pin #define X_DIR 5 #define Y_DIR 6

//Step pin #define X_STP 2 #define Y_STP 3

//Joystick Analog Pin #define X_KEY 8 #define Y_KEY 9

// H Bridge pin #define OUT1 26 // Puente H A1 #define OUT2 27 // Puente H A2

// Servo Pin #define GRIPPER 4

// Boton Joystick #define boton_activa_grua 28 #define boton_modo_automatico 29 #define boton_modo_manual 30

//DRV8825 int delayTime=1500; //Delay between each pause (uS) int stps=6400;// Steps to move char tipo_de_control; int state = 0; bool proceso_finalizado_automatico = false;

// Funcion que manda los pasos y direccion al stepper void step(boolean dir, byte dirPin, byte stepperPin, int steps) { digitalWrite(dirPin, dir); for (int i = 0; i < steps; i++) { digitalWrite(stepperPin, HIGH); delayMicroseconds(delayTime); digitalWrite(stepperPin, LOW); delayMicroseconds(delayTime); } }

void setup(){ pinMode(X_DIR, OUTPUT); pinMode(X_STP, OUTPUT); pinMode(OUT1, OUTPUT); pinMode(Y_DIR, OUTPUT); pinMode(Y_STP, OUTPUT); pinMode(OUT2, OUTPUT); pinMode(boton_modo_automatico, INPUT); pinMode(boton_modo_manual, INPUT); pinMode(boton_activa_grua, INPUT); pinMode(EN, OUTPUT); servoMotor.attach(GRIPPER); Serial.begin(9600); digitalWrite(EN, LOW); Serial.println("Selecciona el tipo de control M(Manual) A(Automatico)"); }

char selecciona_control_M_A(){ if(Serial.available()>0){ char opcion_seleccionada = Serial.read(); return opcion_seleccionada; } int boton_manual = digitalRead(boton_modo_manual); int boton_automatico= digitalRead(boton_modo_automatico); Serial.print("boton manual"); Serial.print(boton_manual); Serial.print("boton automatico"); Serial.println(boton_automatico); if(boton_manual == 1 || boton_automatico == 1){ delay(2000); if(boton_manual){ return 'M'; } else { return 'A'; } } }

void mueve_grua_a_la_izquierda(int pasos){ Serial.print("Moviendo grua a la izquierda"); step(false, X_DIR, X_STP, pasos); //X, Clockwise }

void mueve_grua_a_la_derecha(int pasos){ Serial.print("Moviendo grua a la derecha"); step(true, X_DIR, X_STP, pasos); //X, Clockwise }

void mueve_grua_hacia_arriba(int pasos){ Serial.print("Moviendo grua hacia arriba"); step(false, Y_DIR, Y_STP, pasos); //Y, Clockwise }

void mueve_grua_hacia_abajo(int pasos){ Serial.print("Moviendo grua hacia abajo"); step(true, Y_DIR, Y_STP, pasos); //Y, Clockwise }

void mueve_grua_con_joystick(){ int joystick_x_pos = analogRead (X_KEY); int joystick_y_pos = analogRead (Y_KEY); //Mueve Grua a la izquierda if(joystick_x_pos > 800){ mueve_grua_a_la_izquierda(40); } //Mueve Grua a la derecha else if(joystick_x_pos < 400){ mueve_grua_a_la_derecha(40); } // Mueve Grua hacia arriba else if(joystick_y_pos < 400){ mueve_grua_hacia_arriba(40); } //Mueve grua hacia abajo else if(joystick_y_pos > 800){ mueve_grua_hacia_abajo(40); } }

void mueve_grua_automatico(int x_cm, int y_cm){ long pasos_en_1_cm_desplazamiento = 160; //Cambiar el valor de 1000 al que corresponde al motor int x_steps = fabs(x_cm * pasos_en_1_cm_desplazamiento); // fabs es para obtener el valor absoluto int y_steps = fabs(y_cm * pasos_en_1_cm_desplazamiento); //Mueve grua a la derecha y arriba O solo muevela a la derecha O solo muevela arriba if(x_cm >= 0 && y_cm >= 0){ Serial.println("Mueve grua a la derecha y arriba O solo muevela a la derecha O solo muevela arriba"); mueve_grua_a_la_derecha(x_steps); mueve_grua_hacia_arriba(y_steps); } //Mueve grua a la izquierda y arriba O Solo muevela a la izquierda else if (x_cm < 0 && y_cm >= 0){ Serial.println("Mueve grua a la izquierda y arriba O Solo muevela a la izquierda "); mueve_grua_a_la_izquierda(x_steps); mueve_grua_hacia_arriba(y_steps);

} //Mueve grua a la derecha y abajo O solo muevela abajo else if (x_cm >= 0 && y_cm < 0){ Serial.println("Mueve grua a la derecha y abajo O solo muevela abajo"); mueve_grua_a_la_derecha(x_steps); mueve_grua_hacia_abajo(y_steps);

} //Mueve grua a la izquierda y abajo else if(x_cm < 0 && y_cm < 0){ Serial.println("Mueve grua a la izquierda y abajo"); mueve_grua_a_la_izquierda(x_steps); mueve_grua_hacia_abajo(y_steps); } }

void loop(){ tipo_de_control = selecciona_control_M_A();

if(tipo_de_control == 'M'){ proceso_finalizado_automatico = false; Serial.println("Control Manual Activado"); digitalWrite(EN, LOW); mueve_grua_con_joystick(); int valor_boton = digitalRead(boton_activa_grua); Serial.println(valor_boton); if(valor_boton == 1 && state == 0 ){ Serial.println("etapa 1"); activa_gripper(); state = state+1; } else if(valor_boton == 1 && state == 1 ){ Serial.println("etapa 2"); abre_gripper(); state = 0; } } else if(tipo_de_control == 'A' && proceso_finalizado_automatico == false){ Serial.println("Control Automatico Activado"); digitalWrite(EN, LOW); mueve_grua_automatico(4,4); activa_gripper(); mueve_grua_automatico(-4,-4 ); delay(2000); // Delay en lo que frena el regreso para soltar lo agarrado abre_gripper(); proceso_finalizado_automatico = true; Serial.println("Proceso automatico finalizado"); } else if(tipo_de_control == 'O'){ Serial.println("Apagando Mecanismo"); digitalWrite(EN, HIGH); } else if(tipo_de_control == 'R'){ Serial.println("resetea proceso automatico"); proceso_finalizado_automatico = false; } }

void abre_gripper(){ //Abre Gripper servoMotor.write(130); delay(2000); }

void cierra_gripper(){ //Cierra Gripper servoMotor.write(90); delay(2000); }

void activa_gripper(){ abre_gripper(); //Baja motor por 2 segundos digitalWrite(OUT1, HIGH); digitalWrite(OUT2, LOW); delay(2000); //Apaga Motor digitalWrite(OUT1, LOW); digitalWrite(OUT2, LOW); cierra_gripper(); //Sube motor por 3 segundos digitalWrite(OUT1, LOW); digitalWrite(OUT2, HIGH); delay(2000); //Apaga Motor digitalWrite(OUT1, LOW); digitalWrite(OUT2, LOW); }

Step 10: Conclusión

En conclusión, este proyecto requiere de mucho tiempo ya que pueden surgir detalles que pondrán a prueba al equipo. Este proyecto resultó muy divertido el llevarlo a cabo, además de los aprendizajes que nos llevamos de realizarlo. Consideramos que es un proyecto de mediana dificultad pero con la característica de ser replicado para servir otro propósito. También,consideramos que el tener a la disposición herramientas como impresoras 3D, corte laser, sierra cortadora y herramientas de laboratorio, facilitaron el desarrollo de este proyecto.

A continuación se adjunta el link del video del proyecto, donde se describe su funcionamiento y detalles del diseño mecánico y electrónico.