Felix Maocho

Para quien le interese lo que a nosotros nos interesa

1º Ejercicio de uso de pines digitales de entrada INPUT – Semáforo utilizando “if”

Félix Maocho
22/5/2016
.

Utilizar la función “if” para reducir el número de líneas del 2º Ejercicio de uso de pines digitales de Salida OUPUT – Semáforo

Conocimientos que se precisan

Para realizar este ejercicio tal como aquí se resuelve solo se necesitan los conocimientos que se han ido explicando hasta el capítulo dedicado al “Uso de los pines digitales como entrada (OUTPUT)”, y en lo referebte a la funcion “if” en Uso de los pines digitales como entrada (INPUT), que podemos resumir en los siguientes puntos:

  • Saber escribir, compilar y “subir” a la Tarjeta Arduino un sketch o programa
  • Conocer las funciones “int”, “pinMode”, “digitalWrite” y “display”
  • Conocer la función “if”

Material necesario

  • Tarjeta Arduino y cable de conexiones
  • Tarjeta de prototipado o “protoboard”
  • 9 Cables de conexiones macho/macho (preferiblemente 2 rojos, 2 verdes y 5 negros
  • 4 Resistencias de 220 Ω
  • 4 Led (preferible 2 de color rojo y 2 verdes)

Recordemos un poco aquel ejercicio. Se trataba de Simular un semáforo que regula el paso por el interior de un túnel. Las especificaciones del ejercicio fueron:

  • 1º.- En un extremos se acaba de poner la luz en verde mientras que en el otro extremo está en rojo. Así se mantiene 25 segundos.
  • 2º.- Para estimular el paso de los últimos coches, el verde se pone parpadeante cinco veces con periodos de encendido y apagados de un segundo. o sea esta así 10 segundos más, mientras que el otro extremo esta en rojo, el resto no cambian
  • 3º.- El semáforo se pone en rojo en un extremo, pero para dar tiempo a que salgan los coches que estuvieran dentro del túnel el otro extremo también continua en rojo durante otros 10 segundos

Se repite el proceso, pero en este caso el es otro extremo el que se pone en verde

Hardware

El hardware era tal como muestra el esquema:

Sketch5_5_2_Semaforo_bb

Y el sketch que manejaba el hardware era como sigue

/* Sketch E5.2 Simular de semáforo
* Izquierda (I), Derecha (D), Verde (V), Rojo (R )
* MAYUSCULAS = encendido, minúsculas = apagado
* 1º.- Circulación I >> D (IV) (ir) –- (dv) (DR) tiempo1
* 2º.- Circonio I >> D (IV) parpadea 5 veces (tiempo2) resto no cambian
* 3º.- No hay circulación (iv) (IR) –- (dv) (DR) tiempo3
* Se repite el proceso, pero en este caso es el otro extremo el que se pone en verde
* Repetir el ciclo
*/
// Área de definición de variables y parámetros ********************
int pindv = 10;
int pindr = 11;
int piniv = 12;
int pinir = 13;
int tiempo1 = 4000; // duración del 1º periodo
int tiempo2 = 400; // separación entre destellos cortos
int tiempo3 = 2000; // duración del 3º periodo
// Función setup ********************************************
void setup() {
// Pines abiertos como OUTPUT
pinMode(pindv, OUTPUT); // Pin 10
pinMode(pindr, OUTPUT); // Pin 11
pinMode(piniv, OUTPUT); // Pin 12
pinMode(pinir, OUTPUT); // Pin 13
}
// Función loop ********************************************
void loop() {
// 1º.- Circulación I >> D (IV) (ir) –- (dv) (DR) tiempo1 ***************
digitalWrite(piniv, HIGH);
digitalWrite(pindr, HIGH);
delay(tiempo1);
// 2º.- Circonio I >> D (IV) parpadea 5 veces (tiempo2) resto no cambian ****
// 1º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 2º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 3º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 4º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
//5º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// * 3º.- No hay circulación (iv) (IR) –- (dv) (DR) tiempo3 ****************
digitalWrite(piniv, LOW);
digitalWrite(pinir, HIGH);
delay(tiempo3);
// Fin del paso en una dirección apagamos los semáforos que están encendidos
digitalWrite(pindr, LOW);
// digitalWrite(pindr, LOW); (no es necesario apagar y encender)
// *******************************************************
// Se repite el proceso, pero en este caso el es otro extremo el que se pone en verde
// sea cambiar en los pin la “d” por la “i” y viceversa
// 1º.- Circulación I >> D (IV) (ir) –- (dv) (DR) tiempo1 ***************
digitalWrite(pindv, HIGH);
// digitalWrite(pinir, HIGH); (no es necesario apagar y encender)
delay(tiempo1);
// 2º.- Circonio I >> D (IV) parpadea 5 veces (tiempo2) resto no cambian ****
// 1º Vez ***************************************************
digitalWrite(pindv, LOW);
delay(tiempo2);
digitalWrite(pindv, HIGH);
delay(tiempo2);
// 2º Vez ***************************************************
digitalWrite(pindv, LOW);
delay(tiempo2);
digitalWrite(pindv, HIGH);
delay(tiempo2);
// 3º Vez ***************************************************
digitalWrite(pindv, LOW);
delay(tiempo2);
digitalWrite(pindv, HIGH);
delay(tiempo2);
// 4º Vez ***************************************************
digitalWrite(pindv, LOW);
delay(tiempo2);
digitalWrite(pindv, HIGH);
delay(tiempo2);
//5º Vez ***************************************************
digitalWrite(pindv, LOW);
delay(tiempo2);
digitalWrite(pindv, HIGH);
delay(tiempo2);
// * 3º.- No hay circulación (iv) (IR) –- (dv) (DR) tiempo3 ****************
digitalWrite(pindv, LOW);
digitalWrite(pindr, HIGH);
delay(tiempo3);
// Fin del paso en una dirección apagamos los semáforos que están encendidos
// digitalWrite(pindr, LOW); (no es necesario apagar y encender)
digitalWrite(pinir, LOW);
}

Nueva versión del software utilizando la funcion “if”

Lo que intentamos es aprovechar que la segunda parte del programa hace lo mismo que la primera pero en la otra boca del túnel, acortar la función “loop” a base de camiiar para los ciclos impares las asignaciones hechas de los pines. Dicho así resulta algo lioso por lo que prefiero escribir el programa y comentarlo después. El nuevo programa es como sigue.

Como es el mismo programa conservamos el nombre y tan solo añadimos al código del programa una a, que nos indicará que es la primera variación del mismo

/* Sketch E5.2.a Simular de semáforo
* Resolución utilizando la función “if”
* Los bucles impares dejaran pasar los coches de izquierda a derecha
* y los pares de derecha a izquierda para ello cambiaremos el valor del
* pin a las variables que se utilizan en las funciones “digitalWrite”
*/
// Área de definición de variables y parámetros ********************
int pina = 10; // Pin que maneja el verde de la izquierda
int pinb = 11; // Pin que maneja el rojo de la izquierda
int pinc = 12; // Pin que maneja el verde de la derecha
int pind = 13; // Pin que maneja el rojo de la derecha
int pindv = 0; // Variables que utilizaremos en “digitalWrite”
int pindr = 0;
int piniv = 0;
int pinir = 0;
int tiempo1 = 4000; // duración del 1º periodo
int tiempo2 = 400; // separación entre destellos cortos
int tiempo3 = 2000; // duración del 3º periodo
int par_impar = 0 ; // control de si es vuelta par o impar
// Función setup ********************************************
void setup() {
// Pines abiertos como OUTPUT
pinMode(pina, OUTPUT); // Pin 10
pinMode(pinb, OUTPUT); // Pin 11
pinMode(pinc, OUTPUT); // Pin 12
pinMode(pind, OUTPUT); // Pin 13
}
// Función loop ********************************************
void loop() {
// Control de si es vuelta par o impar
par_impar = par_impar +1; // añadimos i al valor de “par_impar”
if (par_impar == 2) { // si es igual a 2 le cambiamos a 0
par_impar = 0;
}
// Asignación de valores para las vueltas impares
if (par_impar == 1) {
pindv = pina ; // pindv recibe el valor “pina” = 10
pindr = pinb ; // pindr recibe el valor “pinb” = 11
piniv = pinc ; // pindv recibe el valor “pinc” = 12
pinir = pind ; // pindv recibe el valor “pind” = 13
}
// Asignación de valores para las vueltas pares
if (par_impar == 0) {
pindv = pinc ; // pindv recibe el valor “pinc” = 12
pindr = pind ; // pindr recibe el valor “pind” = 13
piniv = pina ; // pindv recibe el valor “pina” = 10
pinir = pinb ; // pindv recibe el valor “pinb” = 11
}
// 1º encendido verde de un lado y rojo del otro tiempo1 ***************
digitalWrite(piniv, HIGH);
digitalWrite(pindr, HIGH);
delay(tiempo1);
// 2º.- parpadea 5 veces la luz verde resto no cambian ****
// 1º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 2º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 3º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 4º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
//5º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// * 3º.- No hay circulación los dos rojos encendidos tiempo3 ****************
digitalWrite(piniv, LOW);
digitalWrite(pinir, HIGH);
delay(tiempo3);
// Fin del paso en una dirección apagamos el semáforo rojo del otro lado
digitalWrite(pindr, LOW);
// *******************************************************
}

Puntuación

Hemos añadido 5 lineas en el // Área de definición de variables y parámetros y 17 lineas en el “loop”, pero hemos quitado 41, es decir hemos eliminado 20 lineas mas o menos un 20%Con ello la puntuación de este nuevo sketch pasaría de ser un 6 que le dábamos antes a un 8, un notable alto,

Observaciones

Cambios en la función “setup”

Fíjense que he cambiado la función “setup” para inicializar los PINs de OUPUT con las variables que tienen ahora los valores de los pines a inicializar, pina, pinb, pinc y pind no con valores fijos o parámetros como lo habíamos hecho hasta el presente.Las variables, pina, pinb, pinc y pind son variables por que las inicio con cualquier valor en este caso a “0” pero antes de utilizarlas obtieben el valor que conviene en ese momento

digitalWrite” admite  variables

Observen que la función “digitalWrite” admite que sea una variable y no un parámetro el que indique cual es el pin que tiene que abrir o cerrar. No es normal utilizar esta posibilidad, pero es posible y a veces, como en este caso, conveniente.

Cómo saber si el “loop” es par o impar

El truco que he utilizado para llevar la cuenta de si es par o impar el loop que va a efectuarse consiste en crear una variable, en mi caso “ par_impar” y lo primero que hago cada vez que se inicia un nuevo loop es sumar 1 a su valor, para que vaya contando vueltas. Como solo quiero saber si es par o impar, el primer “if” cambia el valor de la variable “par_impar” a “0” cuando ha alcanzado el valor “2” , por ello la variable que inicialmente tenía el valor “0”, adquirirá el valor “1” para el primer “loop” , “2” que que se cambia a “0” para el segundo, nuevamente 1 para el tercero etc.

Sabido si es una vuelta par o impar asigno a las variables que utilizarla la función ““digitalWrite” los calores de los pines que controlan un extremo o las de los otros extremos así convenga. Esto es lo que se hace para simular multiprcesos.

Cdumperómo simular multitarea con Arduino

Este truco u otro parecido es muy corriente utilizarlo, porque también es es muy corriente en sketch, hacer cosas diferentes en las sucesivas vueltas del “loop”, cosas como apagar y encender, avanzar y retroceder, o cosas absolutamente diferentes como pueda ser en un dumper de obras conducir el dumper y mover un volquete, unas vueltas del “loop” las destinaremos a conducir y otras a manejar su volquete. Esto es el “truco” para hacer dos cosas diferentes simultáneamente en un aparato concebido solo para ser monotarea. Realmente cada vez se dedica solo a una cosa, pero al cambiar de tarea muy rápidamente hace la sensación de efectuar dos a la vez.

Manejo de la función “if”

Fíjense en el manejo de la función “if” La comparación viene situada entre paréntesis “(…)” y las funciones que se ejecutarán o no según sea cierta la comparación o no vienen entre corchetes “{…}”.

Diferencia entre “==” y “=”

También fíjense en la diferencia de uso del doble igual “==”, o identidad, con el uso del simple igual “=” o transferencia. En el primer caso compara si dos valores son iguales y en el segundo la variable, adquiere el valor de lo que hay situado a la derecha.

Utilización de la función “if / else”

Mi primera intención era haber cambiado el valor de la variable en la propia función “if” que asigna el valor a los pines si era el if de los pares dar a la variable el valor 1 y si era el de los impares el 0, pero no podía hacerlo, porque el programa pasa por los dos “if” y si había entrado en el primer “if” porque tenia el valor 1 y lo cambiaba a 0, pasaba por el segundo porque se lo encontraba un poco más abajo para ejecutarse si el valor era 0 Por eso de 1 paso a 2 y lo cambio en l siguiente loop, porque en este ya he asado por ese sitio.

Cambiar el valor se puede hacer y de hecho es corriente hacerlo, si se utiliza las dos funciones combinadas “if” / “else” porque en ese caso, solamente se ejecuta un sólo grupo de instrucciones de las dos posibles. A titulo solo de avance, pongo aquí la solución con “if” / “else” para que las comparen y vean anticipadamente como se utiliza este par de funciones combinadas

/* Sketch E5.2.b Simular de semáforo
* Resolución utilizando el Par de funciones “if” “else·
* Los bucles impares dejaran pasar los coches de izquierda a derecha
* y los pares de derecha a izquierda para ello cambiaremos el valor del
* pin a las variables que se utilizan en las funciones “digitalWrite”
*/
// Área de definición de variables y parámetros ********************
int pina = 10; // Pin que maneja el verde de la izquierda
int pinb = 11; // Pin que maneja el rojo de la izquierda
int pinc = 12; // Pin que maneja el verde de la derecha
int pind = 13; // Pin que maneja el rojo de la derecha
int pindv = 0; // Variables que utilizaremos en “digitalWrite”
int pindr = 0;
int piniv = 0;
int pinir = 0;
int tiempo1 = 4000; // duración del 1º periodo
int tiempo2 = 400; // separación entre destellos cortos
int tiempo3 = 2000; // duración del 3º periodo
int par_impar = 0 ; // control de si es vuelta par o impar
// Función setup ********************************************
void setup() {
// Pines abiertos como OUTPUT
pinMode(pina, OUTPUT); // Pin 10
pinMode(pinb, OUTPUT); // Pin 11
pinMode(pinc, OUTPUT); // Pin 12
pinMode(pind, OUTPUT); // Pin 13
}
// Función loop ********************************************
void loop() {
// Control de si es vuelta par o impar
// Asignación de valores para las vueltas impares
if (par_impar == 1) {
//Cambianos el valor a “0” para que en el siguiente loop no se haga este trozo
par_impar = 0 :
pindv = pina ; // pindv recibe el valor “pina” = 10
pindr = pinb ; // pindr recibe el valor “pinb” = 11
piniv = pinc ; // pindv recibe el valor “pinc” = 12
pinir = pind ; // pindv recibe el valor “pind” = 13
}
else {
// En otro caso (ciado “par_impar” no es uno
// Asignación de valores para las vueltas pares
//Cambianos el valor a “1” para que en el siguiente loop no se haga este trozo
par_impar = 1 :
pindv = pinc ; // pindv recibe el valor “pinc” = 12
pindr = pind ; // pindr recibe el valor “pind” = 13
piniv = pina ; // pindv recibe el valor “pina” = 10
pinir = pinb ; // pindv recibe el valor “pinb” = 11
}
// 1º encendido verde de un lado y rojo del otro tiempo1 ***************
digitalWrite(piniv, HIGH);
digitalWrite(pindr, HIGH);
delay(tiempo1);
// 2º.- parpadea 5 veces la luz verde resto no cambian ****
// 1º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 2º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 3º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// 4º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
//5º Vez ***************************************************
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
// * 3º.- No hay circulación los dos rojos encendidos tiempo3 ****************
digitalWrite(piniv, LOW);
digitalWrite(pinir, HIGH);
delay(tiempo3);
// Fin del paso en una dirección apagamos el semáforo rojo del otro lado
digitalWrite(pindr, LOW);
// *******************************************************
}

Utilización de la función “for”

Otra cosa que evidentemente se puede es reducir las veces en que se hace lo mismo, aquí el parpadeo solo es de cinco veces, pero imaginemos que fuera de cinco mil, tiene que haber una forma de hacer que una misma función se ejecute tantas veces como que ramos esa función es “for”

La función “for” se utiliza para repetir un bloque de instrucciones entre llaves. Generalmente se establece un contador que se va incrementando, hasta que deja de cumplirse una condición específica. No entramos aquí en mayor explicación sobre el tema, sólo indicar que su sintaxis es:

for (industrialización; condición; incremento) {

  • “For” es la función
  • “nacionalización” es la declaración del contador y suministro del valor inicial. En nuestro caso “int i=0”
  • “condición” es la condición que ha de cumplirse para que se repita el bloque de instrucciones. En nuestro caso “i <= 5; “)
  • “incremento” es la forma de aumentar el contador. En nuestro caso “i++”

Con ello se podría reducir aun más el sketch que estamos realizando, quedando tal como sigue

/* Sketch E5.2.c Simular de semáforo
* Resolución utilizando el Par de funciones “if” “else·
* y la función “for”·
* Los bucles impares dejaran pasar los coches de izquierda a derecha
* y los pares de derecha a izquierda para ello cambiaremos el valor del
* pin a las variables que se utilizan en las funciones “digitalWrite”
*/
// Área de definición de variables y parámetros ********************
int pina = 10; // Pin que maneja el verde de la izquierda
int pinb = 11; // Pin que maneja el rojo de la izquierda
int pinc = 12; // Pin que maneja el verde de la derecha
int pind = 13; // Pin que maneja el rojo de la derecha
int pindv = 0; // Variables que utilizaremos en “digitalWrite”
int pindr = 0;
int piniv = 0;
int pinir = 0;
int tiempo1 = 4000; // duración del 1º periodo
int tiempo2 = 400; // separación entre destellos cortos
int tiempo3 = 2000; // duración del 3º periodo
int par_impar = 0 ; // control de si es vuelta par o impar
// Función setup ********************************************
void setup() {
// Pines abiertos como OUTPUT
pinMode(pina, OUTPUT); // Pin 10
pinMode(pinb, OUTPUT); // Pin 11
pinMode(pinc, OUTPUT); // Pin 12
pinMode(pind, OUTPUT); // Pin 13
}
// Función loop ********************************************
void loop() {
// Control de si es vuelta par o impar
// Asignación de valores para las vueltas impares
if (par_impar == 1) {
//Cambianos el valor a “0” para que en el siguiente loop no se haga este trozo
par_impar = 0 :
pindv = pina ; // pindv recibe el valor “pina” = 10
pindr = pinb ; // pindr recibe el valor “pinb” = 11
piniv = pinc ; // pindv recibe el valor “pinc” = 12
pinir = pind ; // pindv recibe el valor “pind” = 13
}
else {
// En otro caso (ciado “par_impar” no es uno
// Asignación de valores para las vueltas pares
//Cambianos el valor a “1” para que en el siguiente loop no se haga este trozo
par_impar = 1 :
pindv = pinc ; // pindv recibe el valor “pinc” = 12
pindr = pind ; // pindr recibe el valor “pind” = 13
piniv = pina ; // pindv recibe el valor “pina” = 10
pinir = pinb ; // pindv recibe el valor “pinb” = 11
}
// 1º encendido verde de un lado y rojo del otro tiempo1 ***************
digitalWrite(piniv, HIGH);
digitalWrite(pindr, HIGH);
delay(tiempo1);
// 2º.- parpadea 5 veces la luz verde resto no cambian ****
for (int i=0; i <= 5; i++){
digitalWrite(piniv, LOW);
delay(tiempo2);
digitalWrite(piniv, HIGH);
delay(tiempo2);
}
// * 3º.- No hay circulación los dos rojos encendidos tiempo3 ****************
digitalWrite(piniv, LOW);
digitalWrite(pinir, HIGH);
delay(tiempo3);
// Fin del paso en una dirección apagamos el semáforo rojo del otro lado
digitalWrite(pindr, LOW);
// *******************************************************
}

Entraré a explicar el uso de “for” en otra ocasión solo quiero de momento que vean como simplifica la función. Mi intencion es solo anticipar algo el conocimiento de funciones de uso muy frecuente y simplemente oservar como paraa realizar una tarea hay muchísimos caaminos, capaces de realizrla, tan solo que algunos son más fáciles de transitar que otros, Indudabemente un Sketch con menos límeas es en principio más cómoco de escribir, de corregir y poner a punto.

Con los cuatro que he expuesto se consigue exactamente lo nismo sinular un semáforo según las especificaciones que nos dieron.

 

 

Félix Maocho

indice

22 mayo 2016 - Posted by | Curso de Arduino, Robotica | , , , ,

Aún no hay comentarios.

Responder

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. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: