lunes, 3 de agosto de 2015

Semáforos controlados por unidades de emergencia Segunda parte


En esta segunda parte del proyecto se explicaran las mejoras que se hicieron las cuales son:

1.- Saber qué tipo de unidad de rescate (ambulancia o patrulla) es la que activa el receptor infrarrojo para solicitar el cambio del estado próximo del semáforo

2.- Haciendo uso de un módulo de bluetooth en arduino enviar los datos pertenecientes a la unidad de rescate identificada, a una aplicación móvil


3.- La aplicación móvil de debe desplegar la información obtenida por el bluetooth, esta información indicara la fecha (dd/mm/yyyy), la hora (hh:mm:ss), tipo de unidad de rescate (ambulancia o patrulla), la calle y el número de semáforo por el que paso


4.- Como función extra  la aplicación móvil también es capaz de enviar SMS a algún otro dispositivo móvil con la misma información que esta aplicación despliega, la razón es muy simple y es que de este modo podemos enviar los datos a algún otro dispositivo que se encuentre fuera del rango de alcance del módulo bluetooth el cual es de aproximadamente 10 a 15 metros.



PROCEDIMIENTO:


Paso 1: Diferenciar las unidades de emergencia

Para poder identificar qué tipo de unidad de emergencia es la que requiere el cambio de estado del semáforo se podía hacer de varias formas, una de ellas era utilizando sensores de color o con sensores de contraste, estos sensores no los encontramos disponibles en las electrónicas cercanas solo comprado por mercado libre y debido a que no había tiempo suficiente para que nos llegase él envió decidimos seguir utilizando los receptores infrarrojos.
Cada unidad de rescate tiene un emisor de luz infrarroja ubicada a diferentes alturas de modo que cada unidad solo sea capaz de enviar el haz de luz proveniente de su emisor a un determinado receptor infrarrojo, en este caso las ambulancias son las que cargan el emisor infrarrojo en la parte baja y las patrullas en la parte de arriba con una diferencia de 3 cm entre ambos para evitar que un receptor infrarrojo detecte el equivocado.

  • -   Ambulancias con el emisor abajo
  • -   Patrullas con el emisor en la parte de arriba






Paso 2: Configuración del módulo bluetooth

Una vez solucionada la forma en que se identifica la unidad de rescate, procedimos a conectar el módulo de bluetooth, nosotros utilizamos el modelo HC-06 (Configuración bluetooth).


La conexión no es complicada, lo único que varía es que el pin RXD del módulo va conectado al pin TXD de arduino y el pin TXD del módulo al pin RXD de arduino, esto es debido a que el pin RXD se encarga de recibir datos y el TXD transmite datos, de esta forma los datos que se transmiten por del módulo en el pin TXD los recibe arduino en su pin RXD y los que recibe el modulo en RXD son los que le trasmite arduino en el pin TXD.

Para configurarlo utilizamos arduino y comandos AT, ejecute el siguiente código para configurar el modulo bluetooth.


char NOMBRE[5] = "B06"; //NOMBRE DEL BLUETOOTH
char BPS = '4'; //BAUDIOS 9600, 1 = 1200... 4 = 9600
char PASS[10] = "0000"; //CONTRASEÑA PARA VINCULAR EL DISPOSITIVO BLUETOOTH

void setup() {
  Serial.begin(9600);
  pinMode(13,OUTPUT);
  digitalWrite(13,HIGH);
  delay(10000);
  digitalWrite(13,LOW);

  Serial.print("AT");
  delay(1000);

  Serial.print("AT+NAME");
  Serial.print(NOMBRE);
  delay(1000);

  Serial.print("AT+BAUD");
  Serial.print(BPS);
  delay(1000);

  Serial.print("AT+PIN");
  Serial.print(PASS);
  delay(1000);
}



Una vez configurado el modulo Bluetooth es necesario vincularlo, para usarlo en la aplicación móvil posteriormente.



