Proyecto electrónico – Escenario del programa «Atrapa un millón» #4

Continuo con las explicaciones de la parte de electrónica:

  • Etapa de control

Como he comentado anteriormente utilizaré una placa Arduino UNO para dicho control.  Esta placa, mediante la introducción de programa, sería la encargada de gestionar la apertura y el cierre de las puertas.  Una vez que tenemos alimentados los servomotores, debemos controlar su posición, y de esto se encargará la placa Arduino.  Pero debería existir algún tipo de entrada, botones o pulsadores, que permitieran a la persona que controlara la mesa decidir que puerta debería abrirse.  Así que decidí diseñar un mando con cuatro botones.  Los tres primeros servirían para abrir las tres puertas, y el último para hacer un reseteo de la mesa: todas las puertas volverían a la posición inicial.  El esquema de un mando así es muy sencillo:

Esquema del mando a distancia

Como se puede observar, necesitaremos cuatro entradas de nuestra placa Arduino.  Es un circuito sencillo, cuatro resistencias pull-down y los pulsadores.  La alimentación a 5V la traeré al mando desde la salida de 5V que tiene la placa Arduino.  Decidí que acomodaría los pulsadores en algún tipo de cajita de plástico, una que fuera pequeña.  Me acordé de la caja de plástico para guardar naipes que use para fabricar el tag de mi proyecto y pensé en emplear otra que tenía por ahí tirada.  Estas cajitas de plástico me gustan mucho porque son pequeñas y no se ven aparatosas.  El único inconveniente es que el plástico es tan sumamente debil que cualquier mal corte hace que se rompa en mil trozos.  Pero bueno para el proyecto era suficiente.

Aspecto del mando. Bonito bonito no es, pero bueno funciona jaja

Aqui podeis ver el aspecto final del mando.  Los pulsadores corresponden a Puerta 1, Puerta 2, Puerta 3 y Reseteo, respectivamente.  Los cuatro cables negros son los cables que van a las entradas del arduino, y el conector con los cables rojo y negro es la alimentación a 5V. Me hubiera gustado ponerle una pegatina o algo parecido encima con el logo del programa, para que solo se vieran los pulsadores y no los cables y el resto de componentes.  Pero no tuve tiempo y como solo era para mover las puertas decidí dejarlo así.  Los numeritos que se ven están en ambos extremos del cable y sirven para aclararse y no confundir un cable por otro.

Ahora hay que acabar de conectar los servomotores.  Si recordáis, los servomotores tenían 3 pines, dos de alimentación y uno de control.  Pues este último pin, el de control, será el que habrá que comunicar con las salidas del arduino.  Necesitaremos 6 salidas puesto que empleamos 6 servomotores.  Voy a poner un par de esquemas para clarificar el montaje (o eso espero :D):

Esquema gráfico del montaje completo, con Fritzing
Esquema del montaje completo, con Fritzing

Incluyo también una tabla para que el tema de las entradas y las salidas que uso en la placa Arduino quede más claro:

Relación del uso de las entradas y las salidas de la placa Arduino.

Y ahora una imagen de como quedó la parte de control de este esquema:

Placa Arduino UNO con todas las conexiones definitivas.

Con esto ya estaría montado todo el sistema electrónico de la mesa.  Pero todavía no funciona nada porque, obviamente, hay que programar la placa Arduino.  Como he dicho, con la placa Arduino, quiero conseguir que las puertas de la mesa se abran o cierren según los botones que pulse.  Lo primero era saber qué quería que sucediera al pulsar cada uno de los cuatro botones:

  • Pulsador P1 – Cuando se acciona, se abre la puerta 1 (Izquierda)
  • Pulsador P2 – Cuando se acciona, se abre la puerta 2 (Central)
  • Pulsador P3 – Cuando se acciona, se abre la puerta 3 (Derecha)
  • Pulsador Reseteo – Todas las puertas vuelven a su posición original

Con esto claro, me puse a programar la placa Arduino.  Hay varias formas de hacerlo, pero la oficial es utilizar la aplicación que pone a nuestra disposición el equipo Arduino, el entorno de desarrollo Arduino.  La última versión disponible en el momento de escribir esta entrada (10/06/2012) es la 1.0.1.

Voy a poner el código en varios fragmentos y explico brevemente:

#include <Servo.h>
#include <Bounce.h>

#define P1 2
#define P2 4
#define P3 7
#define RESETEO 8

Servo AperturaP1;
Servo CierreP1;

Servo AperturaP2;
Servo CierreP2;

Servo AperturaP3;
Servo CierreP3;

