Go Down

Topic: Problema al Configurar Semáforo con Tres Tiempos Diferentes  (Read 2939 times) previous topic - next topic

brayan24


Hola, soy nuevo en el foro y también en arduino.

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.

Code: [Select]


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.

Arduinito

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:
1. Cada cual programa como gusta luego puede ser que mi ejemplo "no sea de tu gusto / para ti".
2. 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)

Code: [Select]

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:



Un saludo y espero haberte ayudado en algo.
Cualquier duda con el código me puedes preguntar.

Arduinito

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.

noter

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.

Code: [Select]
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
  }
}

Arduinito

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 :smiley-mr-green:

Saludos.

P.D: Me quedo con esto:

Code: [Select]

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.

noter

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.

Go Up