Como comenté en la última entrada, a partir de ahora los prototipos, pero sobre todo, los sketchs que vamos a implementar se van a complicar de manera considerable, resultando muy pesada la explicación pormenorizada de todo lo que hacemos. Por lo tanto, se dará una idea general de lo que queremos hacer, ver un poco como es el prototipo a implementar y el sketch vendrá bien comentado como siempre, pero dejaremos unas pinceladas de lo hecho. Comencemos con el Mini-Proyecto de hoy.
Vamos a realizar el sistema de intermitentes que va a usar nuestro
MotorDroid (que chulo suena... xD). De momento vamos a ir haciendo uso de pulsadores para el control de los comandos que va a tener el vehículo, posteriormente se hará mediante comandos desde un smartphone Android mediante bluetooth, intentando extrapolar las ideas básicas usadas con los pulsadores. En fin, no me adelanto y vamos a lo de hoy.
Usaremos para el montaje del prototipo dos leds amarillos (estoy esperando los naranjas...) que realmente serán cuatro, dos por pulsador (los dos izquierdos y los dos derechos), dos resistencias de 1KOmn y dos pulsadores. Conectaremos el pulsador izquierdo al pin 50 y el led izquierdo al pin 51 con cables azules; y los derechos con verdes al pin 22 y 23 respectivamente. A continuación vemos el sketch infinito que cargaremos en nuestro Arduino Mega para que realice esta función.
//Definimos los pines de los botones
#define IZQBOT 50
#define DERBOT 22
//Definimos los pintes de los leds
#define IZQLED 51
#define DERLED 23
//Definimos estados para los botones
boolean izq_fue_pulsado;
boolean der_fue_pulsado;
//Estados de los leds iniciados como apagados
int izqEstado = LOW;
int derEstado = LOW;
//Contadores de pulsaciones
int pulsacionesIzq;
int pulsacionesDer;
//Tiempo de parpadeo
const long parpadeo = 600;
//Tiempos previos
unsigned long tiempoPrevioI = 0;
unsigned long tiempoPrevioD = 0;
//Función 'Setup'
void setup(){
//Botones como entrada y abiertos
pinMode(IZQBOT, INPUT);
digitalWrite(IZQBOT, HIGH);
pinMode(DERBOT, INPUT);
digitalWrite(DERBOT, HIGH);
//Leds como salida
pinMode(IZQLED, OUTPUT);
pinMode(DERLED, OUTPUT);
//Inicialmente los botones no están pulsados
izq_fue_pulsado = false;
der_fue_pulsado = false;
//Número de pulsaciones
pulsacionesIzq = 0;
pulsacionesDer = 0;
//Inicializamos el puerto Serial
Serial.begin(9600);
}
//Funcion pulsar izquierda
boolean eventoPulsoIzq(){
//Evento a devolver
boolean evento;
//Comprobamos estado actual del botón
int izq_esta_pulsado = !digitalRead(IZQBOT);
//Boton pulsado ahora y no estaba pulsado
evento = izq_esta_pulsado & !izq_fue_pulsado;
//Actualizamos el estado del boton
izq_fue_pulsado = izq_esta_pulsado;
//Devolvemos el evento
return evento;
}
//Funcion pulsar derecha (Análogo a eventoPulsoIzq)
boolean eventoPulsoDer(){
//Evento a devolver
boolean evento;
//Comprobamos estado actual del botón
int der_esta_pulsado = !digitalRead(DERBOT);
//Boton pulsado ahora y no estaba pulsado
evento = der_esta_pulsado & !der_fue_pulsado;
//Actualizamos el estado del boton
der_fue_pulsado = der_esta_pulsado;
//Devolvemos el evento
return evento;
}
//Funcion parpadeo de led izquierdo
void parpadeoLedIZQ(){
//Obtenemos el tiempo actual
unsigned long tiempoActualI = millis();
//Si la diferencia es mayor que el intervalo de tiempo de parpadeo es cuando actualizamos el estado del led
if(tiempoActualI - tiempoPrevioI >= parpadeo) {
//Guardamos el instante de tiempo
tiempoPrevioI = tiempoActualI;
//Si el led esta encendido lo apagamos y viceversa
if (izqEstado == LOW)
izqEstado = HIGH;
else
izqEstado = LOW;
}
// Actualizamos el led
digitalWrite(IZQLED, izqEstado);
}
//Funcion parpadeo de led derecho
void parpadeoLedDER(){
//Obtenemos el tiempo actual
unsigned long tiempoActualD = millis();
//Si la diferencia es mayor que el intervalo de tiempo de parpadeo es cuando actualizamos el estado del led
if(tiempoActualD - tiempoPrevioD >= parpadeo) {
//Guardamos el instante de tiempo
tiempoPrevioD = tiempoActualD;
//Si el led esta encendido lo apagamos y viceversa
if (derEstado == LOW)
derEstado = HIGH;
else
derEstado = LOW;
}
// Actualizamos el led
digitalWrite(DERLED, derEstado);
}
//Funcion que añade linea al Serial
void lineaSerial(){
static int contador = 0;
if((++contador & 0x3f)==0){
Serial.println();
}
}
//Función 'Loop'
void loop(){
//Capturamos los eventos de los botones
boolean izqpulsado = eventoPulsoIzq();
boolean derpulsado = eventoPulsoDer();
//Actualizamos las pulsaciones
pulsacionesIzq += izqpulsado;
pulsacionesDer += derpulsado;
//Si el módulo 2 de las pulsaciones es 1 activamos el parpadeo
if((pulsacionesIzq%2) == 1 && (pulsacionesDer%2) == 0){
parpadeoLedIZQ();
}
if((pulsacionesDer%2) == 1 && (pulsacionesIzq%2) == 0){
parpadeoLedDER();
}
//Si el módulo 2 de las pulsaciones es 0 apagamos los leds
if((pulsacionesDer%2) == 0 && (pulsacionesIzq%2) == 0){
digitalWrite(DERLED, LOW);
digitalWrite(IZQLED, LOW);
}//Si un led estaba en función parpadeo al pulsar el otro, le sumamos 1 y lo apagamos
if((pulsacionesIzq%2) == 1 && (pulsacionesDer%2) == 1){
if(izqpulsado == 1){
pulsacionesDer += 1;
digitalWrite(DERLED, LOW);
}else if(derpulsado == 1){
pulsacionesIzq += 1;
digitalWrite(IZQLED, LOW);
}
}
//Mostramos el número de pulsaciones
Serial.print(pulsacionesIzq);
Serial.print(pulsacionesDer);
//Mostramos por Serial las pulsaciones
Serial.print(izqpulsado ? "I" : ".");
Serial.print(derpulsado ? "D" : ".");
//Añadimos líneas cada cierto tiempo
lineaSerial();
//Imponemos un retraso en el loop
delay(20);
}
Básicamente, tenemos que capturar los eventos de pulsación de los botones, que serán los encargados de decir a los leds si están apagados o haciendo el parpadeo sin
delay como vimos anteriormente. Contamos las pulsaciones para permutar el estado del led entre apagado o parpadeando, si el módulo 2 del número de pulsaciones es 1 entraremos en modo parpadeo, si es 0 se apagará. Además, cuando un led esta en función parpadeo y se pulse el botón del otro led se debe cambiar el estado del otro led además de poner en parpadeo el nuestro. Es decir, o están los dos leds apagados o sólo uno de los dos en modo parpadeo. Quizás en un futuro implemente con otro botón aparte la función estacionaria, haciendo que todos los leds parpadeen simultáneamente. Os dejo el vídeo de muestra para que veáis como funciona (que seguro no me habéis entendido... ^^'):