Bounce PulsadorP1 = Bounce(P1,5);
Bounce PulsadorP2 = Bounce(P2,5);
Bounce PulsadorP3 = Bounce(P3,5);
Bounce Reseteo = Bounce(RESETEO,5);

Decidí emplear dos librerías distintas para mi código. La primera es una librería que, como su nombre indica, me facilitará la faena de maniobrar con los servomotores. Es una librería extremadamente sencilla de utilizar.

La otra librería, Bounce.h, me servirá para evitar el rebote de los pulsadores. Cuando accionamos un pulsador, a nuestros ojos nos parece que solo se ha efectuado un solo clic, cuando en realidad se han producido varios. Puede parecer mentira pero es así. A la placa Arduino le llegan varias pulsaciones seguidas durante unas fracciones de segundo. Esto es debido a la construcción física de los pulsadores y no es algo específico de la placa Arduino; simplemente es así. Y este es un comportamiento no deseado. Existen varias formas de eliminar este problema. Algunas pueden ser mediante unas modificaciones en el esquema electrónico, y otras se pueden realizar por código. Una de ellas es observar dos veces el estado del pulsador durante un corto periodo de tiempo. Para ello hacía falta escribir más código del que deseaba, así que para ahorrarme código decidí emplear esta librería que se encargaba de hacer todo esto de forma casi automática, e iba a simplificarme la tarea de escribir el código.

Después defino las palabras P1, P2, P3 y RESETEO a los números 2, 4, 7 y 8, que son los números de los pines de Arduino que configuraré como entradas.

Creo los objetos que me permitirán controlar los servomotores; seis en total.

Las restantes líneas sirven para crear los objetos el tipo Bounce necesarios para el proyecto. Obviamente, tal y como he comentado, esta librería me permitía evitar el rebote de los pulsadores, con lo cual habrá que crear cuatro objetos, uno para cada entrada. Por ello vinculo cada objeto con una entrada, utilizando la definición asignada anteriormente, y decido configurar un tiempo de 5ms como tiempo de muestreo para el rebote; esto es el tiempo que pasará entre las dos veces que el programa observará el estado del pulsador, para evitar las interferencias descritas anteriormente. Escogí 5ms porque era el tiempo estándar, por así decirlo. Después de probar vi que no había ningún problema con los pulsadores, por lo tanto decidí dejar esta configuración.

void setup()
{
//Vinculamos los servos a una salida
AperturaP1.attach(9);
CierreP1.attach(3);

AperturaP2.attach(10);
CierreP2.attach(5);

AperturaP3.attach(11);
CierreP3.attach(6);

//Entradas mando
pinMode(P1, INPUT);
pinMode(P2, INPUT);
pinMode(P3, INPUT);
pinMode(RESETEO, INPUT);

ReseteoGeneral();
} 

Esta es la función setup() y se ejecutará una única vez: cuando arranque la placa Arduino. Sirve para configurar las entradas y salidas de la placa y también para inicializar variables del programa. Como he dicho, solo se ejecutará una sola vez, a no ser que pulsemos el botón de Reset de la placa Arduino. En ese caso volverá a ejecutarse.

Dentro de este bucle vinculo los objetos de la clase servo que cree a las salidas en las que están conectados los pines de control de cada servomotor. Estos pines de la placa Arduino quedarán configurados automáticamente como salidas. Después configuro los pines que utilizo como entradas, que si recordais, son la 2, 4, 7 y 8. Por último ejecuto la función ReseteoGeneral(). Esta función ha sido creada por mi, y es la que nos cerrará las puertas y pondrá los «pestillos» para que podamos comenzar a jugar con la mesa. Más adelante se verá el contenido de dicha función.

void loop()
{
PulsadorP1.update();
PulsadorP2.update();
PulsadorP3.update();
Reseteo.update();

int EstadoP1 = PulsadorP1.read();
int EstadoP2 = PulsadorP2.read();
int EstadoP3 = PulsadorP3.read();
int EstadoReset = Reseteo.read();

if (EstadoP1){
SecuenciaP1();
}

if (EstadoP2){
SecuenciaP2();
}

if (EstadoP3){
SecuenciaP3();
}

if (EstadoReset){
SecuenciaReseteo();
}
}