Paso 3:Crear la aplicación móvil

Para esto utilizamos una herramienta muy útil llamada APP INVENTOR (http://appinventor.mit.edu/explore/)



Esta aplicación nos facilita la creación de aplicaciones android, y es que básicamente para el desarrollo de una aplicación se basa en la creación de pantallas donde a cada pantalla tiene su vista es decir los elementos que son visibles para el usuario y el código que contiene las funciones de lo que realiza cada elemento dentro de la vista de la pantalla, en la vista se tienen distintos componentes como son botones, label, textbox, checkbox, etc, los cuales nos facilitan la construcción de la interfaz gráfica de usuario, el código se crea por medio de bloques de código los cuales no son más que todas las funciones o métodos que tiene cada elemento que se esté utilizando en la interfaz gráfica de usuario y también algunos otros elementos que se integren al proyecto pero que no son visibles para el usuario como son el bluetooth y el reloj.



Componentes utilizados para crear la aplicación:


Interfaz gráfica:


Explicación del código

Para conectar el dispositivo bluetooth del dispositivo móvil donde se encuentra ejecutando la aplicación móvil al módulo de bluetooth HC-06, lo primero que hicimos fue agregar un componente a la vista llamado list picker este componente posee dos métodos uno llamado BeforePicking este se encarga de realizar algo antes de que el list picker sea presionado, en este apartado se pregunta si el bluetooth del dispositivo móvil se encuentra disponible y si es así entonces obtiene todos los nombres de las direcciones bluetooth que se encuentran vinculadas al dispositivo móvil y estas a su vez  son agregadas como elementos al list picker, puesto que en el paso 2 ya hemos vinculado el modulo bluetooth este aparecerá dentro de esta lista.

Bloque de código BeforePicking


Después de agregar la lista de direcciones bluetooth al list picker, se utiliza el método AfterPicking este método se encarga de hacer algo después de que un elemento es seleccionado en el list picker, aquí lo que hacemos es conectar el bluetooth del dispositivo móvil utilizando el método Connectaddres del componente bluetooth este requiere de una dirección bluetooth y esta la obtenemos del elemento que se seleccione en el list picker.

Bloque de código AfterPicking


Una vez que logramos establecer una conexión entre ambos bluetooth, procedemos a configurar nuestro componente textbox, el cual estará recibiendo todos los mensajes que se reciban de arduino la cual contiene información perteneciente a la unidad de rescate que activo el receptor infrarrojo y  el semáforo al que se le solicito el cambio de estado.

Para esto utilizamos la función Timer del reloj, una función que se está ejecutando cada segundo lo primero que hacemos es verificar si el bluetooth está conectado y si los bytes que se dispone a recibir son mayores a 0, de cumplirse ambas funciones entonces en una variable global creada con anterioridad llamada btexto obtendrá los datos de la fecha actual (dd/mm/yyyy) y hora (hh:mm:ss) 

provenientes del componente reloj estos son concatenados con el tipo de vehículo, la calle por la que transita y numero de semáforo al que se le solicito el cambio de estado estos son enviados por arduino a través del módulo HC-06.

Una vez obtenida esta información en la variable btexto se la pasamos al componente textbox, debido a que el método set text de este componente sobrescribe todo lo que se tenía con anterior decidimos hacer un join el cual concatena todo lo que se tenía anteriormente en el textbox mas lo que se obtuvo en la variable global.

Posteriormente redactamos un SMS pesándole como texto, toda la información de la variable btexto, el número de teléfono el cual establecimos estático y el método SendMessage, que se encarga de enviar el mensaje

La razón por la que usamos una variable global es porque una vez utilizada la función ReceiveText para recibir el texto que envía arduino, estos datos son borrados de la función por ello tenemos que almacenarlos para que puedan ser enviados la primera vez al textbox y la segunda vez al texto del SMS, la variable global no hace falta limpiarla ya que el meto set sobrescribe todo lo que esta tenía anteriormente.


Bloque de código:





Paso 4: Armar el circuito 

Para armar el circuito lo  que se deben agregar es el modulo bluetooth y los dos receptores infrarrojos mas en cada calle los cuales deben estar un poco mas arriba que los utilizados en la parte anterior del proyecto 

Diagrama:


Paso 5: Creación y ejecución del código en arduino

Una vez armado el circuito, debe copiar y ejecutar el siguiente código, el cual es muy similar al utilizado en la parte 1 del proyecto ( Parte 1 );
.

int verde1 = 2;
int amarillo1 = 3;
int rojo1 = 4;

int verde2 = 6;
int amarillo2 = 7;
int rojo2 = 8;

int millisActuales;
int millisAnteriores=0;

int receptor1 = A1;
int receptor2 = A2;
int receptor3 = A3;
int receptor4 = A4;

int tiempo2 = 0;

void setup() {
  Serial.begin(9600);
 
  pinMode(verde1,OUTPUT);
  pinMode(amarillo1,OUTPUT);
  pinMode(rojo1,OUTPUT);
 
  pinMode(verde2,OUTPUT);
  pinMode(amarillo2,OUTPUT);
  pinMode(rojo2,OUTPUT);

  pinMode(receptor1,INPUT);
  pinMode(receptor2,INPUT);
}

void loop() {
  inicio(); 
}

void inicio(){
  millisActuales = millis();
  //Se leen los valores de los sensores infrarrojos 1 y 2
  int valor1 = analogRead(receptor1);
  int valor2 = analogRead(receptor2);
  int valor3 = analogRead(receptor3);
  int valor4 = analogRead(receptor4);

  /*
   * para calcular el tiempo exacto entre cada loop restamos los milisegundos del utimo loop (millisAnteriores) de los milisegundos actuales (millisActuales)
   * el primer loop los millisAnteriores son igual a 0, despues incrementan en 20,000 por loop y asi sucecivamente, esto se hace debido a que la funcion millis
   * no se puede reiniciar a no ser que se aplique un overflow
   *
   * Ahora tambien se agrega un valor mas, que es el tiempo2 cuya funcion es la de acelerar la trancicion de los semaforos de verde a rojo dependiendo de que semaforo sea
   *
   */ 
  int tiempo = millisActuales - millisAnteriores + tiempo2;
  if(tiempo < 7000){
    /*
     * semaforo 1 en verde y semaforo 2 en rojo por 7 segundos
     */
    digitalWrite(verde1,HIGH);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,LOW);
 
    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,HIGH);

    /*
     * Tras obtener el valor del sensor infrarrojo numero 2, es decir el sensor ubicado en el semaforo 2
     * se compara si este valor es mayor a 90, es decir, si detecto una luz infrarroja proveniente de la unidad
     * de rescate, si la condicion se cumple entonces al tiempo2 se le asigna el valor de los milisegundos que resten
     * para terminar el estado del semaforo 1 (que esta en verde) y acelerar su transicion a rojo, haciendo que el
     * semaforo 1 pase rapidamente de verde a amarillo, dando 3 segundo a los vehiculos a pasar o detenerse
     *
     */
    if(valor3 > 140 || valor4 > 140){
      tiempo2 = 7000 - (millisActuales - millisAnteriores);
      /*
       * Si el valor3 que corresponde al receptor infrarrojo 3 incrementa a más de 90 quiere decir que
       * detecto un haz de luz infrarrojo proveniente de la unidad de emergencia, la ambulancia es la unica capaz
       * de emitir un haz de luz al receptor infrarrojo 1 o 3 (valor1 o valor3), por lo tanto los datos enviados
       * al bluetooth hacen referencia a los de una ambulancia
       */
      if(valor3 > 140){
        Serial.println();
        Serial.println("Ambulancia A019");
        Serial.println("Av. Independencia");
        Serial.println("Semaforo: 327");
        Serial.println();
      }

      /*
       * De igual forma que con el if anterior este se hace para saber si fue una patrulla la que paso por
       * el receptor infrarrojo, enviado de esta forma al bluetooth los datos pertenecientes a una patrulla
       */
      if(valor4 > 140){
        Serial.println();
        Serial.println("Patrulla P043");
        Serial.println("Av. Independencia");
        Serial.println("Semaforo: 327");
        Serial.println();
      }
    }
  }
 
  if(tiempo > 7000 && tiempo < 10000){
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,HIGH);
    digitalWrite(rojo1,LOW);
 
    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,HIGH);
  }

  if(tiempo > 10000 && tiempo < 17000){
    /*
     * semaforo 1 en rojo y semaforo 2 en verde por 7 segundos
     */
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,HIGH);
 
    digitalWrite(verde2,HIGH);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,LOW);

    /*
     * Esta funcion es similar a la anterior del semaforo 1, solo que en esta se comprueba si el
     * sensor infrarrojo 1, que se encuentra en el semaforo 1 detecto luz infrarroja para acelerar
     * la transicion del semaforo 2 a rojo, pasando primero por un cambio a amarillo de 3 segundos
     * nuevamente para que los vehiculos tengan tiempo de pasar o detenerse.
     */
    if(valor1 > 140 || valor2 > 140){
      tiempo2 = 17000 - (millisActuales - millisAnteriores);

      /*
       * Solo la ambulancia es capaz de incrementar los valores del receptor infrarrojo 1 o 3 (valor1 o valor3)
       */
      if(valor1 > 140){
        Serial.println();
        Serial.println("Ambulancia A019");
        Serial.println("Av. Independencia");
        Serial.println("Semaforo: 327");
        Serial.println();
      }

      /*
       * Solo la patrulla es capaz de incrementar los valores del receptor infrarrojo 2 o 4 (valor2 o valor4)
       */
      if(valor2 > 140){
        Serial.println();
        Serial.println("Patrulla P043");
        Serial.println("Av. Independencia");
        Serial.println("Semaforo: 327");
        Serial.println();
      }
     
    }
  }

  if(tiempo > 17000 && tiempo < 20000){
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,HIGH);
 
    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,HIGH);
    digitalWrite(rojo2,LOW);
  }

  if(tiempo > 20000){
    /*
    * Una vez terminados 20 segundos el valor de millisAnteriores pasa a ser el de los millisActuales para que el
    * tiempo nunca supere los 20 segundos, y siempre sea un ciclo entre 0 y 20 segundos.
    */
    millisAnteriores = millisActuales;
   
    /*
     * La variable tiempo2 la tenemos definida global y su valor se mantiene tras realizarce cada loop por ello
     * que se resete su valor a 0
     */
    
    tiempo2 = 0;
  }
}



