Proyecto 45 

Juego de la grúa

6 de octubre de 2019

Allá por mayo de 2018 publiqué un tutorial en el que veíamos cómo hacer una grúa como las que se pueden encontrar en las ferias y salones de máquinas recreativas.

Para el montaje de la grúa empleamos piezas y componentes reciclados de viejos equipos electrónicos y el control lo implementamos con una IceZUM Alhambra.

Prometí en su día que cuando tuviera tiempo migraría la parte de control a Arduino y como lo prometido es deuda, en el siguiente tutorial veremos cómo hacer la grúa con un Arduino NANO v3 para que cada uno elija la tarjeta que más le guste. 

En cuanto al montaje mecánico no cambia nada respecto del proyecto original, pero he decidido incluirlo también aquí para tener todo en un único tutorial.

1. Montaje de la grúa

Las siguientes imágenes son orientativas, para que os hagáis una idea de las piezas que componen la grúa. 

Vamos a necesitar ocho soportes en T, guías lineales y rodamientos de 8 mm. 

Una correa GT 2,5 mm, poleas varias y tres motores de CC con reductora. 

Un joystick y una botonera con cuatro pulsadores.

Y una pinza accionada mediante un servo tipo Futaba s3003.

En el siguiente vídeo explico el montaje de la grúa. Es el mismo vídeo que publiqué para la grúa con IceZUM.

2. Construcción de la urna

Una vez terminado el montaje mecánico, lo siguiente es hacer la urna donde colocaremos la grúa y los juguetes. Al final de la página dejo los planos para descargar en formato SketchUp.

Vamos a necesitar una base de MDF de 500 x 600 mm y 16 mm de espesor, cuatro listones de 20 x 20 mm y 560 mm de largo y otros cuatro de 20 x 30 mm y 460 mm de largo. Las maderas para la urna es de lo poco que he comprado para hacer la grúa, en total menos de 20 € en un gran almacén de bricolaje. 

Partimos de una base de MDF de 500 x 600 mm a la que atornillamos desde abajo los cuatro listones de 20 x 20 mm formando un cuadrado de 500 x 500 mm. Los 10 cm que dejamos libres en el frontal servirán para montar el joystick y la botonera.

En la parte superior de los listones que forman las columnas, atornillamos los cuatro listones de 20 x 30 x 460 de largo completando la estructura principal de la urna.

Dentro de la urna colocaremos una base auxiliar de 400 x 400 mm que es el área efectiva que se desplaza la grúa. Alrededor de la base atornillamos unas piezas de metacrilato a modo de paredes, dejando un hueco de 12 x 12 cm en el frontal para recoger los objetos que ganamos con la grúa. 

Con tres piezas de metacrilato haremos las tapas de la urna. La tapa frontal tiene un hueco en la esquina inferior izquierda por donde caerán los objetos. Dejamos la parte trasera libre para poder acceder al interior. 

A continuación montamos el joystick y la botonera en la parte frontal y para terminar introducimos la base auxiliar en el interior de la urna.

El metacrilato lo he reciclado de unos cuadros eléctricos, el joystick y la botonera también salieron de viejos aparatos electrónicos.

3. Fuente de alimentación 

Para alimentar la grúa voy a emplear una fuente de 12V y 4A.

Con los 12V de la grúa alimentamos el Arduino NANO a través de la entrada de alimentación Vin. Con los 5V del regulador interno del NANO alimentamos las salidas de los optoacopladores y señales lógicas de los drivers L293 en el pin 16 VCC.

4. Esquema

En este nuevo diseño para Arduino he simplificado los componentes necesarios, eliminando la fuente doble y el regulador L200C del proyecto original.

El circuito tiene tres partes: los pulsadores de entrada, el servo que acciona la pinza y los drivers L293D para los motores. Veamos cómo funciona.

4.1. Pulsadores y Optoacopladores

Hay ocho pulsadores para el control de movimientos. Cuatro corresponden al joystick para mover la grúa en los ejes X e Y. Los otros cuatro son los pulsadores de la botonera, de los cuales dos son para subir y bajar la pinza y los otros dos son para abrir y cerrar la pinza.

Como los mandos están situados lejos de la electrónica de control, implica que la longitud de los cables es elevada, lo que supone una caída de tensión. Si a esto sumamos los rebotes inherentes a los pulsadores y microswitches ya tenemos el lío montado en forma de ruido en las entradas del Arduino, lo que provoca un mal funcionamiento del circuito.

Para solucionar este problema he colocado cuatro optoacopladores Toshiba TLP504A lo más próximos posible a las entradas del Arduino. De esta forma eliminamos el ruido y mejoramos la respuesta del circuito.