Esta es la función loop().  Se ejecutará de forma infinita hasta que se acabe el mundo, hasta que desconectemos la placa Arduino o se le acabe la batería :).  Lo que hacemos es actualizar la lectura del estado de los pulsadores y almacenarlo en unas variables creadas para tal efecto: EstadoP1, EstadoP2, EstadoP3, EstadoReset.  Después observamos que valor hay almacenado en dicha variable.  Si es 1, o sea, si el pulsador correspondiente se ha pulsado, se ejecuta la función correspondiente.  Por ejemplo, si hemos pulsado el botón 2, la variable EstadoP2 valdrá 1 y se ejecutará la función SecuenciaP2(), que es la que se encarga de abrir la puerta 2.

Ahora pongo el código de las funciones que son llamadas cuando se validan los if vistos en el código superior:

void SecuenciaP1(){

AperturaP1.write(90);
delay(1000);
}

void SecuenciaP2(){

AperturaP2.write(115);
delay(1000);
}

void SecuenciaP3(){

AperturaP3.write(90);
delay(1000);
}

void SecuenciaReseteo(){

ReseteoGeneral();
//ReseteoP1();
//ReseteoP2();
//ReseteoP3();
}

void ReseteoP1(){
CierreP1.write(55);
delay(1300);
AperturaP1.write(10);
delay(500);
CierreP1.write(135);
delay(500);
}

void ReseteoP2(){
CierreP2.write(55);
delay(1300);
AperturaP2.write(10);
delay(500);
CierreP2.write(138);
delay(500);
}

void ReseteoP3(){
CierreP3.write(55);
delay(1300);
AperturaP3.write(10);
delay(500);
CierreP3.write(138);
delay(500);
}

void ReseteoGeneral(){
AperturaP1.write(90);
AperturaP2.write(115);
AperturaP3.write(90);
CierreP1.write(47);
CierreP2.write(55);
CierreP3.write(61);
delay(900);
AperturaP1.write(10);
AperturaP2.write(10);
AperturaP3.write(10);
delay(500);
CierreP1.write(135);
CierreP2.write(138);
CierreP3.write(138);
delay(500);
}

Las funciones Secuencia P1, SecuenciaP2 y Secuencia P3 hacen lo mismo, pero cada una con respecto a un servo de apertura distinto.  Hacen que el servo correspondiente a la puerta que queremos abrir gire lo necesario para que esta se abra.

La función SecuenciaReseteo se llama cada vez que pulsamos el botón de Reset de nuestro mando.  Aquí dispuse de dos formas distintas de ejecutar este reset.  Ya que los servos de cierre consumen más que los otros por el hecho de que son capaces de ejercer más fuerza, decidí que crearía una función distinta para el reseteo de cada puerta.  De esta forma evitaría un pico de consumo muy alto que me debilitara las baterías de forma demasiado rápida.  De ahí salen las funciones ReseteoP1, ResteoP2 y ReseteoP3.  Las tres hacen lo mismo pero con respecto a una puerta distinta.  Primero se aseguran de que el servo de apertura esté en la posición de abrir.  Después accionan el servo de cierre para que suba la puerta, y hace que suba un par de centímetros más que la posición neutral de la puerta.  Después llevan el servo de apertura a la posición de cierre.  Por último el servo de apertura vuelve a la posición neutral.  Y la puerta queda cerrada.  Visto en acción se entiende de forma más clara, ya lo vereis.  Las funciones delay las puse para dejar que el servo llegara a la posición deseada antes de que el siguiente servo actuara.  De esta forma evitaba que, por ejemplo, el servo de apertura se activara antes que el de cierre y al subir la puerta esta chocara contra el brazo del servo y pudiera romper el invento, cosa que no quería que sucediera :D.

Pero al final resultó que las pilas de 9V no aguantaban ni un asalto, decidí crear otra función, ReseteoGeneral, que acciona el reseteo de todas las puertas a la vez.  La nueva batería aguantaba perfectamente los picos de intensidad que se producían al activar los tres servos de cierre, por lo tanto decidí utilizar este método de cierre que además me permitía cerrar las puertas en un tiempo menor.

Y este es todo el código.  Como he dicho, era muy sencillo.  No hay muchas florituras, pero es que las acciones que tiene que realizar la mesa tampoco dan para hacer más de lo que hay.  En la última entrada pondré el código en un archivo por si alguien quisiera descargárselo :).

Con esta entrada termino de hablar de las dos etapas en las que dividí la parte electrónica del montaje, la de potencia y la de control.  Cada vez me queda menos, si hay suerte una sola entrada más :)

Sigue leyendo la 5ª parte.  (Aun no está lista)

Anuncio publicitario

Una respuesta

  1. Pingback: Proyecto electrónico – Escenario del programa “Atrapa un millón” #3 « El rincón del electrónico

Deja una respuesta

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Salir /  Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Salir /  Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Salir /  Cambiar )

Conectando a %s