Paso 6: Pruebas







Nota: Puede descargar la aplicación móvil(.apk) o descargar el archivo del desarrollo de la aplicación 
(.aia) y realizar las modificaciones que desee en app inventor .





FIN  :)


-------------------------------------------------------------------------------

sábado, 25 de julio de 2015

Proyecto Vialidad Urbana: semáforos controlados por unidades de emergencia

En las ciudades muchos delitos o muertes pueden haber sido evitadas si la ayuda de una ambulancia o la policía hubiera llegado a tiempo, en Oaxaca gran parte de la sociedad carece de una cultura vial que ayude a las personas a recibir el auxilio por parte de las unidades de socorro de manera pronta y oportuna. Todos alguna vez hemos estado en carretera mientras alguna unidad de emergencia necesita circular con libertad mientras diversas unidades de motor tienen la imposibilidad de moverse debido a la cantidad de autos que desean circular o no tienen paso por parte del semáforo.


Objetivo:

Explicar como crear una maqueta que simula el control de semáforos por unidades de emergencia como ambulancias, bomberos, etc. utilizando el microcontrolador Arduino y sensores infrarrojos.

Materiales a utilizar:


Material Cantidad Precio Unitario Imagen Configuración
Arduino Uno: Para poder controlar el funcionamiento de los dispositivos 1 $300 Info
Protoboard : Placa para interconectar los componentes electrónicos utilizados 1 $60 Info
Sensor infrarrojo (GP1UE26RK0VF)  :Para detectar la presencia y distancia de un vehículo 2 $13 Info
Led emisor de luz infearroja(IR)  :Para detectar la presencia y distancia de un vehículo 2 $6 Info
Leds(Verde, Rojo, Amarillo):Para simular los semaforos 6 $5 Info
Resistenciasde 220 Ohms:Para controlar la corriente adecuada en el circuito 6 $5 Info
Pila 1.5 v: Para alimentar los leds emisores de luz infrarroja que se montan en los vehículos 2 $20
Cable UTPPara conectar los componetes 1/2 metro $10
Conectores Macho- macho y hembra-Macho: Para conectar los dispositivos al arduino 10 $2
Coches de juguetePara simular las ambuancias 2 $15
Papel Cascaron, pinturas(gris, blanca,amarilla), tijeras, pegamento, cartulinaPara simular las calles, casas, semaforos, etc 1 $40

