Llegados a este punto donde ya hemos visto muchos componentes que poder añadir a Arduino para hacer diferentes tipos de montajes, a partir de hoy, vamos a explicar cómo hacer una serie de proyectos que se puedan realizar en el aula en diferentes sesiones, en función del nivel de cada grupo de alumnos.
En este primer proyecto realizaremos un montaje de un parking domótico donde utilizaremos leds, botones, pantalla lcd, servomotor y un sensor de ultrasonidos. Queremos realizar un montaje que controle las operaciones tanto en la entrada como en la salida de vehículos.
En primer lugar comentamos el modo de funcionamiento del parking. Para entrar habrá que pulsar obligatoriamente un botón. En ese momento tienen que sucederse las siguientes operaciones:
- El led rojo se apagará y se encenderá el verde
- El servo girará 90º para levantar la barrera durante 3 segundos. Al bajar la barrera cambiarán los leds encendidos, estando el rojo de nuevo encendido.
- En la pantalla LCD mostraremos un mensaje de bienvenida en la segunda línea. En la primera línea tiene que aparecer siempre fijo el número de plazas disponibles.
- El contador de plazas disponibles, que inicialmente estará a 5 (nuestro parking tiene 5 plazas), disminuirá en uno su valor. Si el valor es 0 y estamos pulsando el botón de entrada tenemos que visualizar un mensaje de parking lleno y no dejar levantar la barrera.
Para salir un coche no necesitará pulsar un botón, ya que pondremos un sensor de ultrasonidos que detecte cuando un coche está en la rampa de salida, para desencadenar todas las operaciones relacionadas: cambiar estado de led, mensaje de salida en LCD, girar servo y aumentar plazas disponibles.
A estas alturas ya tenemos conocimientos de cómo montar cada uno de estos componentes, pero os vamos a dar una serie de consejos:
- Calcula bien el espacio entre componentes para que por ejemplo el botón pueda estar accesible para pulsar. Puede que necesites hacerlo en dos protoboards.
- Si vas a recrear un montaje en una maqueta real como nosotros, calcula bien la distancia de cables que necesitas para los leds. También puedes poner por debajo tacos de madera para elevar el montaje y poder pasar cables por debajo para que quede más limpio la parte superior.
- Monta los componentes, prueba de forma individual cada uno de ellos para que sepas que el montaje está bien hecho antes de ponerte a programar el parking.
- Incorpora 4 pilas AAA en un portapilas para que pueda ser autónomo el montaje.
A continuación podéis ver dos imágenes en diferentes perspectivas del montaje que hemos realizado:
En el siguiente vídeo Antonio Rey, alumno de 2º ESO, os explica unos cuantos consejos para realizar el montaje y el modo de funcionamiento.
A partir de aquí estamos preparados para comenzar con la parte de la programación.
En primer lugar deberemos tener anotados qué puertos digitales de Arduino hemos utilizado para cada uno de nuestros componentes. A continuación avanzamos los aspectos más importantes del código.
Necesitaremos incluir las librerías LiquidCrystal.h y Servo.h para poder utilizar las funciones relacionadas con el LCD y el servo.
Declarar todas las variables necesarias para programar nuestros componentes asociándoles los puertos de Arduino correspondientes, poner a OUTPUT los leds y el TriggerPin del ultrasonidos, y a INPUT el botón y el echoPin del ultrasonidos.
También declarar las variables necesarias para las operaciones: pos (posición del servo), buttonStateIn (estado del botón), plazasDisponibles (para gestionar plazas libres, inicializando a 5 ya que mi parking tiene 5 plazas), duration y distanceCm (para calcular la distancia del ultrasonidos con el que sabremos si hay un coche en la rampa de salida).
Al principio del loop() realizamos las siguientes operaciones iniciales:
- Realizar el disparo del ultrasonidos y guardar el valor correspondiente en la variable distanceCm.
- Mandar el mensaje al LCD. En la primera línea ponemos plazas disponibles. La segunda línea la dejaremos para el resto de mensajes.
- Poner el servo en la posición 0º
- Poner el led rojo a HIGH y el verde a LOW.
A partir de aquí, comprobaremos el estado del botón de entrada para saber si está siendo pulsado. Con un IF comprobamos si el estado del botón está a HIGH, y en caso de que sea cierto, preguntar en primer lugar IF plazasDisponibles==0 para de estar forma no hacer nada más que visualizar en la segunda línea del LCD “parking completo”. Si hay plazas, cambiar los estados de los leds, mover el servo a 90º, sacar un mensaje en 2º línea de “coche entrando”, realizar una pausa de 3 segundos, mover servo a 0º y disminuir el valor de plazasDisponibles.
El otro IF importante dentro del loop será donde preguntemos si hay coche en salida, utilizando los valores que nos dé el ultrasonidos.
A continuación os ponemos el código fuente en detalle:
// añadimos la librería para gestionar el LCD
#include <LiquidCrystal.h>
// inicializamos la librería del LCD con los números de los pines digitales donde lo vamos a conectar
LiquidCrystal lcd(7, 6, 5, 4, 3, 2);
//añadimos la librería para gestionar el servo
#include <Servo.h>
Servo myservo; // creamos un objeto para controlar el servo
int pos = 0; // variable para gestionar la posición del servo
// salidas digitales para semáforos rojo y verde
int ledPinRojo=8;
int ledPinVerde=9;
// pines para conectar el ultrasonidos. utilizamos los pines analógicos como digitales
const int EchoPin = 12;
const int TriggerPin =13;
// salida digital para botón entrada de parking y su respectivo estado
int buttonPinIn=11;
int buttonStateIn=0;
//variable para controlar cuantas plazas quedan libres. Inicializamos a 5 porque el parking estará vacío
int plazasDisponibles=5;
void setup() {
// inicializamos el LCD con 16 caracteres y 2 filas
lcd.begin(16, 2);
// Inicializamos los leds del semáforo
pinMode(ledPinRojo,OUTPUT);
pinMode(ledPinVerde,OUTPUT);
// Inicializamos el botón de entrada
pinMode(buttonPinIn,INPUT);
// Inicializamos la salida digital del servo en el pin 10
myservo.attach(10);
//Inicializamos los pines del ultrasonidos
pinMode(TriggerPin, OUTPUT);
pinMode(EchoPin, INPUT);
// Inicializamos el monitor serie
Serial.begin(9600);
}
void loop() {
// Realizamos todo el proceso para conocer la distancia del objeto más cercano al sensor de ultrasonidos
long duration, distanceCm;
digitalWrite(TriggerPin, LOW); //para generar un pulso limpio ponemos a LOW 4us
delayMicroseconds(4);
digitalWrite(TriggerPin, HIGH); //generamos Trigger (disparo) de 10us
delayMicroseconds(10);
digitalWrite(TriggerPin, LOW);
duration = pulseIn(EchoPin, HIGH); //medimos el tiempo entre pulsos, en microsegundos
// convertimos la duración a centimetros para luego preguntar si algo a menos de X cm es que hay coche esperando para salir
distanceCm = duration * 10 / 292/ 2; //convertimos a distancia, en cm
Serial.println(distanceCm);
// SITUAMOS CURSOR EN LA PRIMERA FILA (0) Y EN LA POSICIÓN DE CARACTER 0
lcd.setCursor(0, 0);
lcd.print("PLAZAS LIBRES: ");
// VISUALIZAMOS A CONTINUACIÓN LAS PLAZAS DISPONIBLES
lcd.print(plazasDisponibles);
//inicialmente colocamos la biela en la posición 0 (barrera bajada)
pos=0;
myservo.write(pos);
//leemos del botón entrada para saber si alguien quiere entrar
buttonStateIn=digitalRead(buttonPinIn);
Serial.println(buttonStateIn);
//ponemos el semáforo inicialmente a ROJO
digitalWrite(ledPinVerde,LOW);
digitalWrite(ledPinRojo,HIGH);
//preguntamos si está pulsado el botón de entrada
if (buttonStateIn==HIGH)
{
if (plazasDisponibles==0)
{
lcd.setCursor(0, 1);
lcd.print("COMPLETO");
}
else
{
// COCHE ENTRANDO, SEMAFORO VERDE Y SE CAMBIA POSICIÓN DE BIELA
digitalWrite(ledPinVerde,HIGH);
digitalWrite(ledPinRojo,LOW);
pos=90;
myservo.write(pos); // tell servo to go to position in variable 'pos'
//MOSTRAMOS MENSAJE EN PANTALLA DE COCHE ENTRANDO
lcd.setCursor(0, 1);
lcd.print("COCHE ENTRANDO");
//DESCONTAMOS PLAZA LIBRE
plazasDisponibles--;
delay(3000);
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
//comprobamos si la distancia es inferior a cm, en tal caso es hay coche esperando
if (distanceCm < 12)
{
// COCHE SALIENDO, SEMAFORO VERDE Y SE CAMBIA POSICIÓN DE BIELA
digitalWrite(ledPinVerde,HIGH);
digitalWrite(ledPinRojo,LOW);
pos=90;
myservo.write(pos); // tell servo to go to position in variable 'pos'
//MOSTRAMOS MENSAJE EN PANTALLA DE COCHE ENTRANDO
lcd.setCursor(0, 1);
lcd.print("COCHE SALIENDO");
//DESCONTAMOS PLAZA LIBRE
plazasDisponibles++;
delay(3000);
lcd.setCursor(0, 1);
lcd.print(" ");
}
}
Y con todo esto ya tendríamos resuelto nuestro primer montaje digno de ser expuesto en nuestra estantería de proyectos con Arduino. Después de todo.. ¿a que no era tan difícil?