He usado el TLP504A porque es el que tenía por casa, pero serviría cualquier otro optoacoplador de propósito general. El funcionamiento del circuito es muy sencillo; las resistencias en las entradas de los optoacopladores son para limitar la corriente que circula a través del fotodiodo, igual que en un led normal. Y las resistencias R3, R4, R7, R8, R11, R12, R15 y R16 son pull-down para asegurar que previo a pulsar un switch hay un 0 en las entradas del Arduino.


4.2. Servo para pinza robotica

El servo de la pinza lo he alimentado con un 7805 para no sobrecargar el regulador del Arduino NANO.


4.3. L293D Motor Driver

Por último tenemos los drivers L293D para los motores que mueven la grúa en los tres ejes. He utilizado un pequeño shield que viene con el integrado L293D soldado en placa y con los conectores necesarios para el control y alimentación, lo que facilita la conexión.

Un pequeño apunte. Tal como se aprecia en el esquema, el L293D necesita dos alimentaciones; una para los motores -de lo que corresponda- y otra de 5V para la lógica interna del integrado. Para este último propósito, el shield dispone de un regulador 78M05 que toma la tensión de los motores VIN para sacar 5V y cuyo uso desaconsejo porque si VIN es próxima a 5V va a ocasionar un mal funcionamiento del circuito. 

No es nuestro caso, ya que Vin es 12V, pero como voy a aprovechar los drivers del proyecto original, voy a inhabilitar el regulador y a alimentar el shiel con los 5V del NANO. Para deshabilitar el regulador desoldaremos la patilla de entrada. Tan solo hay que dar un poco de calor con el soldador y levantar la patilla con ayuda de un pequeño destornillador plano.

Y poco más que añadir. Más información sobre control de motores con Arduino y el circuito integrado L293D aquí.

5. Optoswitches Interface

Para reducir el cableado y facilitar el montaje del circuito, he diseñado con KiCad una tarjeta de interface entre los microswitches y el NANO. La PCB la he fresado con mi CNC siguiendo este tutorial. Al final de la página están todos los archivos disponibles para descargar, incluyendo el esquema, la tarjeta, y los gerber por si alguno se anima a hacer la PCB con una fresadora CNC.

5.1. Esquema

5.2. Optoswitches Interface PCB 

Optoswitches Interface. Lado componentes

El integrado que se ve en la imagen es un LM317 que añadí por si necesitaba alguna alimentación auxiliar, pero que elimine en la versión definitiva de la tarjeta.

Optoswitches Interface. Lado pistas

6. Sketch

El código para el Arduino es muy sencillo. Cada motor necesita de tres señales para funcionar; enableMotorX va en una salida PWM de manera que en función del valor de analogWrite(enableMotorX, 64) ajustamos la velocidad del motor X para que la grúa se mueva la velocidad deseada. Luego con in1MotorX y in2MotorX seleccionamos el sentido de giro para que el motor se mueva en la dirección correcta. Esto es válido para los tres motores.

Con una estructura switch / case Arduino NANO escucha que pulsador se activa en cada momento e invoca la función que corresponda. Si no se pulsa ningún botón la función void parar() deshabilita los motores.

/*

Proyecto 45 - Juego de la grua - Crane Game Machine

Written by Angel M.

https://sites.google.com/site/angmuz/

Public domain

*/


#include <Servo.h> 


int servoPin = 3; 

Servo servo; 

int angle = 90;   // servo position in degrees 


int enableMotorX = 11;

int in1MotorX = 10;

int in2MotorX = 8;


int enableMotorY = 6;

int in1MotorY = 7;

int in2MotorY = 9;


int enableMotorZ = 5;

int in1MotorZ = 4;

int in2MotorZ = 2;


int command = 0;


void setup()

{

  // Entradas

  pinMode(12, INPUT); // abrir   

  pinMode(13, INPUT); // cerrar

  pinMode(14, INPUT); // derecha   A0 = pin 14

  pinMode(15, INPUT); // izqda     A1 = pin 15

  pinMode(16, INPUT); // atras     A2 = pin 16

  pinMode(17, INPUT); // adelante  A3 = pin 17

  pinMode(18, INPUT); // subir     A4 = pin 18

  pinMode(19, INPUT); // bajar     A5 = pin 19


  servo.attach(servoPin);

  servo.write(angle);


  //Salidas

  pinMode(2, OUTPUT);

  pinMode(4, OUTPUT);

  pinMode(5, OUTPUT);

  pinMode(6, OUTPUT);

  pinMode(7, OUTPUT);

  pinMode(8, OUTPUT);

  pinMode(9, OUTPUT);

  pinMode(10, OUTPUT);

  pinMode(11, OUTPUT); 

 

}

 