Presupuesto aproximado: $520

Procedimiento para armar la maqueta


      1. Pintar dos  calles en el papel cascaron y pintarlas según los colores que desee.
            
         

     2. Armar algunas casas, escuelas, edificios según su creatividad, en este caso se compraron laminas para armas, las cuales las puede conseguir en una papelería o puede dibujar y armas sus propias casas o puede consultar la direccion: http://www.jopasi.org/casas.php,  en la cual encontrará muchos moldes para armar(hospitales, Iglesias, farmacias, escuelas, etc.)



    3. Armar 2 semáforos en los cuales colocaremos los leds mas adelante

   4. Pegar las piezas que armó alrededor de las calles.

   

Una vez que tenga lista su maqueta proceda a armar el circuito electrónico para simular el funcionamiento de los semáforos inteligentes

Procedimiento para armar el circuito eléctrico


     
      Diagrama:




1.- Primero leeremos los datos que nos arroja el sensor infrarrojo, para ello conectamos sus pines basándonos en su datasheet
Conexiones:
·                      Pin 1 - Output conectar al pin A0 de arduino
·                      Pin 2 - GND conectar al al pin GND de arduino
·                      Pin 3 – VCC a  3.3v de arduino

2.- Después conectamos un led emisor infrarrojo, la patita más corta se conecta a una resistencia de 220 ohm y esta se conecta a GND, la patita más larga a corriente 5v.


