Tengo un problema al realizar un semáforo con tres tiempos diferentes a partir de un botón, la idea es que al presionar el botón la primera vez, el semáforo funcione con un tiempo primario, al presionar de nuevo el botón cambie de tiempo y que estoy lo haga de igual manera con otro tiempo, lo intente realizar con condicionales if pero no me funciona, este es el código que tengo, de ante mano gracias por si colaboración.
int estado = 0;
int Rojo = 10; // Variable con su pin
int Amarillo = 9;
int Verde = 8;
int Boton = 13; // pin del interruptor 1
bool actBoton = 0; // estado actual boton
void setup() {
pinMode (Rojo,OUTPUT); // indicamos el modo en el que va a trabajar el pin "Salida"
pinMode (Amarillo,OUTPUT); // "Salida"
pinMode (Verde,OUTPUT); // "Salida"
pinMode (Boton,INPUT); // "Entrada"
}
void loop(){
actBoton = digitalRead (Boton);
if (actBoton == 1)
{
digitalWrite (Verde,HIGH);
delay (1000);
digitalWrite (Verde,LOW);
digitalWrite (Amarillo,HIGH);
delay (1000);
digitalWrite (Amarillo,LOW);
digitalWrite (Rojo,HIGH);
delay (1000);
digitalWrite (Rojo,LOW);
digitalWrite (Amarillo,HIGH);
delay (1000);
digitalWrite (Amarillo,LOW);
actBoton = 0;
}
}
void PrimerT() {
actBoton = digitalRead (Boton);
if (actBoton == 1)
{
digitalWrite (Verde,HIGH);
delay (3000);
digitalWrite (Verde,LOW);
digitalWrite (Amarillo,HIGH);
delay (3000);
digitalWrite (Amarillo,LOW);
digitalWrite (Rojo,HIGH);
delay (3000);
digitalWrite (Rojo,LOW);
digitalWrite (Amarillo,HIGH);
delay (3000);
digitalWrite (Amarillo,LOW);
delay (3000);
estado = 0;
}
}
void SegundoT() {
actBoton = digitalRead (Boton);
if (actBoton == 1)
{
digitalWrite (Verde,HIGH);
delay (5000);
digitalWrite (Verde,LOW);
digitalWrite (Amarillo,HIGH);
delay (5000);
digitalWrite (Amarillo,LOW);
digitalWrite (Rojo,HIGH);
delay (5000);
digitalWrite (Rojo,LOW);
digitalWrite (Amarillo,HIGH);
delay (5000);
digitalWrite (Amarillo,LOW);
estado = 0;
}
}
brayan24:
Por favor necesito de la colaboración de cada uno de ustedes.
Hola, brayan24.
A ver, vale, estas empezando, yo también, pero no se puede obligar a la gente del foro a que te den las cosas hechas (no has planteado una duda), y en tu caso lo pudiste resolver perfectamente "googleando", más en tu caso que son ejemplos de leds.
Poner un pedazo de código mal y pedir que te lo hagan produce el efecto contrario al que buscas. Aparte no ayuda que pongas tú código que si ya de por si repite mil líneas pones funciones que ni estás usando.
Dicho lo cual te pongo un ejemplo, pero te comento dos cosas:
Cada cual programa como gusta luego puede ser que mi ejemplo "no sea de tu gusto / para ti".
Si haces copy and paste de códigos jamás aprenderás ni podrás hacer nada por ti mismo.
Te explico lo que hace este código:
Se encienden y apagan 3 leds (pins del 3 al 5). azul/amarrillo/amarillo/rojo/amarillo/amarillo(repetimos)
Pulsador en pin 2.
El led 4 (amarillo parpadea 2 veces).
Como en tu ejemplo después del rojo vuelve al amarillo.
Al cambiar el estado del pulsador se cambian los tiempos de retardo entre encendido y apagado.
Guardo la posición del led que se estaba cambiando para cuando pulse el botón se cambie el tiempo y no el orden. (que no se reinicie)
int tiempo = 1000;
boolean estado = 0;
byte led_actual = 0; //posición array
byte orden_leds[] = {3,4,4,5,4,4};
void setup() {
//Pulsador
pinMode(2,INPUT);
//Leds
for(byte i = 3; i < 6; i++){
pinMode(i,OUTPUT);
}
}
void loop() {
if(led_actual == sizeof(orden_leds) / sizeof(orden_leds[0])){
led_actual = 0;
}
for(byte i = led_actual; i < sizeof(orden_leds) / sizeof(orden_leds[0]); i++ ){
if(digitalRead(2) != estado){
apagar(false);
break; //salimos del bucle
}
apagar(true);
digitalWrite(orden_leds[i],HIGH);
if(digitalRead(2) != estado){
apagar(false);
break;
}
led_actual = i+1;
delay(tiempo);
}
}
void apagar(boolean pausar){
for(byte i = 3; i < 6; i++){
digitalWrite(i,LOW);
}
//cambiar opciones de tiempo
tiempo = (estado) ? 3000 : 1000;
estado = digitalRead(2);
if(pausar){
delay(tiempo);
}
}
Y la conexión no sabemos tampoco como la tienes pero aquí un ejemplo de 2 minutos:
Ah, sí, los breaks dentro del for es para detener el for cuando se ha cambiado el estado del botón y guardo en que led me quedé para proseguir con el orden del "semáforo" variando sólo el tiempo.
Si tu quieres que siga la secuencia hasta el final y al dar la vuelta cambie el tiempo entonces tendrás que cambiar el planteamiento.
Bueno, Brayan24...
El ver alguien que en su primer post ha utilizado los tags de código me emocionó tanto que me puse a construir un código, e incluso intenté explicarlo; así que, aunque seguramente que tiene muchas similitudes con lo que ha puesto Arduinito, lo dejo por aquí por si puede serte de utilidad a tí o a terceros.
Saludos.
const int Rojo = 10, Amarillo = 9, Verde = 8, Boton = 13; // pin del interruptor 1
const int secuencia[4] = {Verde, Amarillo, Rojo, Amarillo}; // Orden de encendido
int estadoAntBoton=LOW; // último estado del pulsador
int secuenciaActual=0; // Indica qué secuencia de esperas se está utilizando
int luzActual = 0; // indica qué luz dentro de la secuencia está encendida
unsigned long millisInicioUltimoEstado=millis(); // "hora" a la que se encendió la luz actual
int esperas[3][4] = {
{1000, 300, 300, 300},
{300, 300, 1000, 300},
{300, 300, 300, 1000},
};
void setup() {
pinMode (Rojo,OUTPUT); // indicamos el modo en el que va a trabajar el pin "Salida"
pinMode (Amarillo,OUTPUT); // "Salida"
pinMode (Verde,OUTPUT); // "Salida"
pinMode (Boton,INPUT); // "Entrada"
}
void loop(){
int estadoActBoton = digitalRead(Boton);
if (estadoActBoton != estadoAntBoton){ // Si cambió el último estado del pulsador
estadoAntBoton = estadoActBoton; // almacenamos el estado actual como último
if (estadoAntBoton == HIGH) { // si hemos pasado de LOW a HIGH
secuenciaActual ++; // Cambiamos a la siguiente secuencia de esperas
if (secuenciaActual >=3) secuenciaActual = 0; // Si nos pasamos de la última, volvemos a la primera
}
}
if (millis() - millisInicioUltimoEstado >= esperas[secuenciaActual][luzActual]) { // Si ha pasado el tiempo de la secuencia/luz actual
millisInicioUltimoEstado = millis(); // reiniciamos el cronómetro
digitalWrite(secuencia[luzActual], LOW); // apagamos la luz actual
luzActual ++; // pasamos a la siguiente luz de la secuencia
if (luzActual >= 4) luzActual = 0; // si nos pasamos del último paso, volvemos al priemro
digitalWrite(secuencia[luzActual], HIGH); // y encendemos la luz correspondiente
}
}
noter, el mío es un ejemplo rápido, puestos a hacerlo bien bien bien mejor como el tuyo con millis() y no con delay, (no me gusta usar delay y el día q lo haga será porque de verdad deba parar TODO), por no decir que en el tuyo fuiste más allá de su código y añades los tiempos en un array bidimensional, pero bueno lo dicho, fue un ejemplo de dos minutos
Saludos.
P.D: Me quedo con esto:
const int Rojo = 10, Amarillo = 9, Verde = 8, Boton = 13; // pin del interruptor 1
const int secuencia[4] = {Verde, Amarillo, Rojo, Amarillo}; // Orden de encendido
No es un array asociativo tipo php... pero visualmente para exponer un ejemplo de array está bien verlos como si fuesen los índices.
Arduinito:
Ya que le había dedicado un rato a hacerlo, decidí ponerlo a pesar de que ya habías propuesto una solución válida. Por una parte porque me emocionó (no llegué a llorar, pero casi :))) ver que alguien en su primer post había utilizado la etiqueta de código (y creo que es de agradecer). Por otra parte, porque podía ser de interés para terceros. Me alegro de haberlo puesto, en vista de que tu comentario (gracias). A mí también me gusta revisar las soluciones de otros, ya que siempre puedes aprender algo nuevo.
Brayan24:
Evidentemente, aún estás en fases tempranas en esto del C++. Sin embargo, el hecho de haber puesto tu mensaje bien me hace creer que te tomaste la molestia de leer las normas (eso a mí al menos me indica un interés "sincero") y por ello nos hemos molestado en darte la solución prácticamente terminada. Tómate la molestia ahora de intentar no sólo copiar, sino entender y adaptar las soluciones que te hemos propuesto. Por supuesto si hay algo que no entiendas y quieras entender, para eso está este foro.
Saludos a ambos.