void loop()

{



if (digitalRead(12)==HIGH)

    {

      command=12; // abrir

    }

if (digitalRead(13)==HIGH)

    {

      command=13; // cerrar

    }

if (digitalRead(14)==HIGH)

    {

      command=14; // derecha

    }

if (digitalRead(15)==HIGH)

    {

      command=15; // izquierda

    }

if (digitalRead(16)==HIGH)

    {

      command=16; // atras

    }

if (digitalRead(17)==HIGH)

    {

      command=17; // adelante

    }

if (digitalRead(18)==HIGH)

    {

      command=18; // subir

    }

if (digitalRead(19)==HIGH)

    {

      command=19; // bajar

    }


 switch(command)

 {


  case 12: abrirGrua();      break;

  case 13: cerrarGrua();     break;

  case 14: moverDerecha();   break;

  case 15: moverIzquierda(); break;

  case 16: moverAtras();     break;

  case 17: moverAdelante();  break;

  case 18: subirGrua();      break;

  case 19: bajarGrua();      break;

  default: parar();          break;

 }

 command=0;

}


void abrirGrua()

 {

  angle++;

  servo.write(angle);               

  delay(15);

  if (angle > 90) angle = 60;

 }

void cerrarGrua()

 {

  angle--;

  servo.write(angle);               

  delay(15);

 }


void moverDerecha()

  {

    analogWrite(enableMotorX, 64);

    digitalWrite(in1MotorX, LOW);

    digitalWrite(in2MotorX, HIGH); 

  }


void moverIzquierda()

  {

    analogWrite(enableMotorX, 64);

    digitalWrite(in1MotorX, HIGH);

    digitalWrite(in2MotorX, LOW);

  }


void moverAdelante()

  {

    analogWrite(enableMotorY, 80);

    digitalWrite(in1MotorY, HIGH);

    digitalWrite(in2MotorY, LOW); 

  }


void moverAtras()

  {

    analogWrite(enableMotorY, 80);

    digitalWrite(in1MotorY, LOW);

    digitalWrite(in2MotorY, HIGH);

  }


void subirGrua()

  {

    digitalWrite(enableMotorZ, HIGH);

    digitalWrite(in1MotorZ, HIGH);

    digitalWrite(in2MotorZ, LOW); 

  }


void bajarGrua()

  {

    digitalWrite(enableMotorZ, HIGH);

    digitalWrite(in1MotorZ, LOW);

    digitalWrite(in2MotorZ, HIGH);

  }


void parar()

  {

    digitalWrite(enableMotorX, LOW);

    digitalWrite(in1MotorX, LOW);

    digitalWrite(in2MotorX, LOW);

    digitalWrite(enableMotorY, LOW);

    digitalWrite(in1MotorY, LOW);

    digitalWrite(in2MotorY, LOW);

    digitalWrite(enableMotorZ, LOW);

    digitalWrite(in1MotorZ, LOW);

    digitalWrite(in2MotorZ, LOW);

    

  }


Puedes empezar a jugar la grúa con lo que hemos visto hasta aquí, pero si quieres ir un paso más lejos y dejar tu grúa fetén sigue leyendo porque vamos a añadir una tira de ledes para darle un poco de color.

Vamos a pegar una tira de ledes a cada lado de la urna, en la cara interior de los listones que forman la estructura. 

A continuación conectamos las dos tiras soldando cuatro cables de una tira a otra. 

No, la grúa no es peligrosa ni funciona con alta tensión. Ya dije un poco más arriba que el metacrilato lo había sacado de un cuadro eléctrico 😁

En este extremo conectamos la salida del driver.

El encendido de los ledes lo controlaremos mediante un ATtiny85 que dispara las puertas de un driver a transistores MOSFET. 

7. Esquema del driver para tira de ledes RBG

El driver lo he diseñado con KiCad a partir de un Mosfet Driver Module que se utiliza habitualmente con Arduino y al que dediqué este tutorial.

Partiendo del esquema original, he añadido un segundo integrado Mosfet Driver MIC4427 y dos transistores IRF630N. Los Mosfet los he recuperado de un puente en H para motores de CC, los componentes discretos se pueden encontrar fácilmente en cualquier tienda de electrónica y el integrado MIC4427 lo he comprado aquí.