Para poder observar que el led esta emitiendo luz es necesario verlo a través  de una cámara, debido a que la luz es imperceptible para el ojo humano


3. Ejecute el siguiente código y observe que valores muestra en la consola serial:


void setup() {

Serial.begin(9600);

}

void loop() {

  Serial.println(analogRead(A0));

  delay(1000); 



}


Resultados obtenidos:


4.- Una vez que conectamos correctamente el sensor y obtener sus datos procedemos a conectar los leds que pertenecerán a los semáforos(verde, amarillo y rojo) para hacer las simulaciones de su funcionamiento normal, es decir sin los sensores infrarrojos, para programar sus tiempos de cambio, la forma en la que se alternan y en la que se sincronizan.

  Semáforo 1:
                             led Verde1--> Pin  digital 2 de Arduino
                             led Amarillo1--> Pin  digital 3 de Arduino
                             led Rojo1--> Pin  digital 4 de Arduino
  Semáforo 2:
                             led Verde2--> Pin  digital 5 de Arduino
                             led amarillo2--> Pin  digital 6 de Arduino
                             led ROjo2--> Pin  digital 7 de Arduino

5. Ejecute el siguiente código para ver el funcionamiento normal de los semáforos, Se usa la función millis() debido a que se necesita estar leyendo constantemente los datos que nos arrojan los sensores infrarrojos, y  esto no es posible  usando delay() los cuales pausan todos los procesos impidiendo así que se obtengan las lecturas de los sensores infrarrojos de forma constante.


