Youssef Abarca
Helmut Iván Dubón González
Youssef Abarca que elegante solucion
Domina el control de semáforos con Arduino combinando PWM, sensores analógicos y botones peatonales. Pon en práctica entradas y salidas, condicionales, ciclos y estructuras de datos en un escenario real: un crucero con flujo en dos sentidos y prioridades claras para peatones y coches.
¿Qué vas a construir con Arduino: semáforos con peatones?
Vas a programar un par de semáforos que controlan un crucero sobre una avenida principal donde confluyen dos avenidas adicionales. Hay flujo en ambos sentidos y los coches deben poder incorporarse hacia el norte o sur según definas. Además, debes integrar botones para que las personas puedan solicitar cruce.
¿Cómo integrar botones peatonales con Arduino?
Los botones sirven para avisar que hay peatones esperando. Tu lógica debe considerar ese evento y ajustar el flujo vehicular.
¿Cómo definir el algoritmo y los tiempos del semáforo?
Tu decisión sobre qué tiene prioridad impacta la experiencia de ambos: peatón y coche. Diseña una secuencia coherente y justa.
¿Cómo aplicar condicionales, ciclos y estructuras de datos?
El reto exige traducir reglas del tráfico a lógica de programa. Si ya programas o cursaste algoritmos con C, estás listo para abordar estas decisiones; si no, conviene reforzar condicionales, ciclos y estructuras antes de implementarlo.
¿Qué habilidades y conceptos necesitas dominar?
Este reto integra lo aprendido para operar el hardware y la lógica de control. Cada elemento es clave para que el sistema sea seguro, claro y eficiente.
¿Listo para mostrar resultados? Comparte tu programa y el video en YouTube, y cuéntanos en comentarios cómo resolviste los tiempos y la prioridad entre peatones y coches.
Reto cumplido!
El código del programa.
/***************************************************** Desafio#1 - Platzi Semáforo para dos Avenidas (Principal y Secundaria) ambas tienen una luz azul para indicar el giro a la izquierda y un pulsador peatonal para cambiar el estado de la luz verde y darle paso a los peatones. Configuración: Entradas: botones peatonales {13(P),2(S)} Salidas: luces verde, amarilla, roja y azul {11,10,9,8}Princial ; {7,6,5,4}Secundaria Autor: Pablo Cardozo *****************************************************/ // Avenida Principal const int vp = 11; const int ap = 10; const int rp = 9; const int zp = 8; const int butP = 13; //Pulsador Peatonal const int semP[4] = {vp, ap, rp, zp}; // arreglo para semáforo Principal // Avenida Secundaria const int vs = 7; const int as = 6; const int rs = 5; const int zs = 4; const int butS = 2; //Pulsador Peatonal const int semS[4] = {vs, as, rs, zs}; // arreglo para semáforo Secundario // Tiempos para cada luz en milisegundos (tr = tz) int ta = 2000; int tv = 6000; int tz = 3000; // Variables Globales unsigned long tiempoActual; int tiempo; int estadoSem; // el semáforo tiene 6 estados bool flagButton = false; void setup() { // Configuración de Salidas para los semáforos for(int i=0; i<4; i++){ pinMode(semP[i], OUTPUT); pinMode(semS[i], OUTPUT); } // Configuración de Entradas para los pulsadores pinMode(butP, INPUT_PULLUP); pinMode(butS, INPUT_PULLUP); iniciar(); } void loop() { if((millis() - tiempoActual) > tiempo) { cambio(); tiempoActual = millis(); } if((digitalRead(butP) == LOW) || (digitalRead(butS) == LOW)) { delay(200); //esperamos hasta que los botones no esten pulsados while((digitalRead(butP) == LOW) && (digitalRead(butS) == LOW)); flagButton = true; estadoSem--; // el estado actual apunta al siguiente if(estadoSem <= 0) estadoSem = 6; if((estadoSem == 1) || (estadoSem == 4)) estadoSem++, cambio(); else flagButton = false; tiempoActual = millis(); } } void iniciar() { estadoSem = 1; cambio(); } void cambio() { for(int i=0; i<4; i++) { digitalWrite(semP[i], LOW); digitalWrite(semS[i], LOW); } switch (estadoSem) { case 1: digitalWrite(vp, HIGH); digitalWrite(rs, HIGH); tiempo = tv; break; case 2: digitalWrite(ap, HIGH); digitalWrite(rs, HIGH); tiempo = ta; break; case 3: digitalWrite(rp, HIGH); digitalWrite(zp, HIGH); digitalWrite(rs, HIGH); tiempo = tz; break; case 4: digitalWrite(rp, HIGH); digitalWrite(vs, HIGH); tiempo = tv; break; case 5: digitalWrite(rp, HIGH); digitalWrite(as, HIGH); tiempo = ta; break; case 6: digitalWrite(rp, HIGH); digitalWrite(rs, HIGH); digitalWrite(zs, HIGH); tiempo = tz; break; default: break; } if(flagButton) estadoSem += 2, flagButton = false; else estadoSem++; if(estadoSem > 6) estadoSem = 1; }
Dejo el link del repositorio
https://github.com/Pablocyc/semaforo-platzi
Youssef Abarca
Helmut Iván Dubón González
Youssef Abarca que elegante solucion
Jonathan Macalupu Reyes
Ricardo Celis
ProfesorEs un excelentísimo programa! me gusta mucho el manejo de los vectores para reducir la escritura de código utilizando un for y el Switch!
Muchas gracias por tu aporte, sin duda será de mucha ayuda =)
Jorge Gens Abujas
Mola pensar que se podría añadir un sensor de presencia para modificar los tiempos de cambio de color de los semáforos si hay mucha cola de coches esperando, o de personas esperando cruzar. El límite lo pone la imaginación, desde luego.
Buenas clases, gracias!
Ricardo Celis
ProfesorGenial Jorgens! qué bueno que te esté gustando el curso =)
Jeffry Andrés López Garita
La verdad no me esta gustando, he aprendido mas de los comentarios que del profesor
José Manuel Robles Espinosa
pues depende de que forma te es mas facil aprender, no hay que desacreditar al profe tampoco, porque a mi parecer explica muy bien, a la mejor a veces no tenemos muy bien claros ciertos conocimientos que el profe esta dando por sentado que ya debemos saber para poder haber tomado este curso, solo digo que sea como sea el profe esta haciendo bien su labor...
Aldo Sandoval
Ricardo Celis
ProfesorExcelente Aldo! esperamos tu versión avanzada eh!
César Romero
No entiendo bien el Reto, un crucero no es un tipo de barco?, los autos y las personas esperan embarcar?. Sería posible subir un documento explicando el reto y lo que se espera lograr?
Gracias de antemano.
César Romero
Viendo una y otra ves el video creo que quizás es un problema de lenguaje, por contexto me parece que crucero significa intersección de calles, es eso … ?
Alexis Antonio Moraga Gallardo
si, me paso lo mismo al principio, al parecer es la intersección de dos avenidas
Carlos Alberto Quiñonez Tellez
Para construir una interfaz para una tablet Android (o cualquier otro disposivo Touch), cual herramienta recomiendan. Algo asi como esta imagen
Que curso pueden recomendar donde expliquen la interaccion de una pantalla touch con el arduino.
Muchas garcias de antemano.
Jose Antonio Padron Fernandez
Arduino corre en un lenguaje muy parecido a C por lo que yo me tomaría los cursos de C ;)
Buenas tardes compañeros y compañeras, Comparto con ustedes el desafío de esta clase. He partido de algunas premisas para su construcción, las mismas se comentan en el código. Desde ya los invito a proponer sugerencias , cambios y optimizaciones al código.
He intentando aplicar todos los conocimientos adquiridos hasta ahora en la ruta de IoT. He usado distintos tipos variables, distintas estructuras de control y funciones.
Éxitos para todos!!
/******************************************** Para el desarrollo de este desafío se han se ha partido de las premisas enunciadas a continuación: 1- Se considera, interpretando de los comentarios del profesor, que los semáforos permiten ingresar a las avenidas secundarios solo saliendo por la derecha, más no por la izquierda (Practica muy empleada en la cuidad donde vivo). Mientras que desde las avenidas secundarias se puede ingresar a la principal girando tanto a izquierda como a derecha. 2- Esto nos deja con un sistema de semáforos de 3 movimientos. Una secuencia para la avenida principal (en ambos sentidos) y dos secuencias independientes para cada avenida secundaria. 3- Se ha tomado como tiempo de espera para cada semáforo 60s (35s en rojo, 15s en amarillo y 10s en parpadeo amarillo). La luz verde se mantendrá estática por 50s y luego parpadeara por otros 10s. 4- Si un peatón pulsase el botón de cruce, deberá esperar a que la secuencia en ejecución se detenga, y luego tendrá 25s para cruzar la calle. Reto: Crea tu semáforo con Arduino Curso: Fundamentos de Desarrollo de Hardware con Arduino Profesor: Ricardo Celis Alumno: Marcel Nahir Samur Fecha: 25/10/2020 ********************************************************/ // Avenida ppal. const int pr = 11; const int pa = 10; const int pv = 9; const int pb = 8; //Avenida sec. 1 const int s1r = 5; const int s1a = 6; const int s1v = 7; const int s1b = 4; //Avenida sec. 2 const int s2r = A1; const int s2a = A2; const int s2v = A3; const int s2b = A0; const int arrSem[9] = {pr, pa, pv, s1r, s1a, s1v, s2r, s2a, s2v}; // Arreglo de LEDs const int alarmaPeaton = 13; //Alarma de peatones //Duración de las luces (en Milisegundos) unsigned int drs = 35000; unsigned int das = 15000; unsigned int dap = 10000; unsigned int dbs = 25000; bool btnFlag = false; int status; void setup() { Serial.begin(9600); //Luces for (int i = 0 ; i < 9 ; i++) pinMode(arrSem[i], OUTPUT); //Pulsadores pinMode(pb, INPUT_PULLUP); pinMode(s1b, INPUT_PULLUP); pinMode(s2b, INPUT_PULLUP); //Alarma pinMode(alarmaPeaton, OUTPUT); } void loop() { // Los estados son 4, 3 p/circulacion vehicular y 1 para cruce de peatones status = 1; for (int j = 0 ; j < 3 ; j++) //Ejecutamos las 3 secuencias de semáforos { secuencia(); // Se evalua en cada iteración si algun peaton ha oprimido el pulsador if (btnFlag == true) { for (int k = 0 ; k < 9 ; k++) { digitalWrite(arrSem[k], LOW); // Semáforos apagados } digitalWrite(pr, HIGH); //Todos los semáforos digitalWrite(s1r, HIGH); // vehiculares digitalWrite(s2r, HIGH); // en rojo digitalWrite(alarmaPeaton, HIGH); // Semáforos peatonales delay(dbs); status++; // Se pasa a la siguiente secuencia btnFlag = false; // Se desactiva la señal peatonal } else { status++; // Se pasa a la siguiente secuencia } } } /* Se utiliza el parpadeo de los LEDs verde y amarillo para indicar un cambio de estado inminente*/ int atencion(int at1,int at2,int at3) { for (int f = 0 ; f < 5 ; f++) // Para generar el parpadeo { digitalWrite(at1, LOW); digitalWrite(at2, LOW); digitalWrite(at3, HIGH); peaton(1000); digitalWrite(at1, HIGH); digitalWrite(at2, HIGH); digitalWrite(at3, HIGH); peaton(1000); } } // Estado de circulación libre o detención total int estatico(int static1,int static2,int static3,int static4) { digitalWrite(static1, HIGH); digitalWrite(static2, HIGH); digitalWrite(static3, HIGH); peaton(drs); digitalWrite(static3, LOW); digitalWrite(static4, HIGH); peaton(das); } /* Función para ejecutar los 3 posibles estados de los semáforos vehiculares */ int secuencia() { for (int g = 0 ; g < 9 ; g++) digitalWrite(arrSem[g], LOW); // Semáforos apagados switch (status) { case 1: estatico(pv, s1r, s2r, s2a); atencion(pv, s2a, s1r); break; case 2: estatico(s2v, pr, s1r, s1a); atencion(s2v, s1a, pr); break; case 3: estatico(s1v, s2r, pr, pa); atencion(s1v, pa, s2r); break; default: Serial.println("Error! Contacte a soporte técnico"); break; } } /* Se utiliza esta función para comprobar si un peaton ha pulsado el boton */ bool peaton(unsigned int dFrac) { int dRes = 250; //Resolución, utilizado p/ dividir el retardo dFrac = dFrac/dRes; for (int dBtn = 0 ; dBtn < dFrac ; dBtn++) { if (digitalRead(pb) == LOW || digitalRead(s1b) == LOW || digitalRead(s2b) == LOW) { btnFlag = true; digitalWrite(alarmaPeaton, HIGH); delay(dRes); } else { delay(dRes); digitalWrite(alarmaPeaton, LOW); // Indicador de peatones apagado } } return btnFlag; // Se retorna el valor que se evaluará } // en la función principal
Gerardo Castro
Andrés Leonardo Mogollón Benavides
La verdad No Aprendí Mucho =(
Korpi delfin
¡Hola! :D
¿En qué se te hizo complicado este curso?
Fernando Arango Orozco
este código utiliza sensores, para efectos prácticos utilizo dos pulsadores, cada que presiono un pulsador se realiza el cambio de semaforo
Jess Key
Jaime de Jesús Meza Estrada
Progamacion de Semaforos
David Santiago Medina Puerto
Así fue como planté el ejercicio, con todos los giros a las diferentes direcciones posibles.
David Santiago Medina Puerto
creo que esta propuesta se complica mucho, estoy trabajando en una solucion mas simple.
David Santiago Medina Puerto
Marcelo Rodrigo Duran Mamani
Joaquim Jair Merlo Luque
José Enrique Durán Granados
Imagen:
Código:
void loop() {
if(estado == 0){
digitalWrite(ledR1, HIGH);
digitalWrite(ledA1, LOW);
digitalWrite(ledV1, LOW);
digitalWrite(ledR0, LOW);
digitalWrite(ledA0, LOW);
digitalWrite(ledV0, HIGH);
if(digitalRead(boton0) == LOW){
digitalWrite(ledW1, HIGH);
digitalWrite(ledB0, LOW);
delay(tiempo);
digitalWrite(ledW1, LOW);
digitalWrite(ledB0, HIGH);
}
digitalWrite(ledB0, HIGH);
estado = 1;
ruta = true;
delay(tiempo);
}else if(estado == 1){
digitalWrite(ledR1, LOW);
digitalWrite(ledA1, HIGH);
digitalWrite(ledV1, LOW);
digitalWrite(ledB1, LOW);
digitalWrite(ledW1, LOW);
digitalWrite(ledR0, LOW);
digitalWrite(ledA0, HIGH);
digitalWrite(ledV0, LOW);
digitalWrite(ledB0, LOW);
if(ruta){estado = 2; }else{estado = 0;}
delay(tiempo-(tiempo*0.5));
}else{
digitalWrite(ledR1, LOW);
digitalWrite(ledA1, LOW);
digitalWrite(ledV1, HIGH);
digitalWrite(ledR0, HIGH);
digitalWrite(ledA0, LOW);
digitalWrite(ledV0, LOW);
digitalWrite(ledB0, LOW);
if(digitalRead(boton1) == LOW){
digitalWrite(ledB1, LOW);
digitalWrite(ledW0, HIGH);
delay(tiempo);
digitalWrite(ledW0, LOW);
}
digitalWrite(ledB1, HIGH);
estado = 1;
ruta = false;
delay(tiempo);
}
Nicolas Pennisi
Nicolas Pennisi
Emanuel Moreno Manriquez
Como solo quieres una pista intenta usar while y goto para forzar las rutas del diagrama de flujo para que no tengas que leer todas las situaciones en cada ciclo.
Ricardo Portillo
Intente hacer el código lo más simple y legible posible. Los semáforos funcionan con 6 estados (cases 0 al 5), y cada estado tiene un tiempo de duración.
const int GREEN_MAIN_STREET = 3; const int YELLOW_MAIN_STREET = 4; const int RED_MAIN_STREET = 5; const int BUTTON_MAIN_STREET = 6; const int GREEN_SIDE_STREET = 7; const int YELLOW_SIDE_STREET = 8; const int RED_SIDE_STREET = 9; const int BUTTON_SIDE_STREET = 10; int waitTime = 0; typedef struct { bool green; bool yellow; bool red; } lights; void setup() { // put your setup code here, to run once: pinMode(GREEN_MAIN_STREET, OUTPUT); pinMode(YELLOW_MAIN_STREET, OUTPUT); pinMode(RED_MAIN_STREET, OUTPUT); pinMode(BUTTON_MAIN_STREET, INPUT_PULLUP); pinMode(GREEN_SIDE_STREET, OUTPUT); pinMode(YELLOW_SIDE_STREET, OUTPUT); pinMode(RED_SIDE_STREET, OUTPUT); pinMode(BUTTON_SIDE_STREET, INPUT_PULLUP); } void loop() { lights mainStreet = {0, 0, 0}; lights sideStreet = {0, 0, 0}; // put your main code here, to run repeatedly: for (int i = 0; i < 6; i++) { switch (i) { case 0: mainStreet = {0, 0, 1}; sideStreet = {0, 0, 1}; waitTime = 20; break; case 1: mainStreet = {0, 0, 1}; sideStreet = {1, 0, 0}; // Green light sideStreed waitTime = 40; break; case 2: mainStreet = {0, 0, 1}; sideStreet = {0, 1, 0}; waitTime = 10; break; case 3: mainStreet = {0, 0, 1}; sideStreet = {0, 0, 1}; waitTime = 10; break; case 4: mainStreet = {1, 0, 0}; // Green light mainStreed sideStreet = {0, 0, 1}; waitTime = 40; break; case 5: mainStreet = {0, 1, 0}; sideStreet = {0, 0, 1}; waitTime = 10; break; } trafficLightMain(mainStreet); trafficLightSide(sideStreet); // Usamos un for para no usar un delay tan alto sino // particionar el tiempo en tiempos más pequeños // y cada cierto tiempo revisamos el estado de los botones // cuando exista la luz verde for (int t = 0; t < 100; t++) { if (i == 4 && digitalRead(BUTTON_MAIN_STREET) == LOW) { delay(1000); break; } if (i == 1 && digitalRead(BUTTON_SIDE_STREET) == LOW) { delay(1000); break; } delay(waitTime); } } } void trafficLightMain(lights value) { digitalWrite(GREEN_MAIN_STREET, value.green); digitalWrite(YELLOW_MAIN_STREET, value.yellow); digitalWrite(RED_MAIN_STREET, value.red); } void trafficLightSide(lights value) { digitalWrite(GREEN_SIDE_STREET, value.green); digitalWrite(YELLOW_SIDE_STREET, value.yellow); digitalWrite(RED_SIDE_STREET, value.red); }
Cualquier sugerencia es bienvenida :)
¡Tremendo reto!. Lo que hice fue colocar un botón que reduzca en 20 segundos el tiempo cuando el semáforo se encuentra sólo en verde. Aplicado cuando alguien quisiera cruzar, reduce el tiempo de la luz verde para que los carros se detengan en menos tiempo y los peatones crucen.
Adicionalmente conecté el LCD 16x2 donde me indica en texto el color y un reloj cuenta atrás para saber cuánto falta para cambiar de luz.
Coloco mi código (he tratado de softcodear para que se vea limpio):
#include <LiquidCrystal.h> LiquidCrystal lcd(12, 11, 5, 4, 3, 2); const int ledR = 6; const int ledY = 9; const int ledG = 10; const int boton = 13; int timeSem = 100; int reduccionTiempo = 20; void setup() { Serial.begin(9600); // put your setup code here, to run once: lcd.begin(16,2); pinMode(ledR, OUTPUT); pinMode(ledY, OUTPUT); pinMode(ledG, OUTPUT); pinMode(boton, INPUT_PULLUP); } void loop() { cambioSem(ledR, ledY, ledG, timeSem); } void cambioSem(int rojo, int amarillo, int verde, int tiempo) { char luz0[9] = "Rojo"; char luz1[9] = "Amarillo"; char luz2[9] = "Verde"; char *luzSem[3]; luzSem[0]=luz0; luzSem[1]=luz1; luzSem[2]=luz2; int timeL[] = {100, 5, 120}; for (int a = 0; a<3; a++) { for (int i = timeL[a]; i>=0; i=i-1) { lcd.clear(); lcd.setCursor(0,1); lcd.print(i); lcd.setCursor(0,0); lcd.print(luzSem[a]); switch (luzSem[a][0]) { case 'R': analogWrite(rojo, HIGH); analogWrite(amarillo, LOW); analogWrite(verde, LOW); break; case 'A': analogWrite(rojo, LOW); analogWrite(amarillo, HIGH); analogWrite(verde, LOW); break; case 'V': analogWrite(rojo, LOW); analogWrite(amarillo, LOW); analogWrite(verde, HIGH); if (digitalRead(boton)==LOW) { i = i - reduccionTiempo; } break; } delay(1000); } } }
El ensamblaje queda así:
EL vídeo donde pueden ver el funcionamiento es el siguiente link
**Este es el código de un semáforo básico, espero que les sea de ayuda a los que no saben como empezar y puedan cumplir el reto. 😃 **
//** Definiciones **// int rojo=2; //definimos el valor del pin para el led rojo int amarillo=4; //definimos el valor del pin para el led amarillo int verde=7; //definimos el valor del pin para el led verde //** Programa **// void setup() { pinMode(verde,OUTPUT); //declaramos el pin verde como salida pinMode(amarillo,OUTPUT);//declaramos el pin amarillo como salida pinMode(rojo,OUTPUT); //declaramos el pin rojo como salida } void loop() { digitalWrite(verde,HIGH); //encendemos el led rojo delay(2000); //esperamos 2 segundos digitalWrite(verde,LOW); //apagamos el led rojo delay(500); //esperamos medio segundo digitalWrite(amarillo,HIGH); //encendemos el led amarillo delay(2000); //esperamos 2 segundos digitalWrite(amarillo,LOW); //apagamos el led amarillo delay(500); //esperamos medio segundo digitalWrite(rojo,HIGH); //encendemos el led verde delay(2000); //esperamos 2 segundos digitalWrite(rojo,LOW); //apagamos el led verde delay(500); //esperamos medio segundo }
Aqui les dejo mi codigo! debo darle credito al companero Pablo Cardozo, me guie un poco de su coidgo para poder empezar pero le di mi propio enfoque y tambien copie el inicio donde aparece la descripcion, hacer eso es muy buena practica.
/************************************************************** Desafio#1 - Platzi Semáforo para dos Avenidas (Principal y Secundaria) ambas tienen una luz azul para indicar el giro a la izquierda y un pulsador peatonal para cambiar el estado de la luz verde y darle paso a los peatones. Configuración: Entradas: botones de paso {A0(P),A1(S)} Salidas: luces verde, amarilla, roja y azul {6,7,8,9}Princial ; {10,11,12,13}Secundaria cada LED esta conectado con una Resistencia de 220 Ohms Pantalla LCD RS = 0, E = 1, D4 = 2, D5 = 3, D6 = 4, D7 = 5; estamos utilizando para el LCD un potenciometro de 10 kOhms Autor: Gerardo Castro Fecha: 20.12.2018 **************************************************************/ #include <LiquidCrystal.h> //VARIABLES GLOBALES. unsigned int tiempo = 0; //En segundos. el cero no significa nada, solo esta siendo inicializada. int peaton = 0; unsigned long tiempoTimer; int estadoPasado = 0; int estadoActual = 0; //utilizaremos esto para asegurarnos de que todos los ciclos del semaforo se cumplan. int estadoSiguiente = 1; //SEMAFORO PRINCIPAL const int verdP = 6; const int amarP = 7; const int rojoP = 8; const int azulP = 9; const int botP = A0; int semPrin [4] = {verdP, amarP, rojoP, azulP}; //SEMAFORO SECUNDARIO const int verdS = 10; const int amarS = 11; const int rojoS = 12; const int azulS = 13; const int botS = A1; int semSec [4] = {verdS, amarS, rojoS, azulS}; LiquidCrystal lcd (0, 1, 2, 3, 4, 5); //-------------------------------------------------// //ESTRUCTURA ARDUINO //-------------------------------------------------// void setup() { // put your setup code here, to run once: lcd.begin(16,2); for (int i = 0;i < 4; i++){ //Definimos los pines del semaforo como output pinMode (semPrin[i], OUTPUT); pinMode (semSec[i], OUTPUT); } //Activamos los pullup resistors para los botones. pinMode (botP, INPUT_PULLUP); pinMode (botS, INPUT_PULLUP); iniciar(); } void loop() { // put your main code here, to run repeatedly: if (timer(tiempo)){ cambio(); } } //-------------------------------------------------// //-------------------------------------------------// //*************************************************// //TEMPORIZADOR //*************************************************// bool timer(int t){ tiempoTimer = (millis()/1000) + t; for(;(tiempoTimer - (millis()/1000)) >= 0;){ boton(); lcd.print(tiempoTimer - (millis()/1000)); if((millis()%500 == 0)){//refrescamos la pantalla cada 1/2 segundo. lcd.clear(); if(peaton == 1){ lcd.clear(); lcd.setCursor(0,1); lcd.print("Peaton Esperando"); } } lcd.setCursor(0,0); if((tiempoTimer - (millis()/1000)) <= 4 && (tiempoTimer - (millis()/1000)) > 0){//Prendemos las luces amarillas cuando digitalWrite(amarP, HIGH); digitalWrite(amarS, HIGH); } else if((tiempoTimer - (millis()/1000)) == 0){ estadoPasado = estadoActual; return (1); //Devuelve TRUE una vez que el tiempo se agote. } } } //*************************************************// //STARTUP DEL SEMAFORO //*************************************************// void iniciar(){ //Simple Animacion al inicio del programa, puede ser eliminado. int t = 175; digitalWrite(verdP, HIGH); delay(t); digitalWrite(amarP, HIGH); digitalWrite(verdP, LOW); delay(t); digitalWrite(rojoP, HIGH); digitalWrite(amarP, LOW); delay(t); digitalWrite(azulP, HIGH); digitalWrite(rojoP, LOW); delay(t); digitalWrite(verdS, HIGH); digitalWrite(azulP, LOW); delay(t); digitalWrite(amarS, HIGH); digitalWrite(verdS, LOW); delay(t); digitalWrite(rojoS, HIGH); digitalWrite(amarS, LOW); delay(t); digitalWrite(azulS, HIGH); digitalWrite(rojoS, LOW); delay(t); digitalWrite(azulS, LOW); delay(t); for(int x = 0; x < 2; x++){ for(int i = 0; i < 4; i++){ digitalWrite(semPrin[i], HIGH); digitalWrite(semSec[i], HIGH); } delay(200); for(int i = 0; i < 4; i++){ digitalWrite(semPrin[i], LOW); digitalWrite(semSec[i], LOW); } delay(200); } delay(1000); } //*************************************************// //SECUENCIA DE CAMBIO DEL SEMAFORO //*************************************************// void cambio(){ for(int i = 0; i < 4; i++){ //Apagamos todas las luces. digitalWrite(semPrin[i], LOW); digitalWrite(semSec[i], LOW); } switch(estadoSiguiente){//Definicion de cada caso posible de los semaforos. Recibe como parametro el siguiente estado del semaforo. case 0://Principal Verde, Secundario Rojo. tiempo = 90; digitalWrite(verdP, HIGH); digitalWrite(rojoS, HIGH); estadoActual = 0; estadoSiguiente = estadoActual + 1; break; case 1://Principal Rojo, Secundario Verde. tiempo = 60; digitalWrite(rojoP, HIGH); digitalWrite(verdS, HIGH); estadoActual = 1; estadoSiguiente = estadoActual + 1; break; case 2:// Principal Azul, Secundario Rojo. tiempo = 45; digitalWrite(azulP, HIGH); digitalWrite(rojoS, HIGH); estadoActual = 2; estadoSiguiente = estadoActual + 1; break; case 3:// Principal Rojo, Secundario Azul. tiempo = 30; digitalWrite(rojoP, HIGH); digitalWrite(azulS, HIGH); estadoActual = 3; estadoSiguiente = 0; break; } peaton = 0; } //*************************************************// //COMPORTAMIENTO DEL BOTON. DETECCION DE PEATONES //*************************************************// void boton(){ if (!digitalRead(botP)){ if ((estadoActual == 0 || estadoActual == 2) && peaton == 0){//Verificamos que fluyan carros en la Av. Prin. y que solo se pueda presionar una vez el boton. if(estadoPasado == 3){ estadoSiguiente = 1; } else if(estadoPasado == 1) { estadoSiguiente == 3; } peaton = 1; if((tiempoTimer - (millis()/1000)) > 20){//acortamos el tiempo de espera. tiempoTimer = tiempoTimer - 15; } } } else if (!digitalRead(botS)){ if ((estadoActual == 1 || estadoActual == 3) && peaton == 0){ if(estadoPasado == 0){ estadoSiguiente = 2; } else if(estadoPasado == 2) { estadoSiguiente == 0; } peaton = 1; if((tiempoTimer - (millis()/1000)) > 21){ tiempoTimer = tiempoTimer - 15; } } } }```
Ya lo resolví, aquí está el link
// C++ code // //Mantén presionado unos segundos el botón para que cambie a verde. int led_roja_1 = 2; int led_amarilla_1 = 3; int led_verde_1 = 4; int boton1 = 8; int botonState1; int led_roja_2 = 5; int led_amarilla_2 = 6; int led_verde_2 = 7; int boton2 = 9; int botonState2; int led_roja_3 = 10; int led_amarilla_3 = 11; int led_verde_3 = 12; int boton3 = 13; int botonState3; int led_roja_4 = 14; int led_amarilla_4 = 15; int led_verde_4 = 16; int boton4 = 17; int botonState4; int i; void setup() { pinMode(led_roja_1, OUTPUT); pinMode(led_amarilla_1, OUTPUT); pinMode(led_verde_1, OUTPUT); pinMode(led_roja_2, OUTPUT); pinMode(led_amarilla_2, OUTPUT); pinMode(led_verde_2, OUTPUT); pinMode(led_roja_3, OUTPUT); pinMode(led_amarilla_3, OUTPUT); pinMode(led_verde_3, OUTPUT); pinMode(led_roja_4, OUTPUT); pinMode(led_amarilla_4, OUTPUT); pinMode(led_verde_4, OUTPUT); pinMode(boton1, INPUT); pinMode(boton2, INPUT); pinMode(boton3, INPUT); pinMode(boton4, INPUT); Serial.begin(9600); } void LED_1A_green(){ digitalWrite(led_amarilla_1, HIGH); digitalWrite(led_amarilla_4, HIGH); delay(2000); digitalWrite(led_amarilla_1, LOW); digitalWrite(led_amarilla_2, LOW); digitalWrite(led_amarilla_3, LOW); digitalWrite(led_amarilla_4, LOW); delay(200); digitalWrite(led_verde_1, HIGH); digitalWrite(led_verde_2, LOW); digitalWrite(led_verde_3, LOW); digitalWrite(led_verde_4, LOW); digitalWrite(led_roja_1, LOW); digitalWrite(led_roja_2, HIGH); digitalWrite(led_roja_3, HIGH); digitalWrite(led_roja_4, HIGH); delay(2000); digitalWrite(led_verde_1, LOW); } void LED_2A_green(){ digitalWrite(led_amarilla_1, HIGH); digitalWrite(led_amarilla_2, HIGH); delay(2000); digitalWrite(led_amarilla_1, LOW); digitalWrite(led_amarilla_2, LOW); digitalWrite(led_amarilla_3, LOW); digitalWrite(led_amarilla_4, LOW); delay(200); digitalWrite(led_verde_2, HIGH); digitalWrite(led_verde_1, LOW); digitalWrite(led_verde_3, LOW); digitalWrite(led_verde_4, LOW); digitalWrite(led_roja_2, LOW); digitalWrite(led_roja_1, HIGH); digitalWrite(led_roja_3, HIGH); digitalWrite(led_roja_4, HIGH); delay(2000); digitalWrite(led_verde_2, LOW); } void LED_3A_green(){ digitalWrite(led_amarilla_2, HIGH); digitalWrite(led_amarilla_3, HIGH); delay(2000); digitalWrite(led_amarilla_1, LOW); digitalWrite(led_amarilla_2, LOW); digitalWrite(led_amarilla_3, LOW); digitalWrite(led_amarilla_4, LOW); delay(200); digitalWrite(led_verde_3, HIGH); digitalWrite(led_verde_1, LOW); digitalWrite(led_verde_2, LOW); digitalWrite(led_verde_4, LOW); digitalWrite(led_roja_3, LOW); digitalWrite(led_roja_1, HIGH); digitalWrite(led_roja_2, HIGH); digitalWrite(led_roja_4, HIGH); delay(2000); digitalWrite(led_verde_3, LOW); } void LED_4A_green(){ digitalWrite(led_amarilla_3, HIGH); digitalWrite(led_amarilla_4, HIGH); delay(2000); digitalWrite(led_amarilla_1, LOW); digitalWrite(led_amarilla_2, LOW); digitalWrite(led_amarilla_3, LOW); digitalWrite(led_amarilla_4, LOW); delay(200); digitalWrite(led_verde_4, HIGH); digitalWrite(led_verde_1, LOW); digitalWrite(led_verde_2, LOW); digitalWrite(led_verde_3, LOW); digitalWrite(led_roja_4, LOW); digitalWrite(led_roja_1, HIGH); digitalWrite(led_roja_2, HIGH); digitalWrite(led_roja_3, HIGH); delay(2000); digitalWrite(led_verde_3, LOW); } void checkBotonStatus(){ botonState1 = digitalRead(boton1); botonState2 = digitalRead(boton2); botonState3 = digitalRead(boton3); botonState4 = digitalRead(boton4); if(botonState1 == HIGH){ i = 4; } if(botonState2 == HIGH){ i = 1; } if(botonState3 == HIGH){ i = 2; } if(botonState4 == HIGH){ i = 3; } } void loop() { for(i=1; i<5; ++i){ switch(i){ case 1: LED_1A_green(); checkBotonStatus(); break; case 2: LED_2A_green(); checkBotonStatus(); break; case 3: LED_3A_green(); checkBotonStatus(); break; case 4: LED_4A_green(); checkBotonStatus(); break; } } }
#include <LiquidCrystal.h> int rojo1 = 2; int verde1 = 4; int rojo2 = 5; int verde2 = 7; int boton1 = 3; int boton2 = 6; int turno = 1; int c; LiquidCrystal lcd(13, 12, 11, 10, 9, 8); void setup() { lcd.begin(16,2); pinMode(boton1, INPUT_PULLUP); pinMode(boton2, INPUT_PULLUP); pinMode(rojo1,OUTPUT); pinMode(verde1,OUTPUT); pinMode(rojo2,OUTPUT); pinMode(verde2,OUTPUT); } void loop() { if(turno == 1) { for( c = 5; c > 0 ; c--) { if(digitalRead(boton1) == LOW) { c = 0; } digitalWrite(rojo1, LOW); digitalWrite(verde2, LOW); digitalWrite(verde1, HIGH); digitalWrite(rojo2, HIGH); lcd.setCursor(0,0); lcd.print("Verde"); lcd.setCursor(0,1); lcd.print(c); delay(1000); lcd.clear(); } turno++; } else if(turno == 2) { for(c = 5; c > 0 ; c--) { if(digitalRead(boton2) == LOW ) { c = 0; } digitalWrite(verde1,LOW); digitalWrite(rojo2, LOW); digitalWrite(rojo1, HIGH); digitalWrite(verde2, HIGH); lcd.setCursor(0,0); lcd.print("Rojo"); lcd.setCursor(0,1); lcd.print(c); delay(1000); lcd.clear(); } turno = 1; } }``` 
Por poco cumplo el reto 😅😅 Comparto mi código, Arduino y diagrama de flujo. Necesitaría una pista, si no es molestia. Armé estos semáforos basados en el sistema que vi en L.A., que cuando un peatón aprieta el botón, todos los semáforos se ponen en rojo y los peatones pueden cruzar para cualquier lado.
Usé 2 Leds RGB para simular el semáforo principal, 2 Leds azules para simular las luces de giro y 2 blancos para simular la luz de los peatones. La idea es que, como no me alcanzan los pines digitales, cada uno cumple la función los 2 semáforos de la avenida (que están enfrentados).
Mi problema es que quiero que cuando se apriete un botón, el programa espere a que el Led termine su acción y luego pase al sistema de peatón. En el sentido que no se apriete el botón y pase automáticamente al modo de peatones. Y si alguno sabe, estaría agradecido que me diera aunque sea una pista para después yo averiguar por mí mismo.
Me encantó el curso hasta ahora!!
Usé el Monitor Serial para hacer controles nada más.
//p refiere a la avenida principal, mientras que s refiere a la avenida secundaria constint redP = 11; constint greenP = 10; constint blueP = 9;; constint peatonP = 13; constint giroP = 12; constint redS = 7; constint greenS = 6; constint blueS = 5; constint peatonS = 3; constint giroS = 4; constint button = 2; int button_value; int button_pressed = LOW; long previousTime = 0; int semaforo = 0; long semaforo_rojo_verde = 16000; long semaforo_peatones = 16000; long semaforo_giro = 6000; long semaforo_amarillo = 2000; voidsetup() { pinMode(redP, OUTPUT); pinMode(greenP, OUTPUT); pinMode(blueP, OUTPUT); pinMode(peatonP, OUTPUT); pinMode(giroP, OUTPUT); pinMode(redS, OUTPUT); pinMode(greenS, OUTPUT); pinMode(blueS, OUTPUT); pinMode(peatonS, OUTPUT); pinMode(giroS, OUTPUT); pinMode(button, INPUT_PULLUP); Serial.begin(9600); } voidloop() { button_value = digitalRead(button); unsignedlong currentTime = millis(); //En esta cadena de if se van apagando y prendiendo LEDs siguiendo un orden especifico para simular la actuacion de los semaforos en la calle //currentTime = previousTime es necesario porque, una vez que se supera el tiempo que se quiere, la accion queda. Si esta igualdad no estuviera, la accion se repetiria todo el tiempo. Es un if, no un while\ //El tiempo que se fija a superar en los if se refiere al de la duracion del if anterior. En el caso 0 se refiere al 10 //Estructura en los digitalWrite: // 1 - Leds que pasan a HIGH y Leds que pasan a LOW, tienen un delay de 100, haciendo de cuenta que pasarian a ser otro Led mas o que el RGB va a cambiar de color, y pasan de vuelta a HIGH // 2 - Leds que permanecen en HIGH // 3 - Leds que pasan a LOW // 4 - Leds que permanecen en LOW if(semaforo == 0) { if (currentTime - previousTime > semaforo_amarillo) { previousTime = currentTime; semaforo++; digitalWrite(redP, HIGH); digitalWrite(giroP, HIGH); digitalWrite(redS, HIGH); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); digitalWrite(giroS, LOW); Serial.println("0"); Serial.println(currentTime); } } if(semaforo == 1) { if (currentTime - previousTime > semaforo_giro) { previousTime = currentTime; semaforo++; digitalWrite(giroP, LOW); delay(100); digitalWrite(giroP, HIGH); digitalWrite(redP, HIGH); digitalWrite(redS, HIGH); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); digitalWrite(giroS, LOW); Serial.println("1"); Serial.println(currentTime); } } if(semaforo == 2) { if (currentTime - previousTime > semaforo_giro) { previousTime = currentTime; semaforo++; digitalWrite(redP, LOW); delay(100); digitalWrite(redP, HIGH); digitalWrite(greenP, HIGH); digitalWrite(redS, HIGH); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(giroP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); digitalWrite(giroS, LOW); Serial.println("2"); Serial.println(currentTime); } } if(semaforo == 3) { if (currentTime - previousTime > semaforo_amarillo) { previousTime = currentTime; semaforo++; digitalWrite(greenP, LOW); delay(100); digitalWrite(greenP, HIGH); digitalWrite(peatonP, HIGH); digitalWrite(redS, HIGH); digitalWrite(redP, LOW); digitalWrite(blueP, LOW); digitalWrite(giroP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); digitalWrite(giroS, LOW); Serial.println("3"); Serial.println(currentTime); } } if(semaforo == 4) { if (currentTime - previousTime > semaforo_rojo_verde) { previousTime = currentTime; semaforo++; digitalWrite(greenP, LOW); delay(100); digitalWrite(greenP, HIGH); digitalWrite(redP, HIGH); digitalWrite(redS, HIGH); digitalWrite(peatonP, LOW); digitalWrite(blueP, LOW); digitalWrite(giroP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); digitalWrite(giroS, LOW); Serial.println("4"); Serial.println(currentTime); } } if(semaforo == 5) { if (currentTime - previousTime > semaforo_amarillo) { previousTime = currentTime; semaforo++; digitalWrite(redP, LOW); delay(100); digitalWrite(redP, HIGH); digitalWrite(giroS, HIGH); digitalWrite(giroS, HIGH); digitalWrite(redS, HIGH); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(giroP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); Serial.println("5"); Serial.println(currentTime); } } if(semaforo == 6) { if (currentTime - previousTime > semaforo_giro) { previousTime = currentTime; semaforo++; digitalWrite(giroS, LOW); delay(100); digitalWrite(giroS, HIGH); digitalWrite(redP, HIGH); digitalWrite(redS, HIGH); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(giroP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); Serial.println("6"); Serial.println(currentTime); } } if(semaforo == 7) { if (currentTime - previousTime > semaforo_giro) { previousTime = currentTime; semaforo++; digitalWrite(redS, LOW); delay(100); digitalWrite(redS, HIGH); digitalWrite(greenS, HIGH); digitalWrite(redP, HIGH); digitalWrite(giroS, LOW); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(giroP, LOW); digitalWrite(blueS, LOW); digitalWrite(peatonS, LOW); Serial.println("7"); Serial.println(currentTime); } } if(semaforo == 8) { if (currentTime - previousTime > semaforo_amarillo) { previousTime = currentTime; semaforo++; digitalWrite(greenS, LOW); delay(100); digitalWrite(greenS, HIGH); digitalWrite(peatonS, HIGH); digitalWrite(redP, HIGH); digitalWrite(redS, LOW); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(giroP, LOW); digitalWrite(blueS, LOW); digitalWrite(giroS, LOW); Serial.println("8"); Serial.println(currentTime); } } if(semaforo == 9) { if (currentTime - previousTime > semaforo_rojo_verde) { previousTime = currentTime; semaforo++; digitalWrite(greenS, LOW); delay(100); digitalWrite(greenS, HIGH); digitalWrite(redS, HIGH); digitalWrite(redP, HIGH); digitalWrite(peatonS, LOW); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(peatonP, LOW); digitalWrite(giroP, LOW); digitalWrite(blueS, LOW); digitalWrite(giroS, LOW); Serial.println("9"); Serial.println(currentTime); } } if(semaforo > 9) { semaforo = 0; } if (button_value == LOW && button_pressed == LOW) { digitalWrite(redP, HIGH); digitalWrite(peatonP, HIGH); digitalWrite(redS, HIGH); digitalWrite(peatonS, HIGH); digitalWrite(greenP, LOW); digitalWrite(blueP, LOW); digitalWrite(giroP, LOW); digitalWrite(greenS, LOW); digitalWrite(blueS, LOW); digitalWrite(giroS, LOW); delay(semaforo_peatones); Serial.println("boton"); Serial.println(currentTime); button_pressed = HIGH; } if (button_value == HIGH && button_pressed == HIGH) { button_pressed = LOW; } }
Me quede sin entradas pwd en el arduino. XD pero hize el código con 3 led. Lo voy a dejar para que pueda estudiarlo y si alguien cuenta con una placa más grande como la Arduino MEGA pueda terminarlo.
const int RETARDO_VERDE = 4000; const int RETARDO_PARPADEO_VERDE = 500; const int RETARDO_AMARILLO = 2000; const int verde = 0; const int amarillo = 1; const int rojo = 2; int j = 0; //configuración de led int light[4][3] = { {2,3,4}, {5,6,7}, {8,9,10}, {11,12,13}, }; void setup() { for (int i = 0; i < 4; i++){ digitalWrite(light[i][verde],LOW); digitalWrite(light[i][rojo],HIGH); digitalWrite(light[i][amarillo],LOW); pinMode(light[i][verde],OUTPUT); pinMode(light[i][amarillo],OUTPUT); pinMode(light[i][rojo],OUTPUT); } } void loop() { digitalWrite(light[j][verde],HIGH); digitalWrite(light[j][amarillo],LOW); digitalWrite(light[j][rojo],LOW); delay(RETARDO_VERDE); for(int i = 0; i < 6; i++) { if((i%2) == 0){ digitalWrite(light[j][verde],HIGH); }else{ digitalWrite(light[j][verde],LOW); } delay(RETARDO_PARPADEO_VERDE); } digitalWrite(light[j][amarillo],HIGH); delay(RETARDO_AMARILLO); digitalWrite(light[j][amarillo],LOW); digitalWrite(light[j][rojo],HIGH); j++; if(j>3){ j=0; } }```