Error en secuencia de encendido de leds; fallo en el código o en la simulación??

Buenas tardes a todos,

Soy nuevo en el foro y estoy empezando con Arduino, así que en primer lugar pido disculpas si la forma en la que edito este mensaje no es la más adecuada. Si en el mensaje o en la forma hay algo que se considere incorrecto, por favor, ruego seais comprensibles y me aviséis para poder cambiar lo que sea necesario.

En una práctica que estoy realizando me surge un problema de funcionamiento y la verdad es que no se si es por algún error en el código que he escrito o es a la hora de simular en Proteus.

El programa debe realizar lo siguiente:

Al detectar un flanco de subida en el pin analógico A0 se deben ir encendiendo y apagando secuencialmente los pines de salida 5, 6, 7 y 8 (200ms encendido, 200ms apagado).

El problema que observo a la hora de simularlo es que en ocasiones el pin5 se queda activado durante toda la secuencia. En otras ocasiones se queda apagado mientras la secuencia de los pines 6 al 8 se realiza correctamente.

Algo que me hace sospechar de la simulación en Proteus es que si no escribo un "Serial.print" antes de un "if" este if no se ejecuta aún cumpliendose la condición.

Más abajo he copiado el código que he empleado. También adjunto el archivo por si alguien quisiera probarlo.

  int TiempoON = 200; //Tiempo que ha de estar el LED encendido
  int TiempoOFF = 200; //Tiempo que ha de estar el LED apagado
  int TiempoTOTAL = 0; //Será la suma de TiempoON y TiempoOFF
  int Tiempo1 = 0;
  int Tiempo_origen = 0;
  int LED = 5;
  int Tiempo_anterior = 0;
  int Estado_actual = 0;
  int Estado_anterior = 0;
  void mi_funcion_tiempo();
  int flanco = 0;
  boolean interrupcion(int flanco);
  
void setup() {
  Serial.begin(9600);
  pinMode(A0,INPUT);
  pinMode(5,OUTPUT);
  pinMode(6,OUTPUT);
  pinMode(7,OUTPUT);
  pinMode(8,OUTPUT);

}

void loop() {

  flanco, interrupcion();
  if (flanco==1){
      for (LED=5; LED<=8; LED++){
        mi_funcion_tiempo (); 
        flanco = 0;
      }
  }
}


boolean interrupcion(){  //esta función (que no es una interrupción) sirve para detectar un flanco ascendente en la entrada analógica A0
  Tiempo_anterior = millis();
  Estado_anterior = analogRead(A0);
  Serial.println("ALGO RARO");    //Sucede algo que si no tengo esta línea aquí no me entra en el if
  if ((Tiempo_anterior + 1)<millis()){  //cuando pasan más de 5 milisegundos desde que se asignó el valor de "Tiempo_anterior" se cumple la condición.
      Estado_actual = analogRead(A0);
      if (Estado_actual>Estado_anterior){  //Se cumple la condición cuando se detecta un cambio de nivel (flanco de subida) en el pin A0.
          flanco = 1;
          return flanco;      
      }
  }
  
  
}


void mi_funcion_tiempo(){
    
    while((Tiempo1-Tiempo_origen) <= TiempoON){  
      //Mientras Tiempo1-Tiempo_origen sea menor que el tiempo de encendido se ejecutará el while y la salida LED estará activa.
      Tiempo1 = millis();
      digitalWrite(LED,HIGH);
    }

    //Serial.println("ZONA_WHILES");
    TiempoTOTAL=TiempoON+TiempoOFF;
   
    while((Tiempo1-Tiempo_origen)<=TiempoTOTAL){  //(TiempoON+TiempoOFF)
      //Mientras Tiempo1-Tiempo_origen sea menor que la suma del tiempo de encendido y del tiempo de apagado, se ejecutará el while y la salida LED estará desactivada.
      digitalWrite(LED,LOW);
      Tiempo1 = millis();  
    }
        
    Tiempo_origen = millis();   //Igualamos el Tiempo_origen a millis() para el siguiente ciclo.

}

robotica_prac_3_pruebas.ino (2.15 KB)

Hola.
Veo así a primera vista dos cuestiones que no entiendo muy bien. Por un lado, aunque no lance error al compilar, la siguiente línea no sé qué efecto puede tener:

 flanco, interrupcion();

¿Qué pinta "flanco, " antes de la llamada a la función?

Y en la parte en la que dices que no se ejecuta el if si no pones el serial.print, creo que es evidente:

Nada más entrar en la función, se carga millis en Tiempo_anterior.

  Tiempo_anterior = millis();
  Estado_anterior = analogRead(A0);

Luego pones el siguiente if:

  if ((Tiempo_anterior + 1)<millis()){  //cuando pasan más de 5 milisegundos desde que se asignó el valor de "Tiempo_anterior" se cumple la condición.

Como acabas de cargar millis en Tiempo_anterior, sólo entraría en tu if si cuando llegas a la comprobación ha pasado un milisegundo (tiempo_anterior+1) desde que habías cargado hasta que compruebas. No te entra por tanto en dicho if, porque normalmente no ha transcurrido ese milisegundo, salvo cuando "pierdes tiempo" en el serial.print.

Me da la sensación de que no has terminado de tomar el concepto de cómo funciona millis. Supongo que lo que intentas hacer en este caso pasaría por meter los pasos que te puse en el primer bloque dentro del propio if (de paso puedes poner los cinco milisegundos que citas en el comentario, en lugar de uno). Te recomiendo que en lugar del if sumando como lo tienes, hacerlo de la forma if ((millis()-Tiempo_anterior)>= 5). Al meter los pasos en el if, tiempo_anterior sólo se va a "recargar" cada vez que se alcancen cinco milisegundos; no siempre que entres en la función.

que es esto?

flanco, interrupcion();

siempre lo usé como

interrupción(flanco);

Buenas tardes,

Ante todo, gracias por vuestras respuestas y por la rapidez.

En cuanto a lo de

Code: [Select]

flanco, interrupcion();

Code: [Select]

Si os digo la verdad, no tengo ni idea de dónde lo he sacado. Creo que lo ví en algún ejemplo y lo escribí tal cual. Ya os digo que estóy empezando a programar ahora y apenas tengo idea de cómo usar las funciones o como llamar a ellas.

En cuanto al uso de millis(), creo que entiendo como funciona y que quizá mi problema no esté en el funcionamiento de millis sino en cómo plantee el código. Cuando noter comentó la forma en que debería haber empleado la condición del if vi que cometí un error.

He modificado un poco el código, cambiando la condición del if (y quitando lo de flanco, interrupcion(); ), pero sigue sin funcionar correctamente. Esta noche trataré de encontrar cuál es el fallo que estoy cometiendo y si no lo encontrase os volvería a pedir ayuda.

Saludos, y nuevamente gracias!!!