int verde1 = 2;
int amarillo1 = 3;
int rojo1 = 4;


int verde2 = 5;
int amarillo2 = 6;
int rojo2 = 7;

int millisActuales; //para almacenar el valor de los milisegundos que se leen de la función millis()
int millisAnteriores=0; //almacena el valor de los milisegundos tras haber terminado un loop, necesario para calcular los intervalos de tiempo entre los loops

void setup() {
  Serial.begin(9600);

  pinMode(verde1,OUTPUT);
  pinMode(amarillo1,OUTPUT);
  pinMode(rojo1,OUTPUT);

  pinMode(verde2,OUTPUT);
  pinMode(amarillo2,OUTPUT);
  pinMode(rojo2,OUTPUT);
}

void loop() {
  //se optine el valor de los milisegundos que lleva en ejecucion arduino
  millisActuales = millis();

  inicio();
  //imprime el valor de los milisegundos
  Serial.println(millisActuales);
}

void inicio(){
  /*
   * Para calcular el tiempo exacto entre cada loop restamos los milisegundos del ultimo loop (millisAnteriores) de los milisegundos actuales (millisActuales)
   * El primer loop los millisAnteriores son igual a 0, después incrementan en 20,000 por loop y así sucesivamente, esto se hace debido a que la funcion millis, no se puede reiniciar a no ser que se aplique un overflow
   */ 
  int tiempo = millisActuales - millisAnteriores;

  if(tiempo < 7000){
    //semáforo 1, led verde encendido 7 segundos
    digitalWrite(verde1,HIGH);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,LOW);

    //semáforo 2, led rojo encendido 7 segundos
    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,HIGH); 
  }

  if(tiempo > 7000 && tiempo < 10000){
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,HIGH);
    digitalWrite(rojo1,LOW);

    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,HIGH);
  }

  if(tiempo > 10000 && tiempo < 17000){

    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,HIGH);

    digitalWrite(verde2,HIGH);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,LOW);
  }

  if(tiempo > 17000 && tiempo < 20000){
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,HIGH);

    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,HIGH);
    digitalWrite(rojo2,LOW);
  }

  if(tiempo > 20000){
    /*
    * Una vez terminados 20 segundos el valor de millisAnteriores pasa a ser el de los millisActuales para que el tiempo nunca supere los 20 segundos, y siempre sea un ciclo entre 0 y 20 segundos.
    */
    millisAnteriores = millisActuales;
  }
}



Resutados:



6. Ahora con el siguiente el código hace  que todo  funcione (que nos costó un dolor de cabeza) porque no solo es leer los datos de los sensores sino, modificar parte del funcionamiento lógico de los semáforos para prevenir accidentes a la hora de realizar los cambios cuando una unidad de emergencia lo requiera.

int verde1 = 2;
int amarillo1 = 3;
int rojo1 = 4;

int verde2 = 5;
int amarillo2 = 6;
int rojo2 = 7;

int millisActuales;
int millisAnteriores=0;

const char receptor1 = A0;
ionst char receptor2 = A1;

int tiempo2 = 0;

void setup() {
  Serial.begin(9600);

  pinMode(verde1,OUTPUT);
  pinMode(amarillo1,OUTPUT);
  pinMode(rojo1,OUTPUT);

  pinMode(verde2,OUTPUT);
  pinMode(amarillo2,OUTPUT);
  pinMode(rojo2,OUTPUT);

  pinMode(receptor1,INPUT);
  pinMode(receptor2,INPUT);
}

void loop() {
  inicio(); 
}