El circuito se alimenta de los mismos 12V que el resto de tarjetas, pero ojo, el consumo ahora se va a incrementar en unos 2A. Tenedlo en cuenta a la hora de dimensionar correctamente la fuente de alimentación.

Si el dirver para los ledes te parece un poco complicado de montar, puedes utilizar este otro circuito más sencillo. 

 Siempre hay que comprobar que el transistor elegido tiene una corriente de colector mayor que la corriente que consumen los ledes.

7.1. Diseño de la PCB 

La tarjeta la he fresado con mi CNC (al igual que la microswitches interface). Lo de fresar PCB´s es alucinante, en media hora puedes tener lista una tarjeta medianamente compleja de 70x100 mm incluyendo los taladros. 

RGB Led Strip Mosfet Driver. Lado pistas.

RGB Led Strip Mosfet Driver. Lado componentes.

Así queda la parte de atrás de la grúa con todas las tarjetas conectadas. De izquierda a derecha podemos ver la Microswitches Interface, Arduino NANO, los drivers L293D para los motores de CC, el driver para la tira de ledes y el ATtiny85.

8. Sketch para ATtiny85

El código para el ATtiny lo he sacado del proyecto original de Robotic Arts donde explica cómo hacer unas zapatillas LED

Más info sobre Arduino y el ATtiny85 aquí

int blue = 2, red = 1, green = 0;

int c = 0, t_on = 0, t_off = 0;

float T = 0, f = 0;


void setup() {


  pinMode(blue,OUTPUT);

  pinMode(red,OUTPUT);

  pinMode(green,OUTPUT);

}


/*

 * Red to Yellow: Red: HIGH  and Green: FADE UP

 * Yellow to Green: Green: HIGH and Red: FADE UP

 * Green to Cyan: Green: HIGH and Blue: FADE UP

 * Cyan to Blue: Blue: HIGH and Green: FADE UP

 * Blue to Magenta: Blue: HIGH and Red: FADE UP

 * Magenta to Red: Red: HIGH and Blue: FADE UP

 */


void loop() {



WriteColor('r','b','g','u');

// Termina con BLUE al maximo y GREEN al minimo

WriteColor('r','b','g','d');

//Termina con RED al maximo y BLUE al minimo


  for(int i = 0; i<=255; i++){

    

    for(int j = 0; j<=10; j++){

      digitalWrite(blue,LOW);

      analogWrite(red,255-i);

      analogWrite(green,i);

      delayMicroseconds(2000);

    }

  }

//Termina con GREEN al maximo y RED al minimo 

}


void WriteColor(char high, char fade_up, char low, char adress){

  

  int led_H = 0, fade = 0, led_L = 0;


  switch(high){

  case 'r': led_H = red; break;

  case 'b': led_H = blue; break;

  case 'g': led_H = green; break;

  }

  

  switch(fade_up){

  case 'r': fade = red; break;

  case 'b': fade = blue; break;

  case 'g': fade = green; break;

  }


  switch(low){

  case 'r': led_L = red; break;

  case 'b': led_L = blue; break;

  case 'g': led_L = green; break;

  }

  

 // digitalWrite(led_H,HIGH);

 // digitalWrite(led_L,LOW);


  

  switch(adress){

  case 'u': c = 0; break; 

  case 'd': c = 255; break;

  }


  while(c<=255 && c>=0){


     

     f = 500; // 500 Herzts

     T = (1/f)*1000*1000;  // x1000 ya que está en us 

     //c = Ciclo de trabajo en %

     t_on = (c*T)/255; // Tiempo en alto

     t_off = T - t_on; // Tiempo en bajo


     if(adress == 'u'){ analogWrite(green,255-c); digitalWrite(red,LOW); }

     if(adress == 'd'){ analogWrite(red, 255-c); digitalWrite(green,LOW); }


     for(int i = 0; i<=10; i++){  

  

       digitalWrite(fade,HIGH);

       delayMicroseconds(t_on);

       digitalWrite(fade,LOW);

       delayMicroseconds(t_off);

      }

      

     switch(adress){

     case 'u': c++; break;

     case 'd': c--; break;

     }

  }

}


Eso es todo, espero que os haya gustado.

Links

Proyecto original con IceZUM Alhabra 

Control de Motores con Arduino y L293D

 Cómo hacer unas zapatillas LED. Gracias a Robotic Arts

Cómo grabar un ATtiny85 con Arduino aquí y aquí.


Dónde Comprar

Polea lisa 5 mm

Pinza robótica con servo

L293D Motor Shield


Descargas

Descarga los esquemas en KiCAD, los planos de la urna para SketchUp y el código de Arduino y ATtiny85