void inicio(){
  millisActuales = millis();
  //Se leen los valores de los sensores infrarrojos 1 y 2
  int valor1 = analogRead(receptor1);
  int valor2 = analogRead(receptor2);

  /*
   * Para calcular el tiempo exacto entre cada loop restamos los milisegundos del utimo loop (millisAnteriores) de los milisegundos actuales (millisActuales)
   * El primer loop los millisAnteriores son igual a 0, despues incrementan en 20,000 por loop y así sucesivamente, esto se hace debido a que la funcion millis no se puede reiniciar a no ser que se aplique un overflow
   *
   * Ahora también se agrega un valor más, que es el tiempo2 cuya función es la de acelerar la transición de los semáforos de verde a rojo dependiendo de que semáforo sea
   *
   */ 
  int tiempo = millisActuales - millisAnteriores + tiempo2;
  Serial.println(tiempo);
  if(tiempo < 7000){
    /*
     * semáforo 1 en verde y semáforo 2 en rojo por 7 segundos
     */
    digitalWrite(verde1,HIGH);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,LOW);

    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,HIGH);

    /*
     * Tras obtener el valor del sensor infrarrojo número 2, es decir el sensor ubicado en el semáforo 2
     * Se compara si este valor es mayor a 90, es decir, si detecto una luz infrarroja proveniente de la unidad
     * de rescate, si la condición se cumple entonces al tiempo2 se le asigna el valor de los milisegundos que resten
     * para terminar el estado del semáforo 1 (que esta en verde) y acelerar su transición a rojo, haciendo que el
     * semáforo 1 pase rápidamente de verde a amarillo, dando 3 segundo a los vehículos a pasar o detenerse
     *
     */
    if(valor2 > 90){
      tiempo2 = 7000 - (millisActuales - millisAnteriores);
    }
  }

  if(tiempo > 7000 && tiempo < 10000){
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,HIGH);
    digitalWrite(rojo1,LOW);

    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,HIGH);
  }

  if(tiempo > 10000 && tiempo < 17000){
    /*
     * Semáforo 1 en rojo y semáforo 2 en verde por 7 segundos
     */
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,HIGH);

    digitalWrite(verde2,HIGH);
    digitalWrite(amarillo2,LOW);
    digitalWrite(rojo2,LOW);

    /*
     * Esta función es similar a la anterior del semáforo 1, solo que en esta se comprueba si el
     * sensor infrarrojo 1, que se encuentra en el semáforo 1 detecto luz infrarroja para acelerar
     * la transición del semáforo 2 a rojo, pasando primero por un cambio a amarillo de 3 segundos
     * nuevamente para que los vehículos tengan tiempo de pasar o detenerse.
     */
    if(valor1 > 90){
      tiempo2 = 17000 - (millisActuales - millisAnteriores);
    }
  }

  if(tiempo > 17000 && tiempo < 20000){
    digitalWrite(verde1,LOW);
    digitalWrite(amarillo1,LOW);
    digitalWrite(rojo1,HIGH);

    digitalWrite(verde2,LOW);
    digitalWrite(amarillo2,HIGH);
    digitalWrite(rojo2,LOW);
  }

  if(tiempo > 20000){
    /*
    * Una vez terminados 20 segundos el valor de millisAnteriores pasa a ser el de los millisActuales para que el
    * tiempo nunca supere los 20 segundos, y siempre sea un ciclo entre 0 y 20 segundos.
    */
    millisAnteriores = millisActuales;
   
    /*
     * La variable tiempo2 la tenemos definida global y su valor se mantiene tras realizarse cada loop por ello
     * que se reinicie su valor a 0
     */
    
    tiempo2 = 0;
  }
}



Resultados:




7. Una vez probado el funcionamiento correcto de los semáforos y los sensores, lo único que nos queda por hacer, es colocar los leds en cada semáforo que armamos y pegarlos en la maqueta.


8. Veamos como funcionan los semáforos con el uso de sensores infrarrojos




Funcionamiento:


El led emisor de luz infrarroja esta montado sobre la ambulancia, y el receptor de luz esta  en el semáforo. El receptor de luz obtendrá valores variados de acuerdo a la distancia a la que se encuentre el emisor de luz y de acuerdo a esos valores es que se programa en el microcontrolador (Arduino Uno) el funcionamiento del semáforo (tiempo en que tarda en cambiar cada estado).

Para evitar accidentes la forma en que funcionan los semáforos automáticos es mediante la aceleración entre sus transiciones de estado, es decir, si el semáforo donde pasara en un determinado tiempo una unidad de rescate se encuentra en rojo, se acelera el proceso de transición de todos los semáforos que se encuentren alrededor de este de modo que este pueda pasar a verde dentro de pocos segundos.

Ejemplo con dos semáforos:
Estados
Semáforo 1
Semáforo 2
Tiempo
q0
7 segundos
q1
3 segundo
q2
7 segundos
q3
3 segundo


Suponiendo que el estado actual es q0 y una unidad de rescate este próxima al semáforo 2, entonces rápidamente se acelera la transición del estado q0 a q1, quitando así los segundos restantes (7 en este caso) para que durante 3 segundos los vehículos que transiten por el semáforo 1 puedan o terminar de cruzar o detenerse, de este modo cuando la unidad de rescate llegue al semáforo 2 pueda pasar sin problemas, esto se aplica de la misma forma para el semáforo 2, si se está en el estado q2 entonces se acelera la transición al estado q3.


Beneficios en la vida real y tiempo de vida  :)


Los los semáforos inteligentes se agiliza la circulación de los vehículos, evitando el trafico que a veces se produce, en este caso con el control de los semáforos por un vehículo como las ambulancias, bomberos, etc. se ven beneficiados las personas las cuales su vida esta en peligro, permitiendo que el traslado a un hospital sea mucho mas rápido, ya que unos minutos son suficientes para poder salvar a una persona.
Los países de primer mundo tienen prácticamente todos los servicios automatizados evitando grandes problemas de tiempo. En dado caso de que nuestro prototipo se llegue a implementar en la ciudad en un futuro el tiempo de vida será mientras se le siga invirtiendo al mantenimiento y mejoras, de acuerdo a los resultados que obtenga su implementación en la realidad, que sin duda alguna sería un gran beneficio para la población.


Inconconvenientes  :(  

Muchas cosas que intentamos hacer no se lograron a la primera o simplemente no se podía y tuvimos que recurrir a distintas alternativas

1.- El primer problema que tuvimos fue cuando intentamos utilizar un sensor infrarrojo como este:


Es un diodo receptor infrarrojo, cuya función es la de un diodo pero este diodo solo permite el flojo de corriente en una dirección cuando una luz infrarroja es captada por el mismo.
Por tanto si decidíamos utilizarlo se necesitaría de un transistor como el siguiente:


 
Una resistencia de 100k ohm donde un extremo de la esta va conectada a la patita más larga de nuestro diodo receptor infrarrojo y el otro extremo de la resistencia a la gate del transistor, el colector del transistor a corriente 5v y el emisor a un jumper que va conectado a un pin digital de arduino y a su vez a tierra.
La intención de esto es que cuando el diodo receptor detecte un haz de luz infrarroja deje fluir corriente a la gate del transistor y con la resistencia de 100k ohm la gate del transistor solo reciba entre 0 a 1 amperes la necesaria para abrir o cerrarla, en este caso el diodo dejaría pasar 1 Amper a la gate del transistor haciendo que este deje pasar 5v del ánodo al emisor y ello cree una lectura de HIGH en nuestro pin digital de arduino.
La razón por la que decidimos no hacerlo de esta forma, es que encontramos otro dispositivo con el que se podía hacer todo lo anterior mucho más fácil.

2.- Durante la práctica aprendimos sobre las desventajas de utilizar la función delay, y que existe otra alternativa con la función millis aunque su aplicación resulta un poco más complicada en algunos casos.



Créditos:

Díaz Jimenez Magaly P.
Leal Barragán Santiago
López López David



 Dejen sus comentarios  :)