domingo, 17 de febrero de 2013

Sesión III (2ª parte)

Hacemos la segunda parte de la sesión dedicada exclusivamente a finalizar el prototipo de semáforo doble añadiendo la funcionalidad que nos faltó, esto es:


  • Añadir un segundo semáforo modificando la programación para contemplar los cambios de este nuevo semáforo.
  • Añadir un botón para seleccionar 'Todo Naranja' para los dos semáforos
dada la nula experiencia de programación de los alumnos vamos despacio para que entiendan los conceptos y poco a poco podamos refinar el código. Es decir, hoy no les voy a hablar de las interrupciones en Arduino si no que vamos a introducir el botón como parte del loop para que de esa forma se vayan planteando necesidades que después iremos implementando.

Así, en la primera implementación completa del segundo semáforo, antes de añadir el botón, lo que hacemos es modificar la escala de tiempos (añadimos más delays) para contemplar los pasos a naranja desde verde mientras que está en rojo el otro. Volvemos a trabajar el diagrama de tiempos para que ellos deduzcan los espacios a considerar.

Cuando introducimos el botón y la funcionalidad de 'Todo Naranja', lo hacemos al principio del bucle mirando si está o no pulsado el botón. El problema que aparece con esta localización es que sólo se evalúa cuando todo el bucle de tiempo se ejecuta, pero insisto que es interesante esta aproximación paso a paso para que vean casuísticas y cómo se resuelven.
Sin entrar todavía en interrupciones y para acotar más el problema, lo que hacemos es que nos creamos una función 'espera y mira' que lo que hace es hacer delays más cortos y evaluar el botón.
Aparece entonces otro comportamiento que no les gusta y es que cuando se deja de pulsar el botón se recupera la posición que había en el semáforo lo cual no es seguro en la vida real por lo que les introduzco el concepto de reinicio de bucle implementado con sentencias if.

El prototipo queda como se ve en la foto

Recomiendo echar un vistazo al código y al video que grabamos con el resultado (ya mejoraremos en esto porque no está muy fino) .

Código

/*
  Semaforo, Version 2
  Incluye dos semáforos y un botón para Naranja Parpadeante
  Febr 2013
  Arturo, Jaime
 */
 
int ledRojoSem1 = 12;
int ledNaranjaSem1 = 11;
int ledVerdeSem1 = 10;

int ledRojoSem2 = 5;
int ledNaranjaSem2 = 6;
int ledVerdeSem2 = 7;
 
int buttonState1 = 0; 

int duracion = 1000; 
int duracTotal = 1000;
boolean continuar= true;

//Duracion de Naranja. Rojo = 6*Naranja, Verde = 5*Naranja

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
//  Serial.begin(9600);
  pinMode(ledRojoSem1, OUTPUT);     
  pinMode(ledNaranjaSem1, OUTPUT);
  pinMode(ledVerdeSem1, OUTPUT);     
  pinMode(ledRojoSem2, OUTPUT);     
  pinMode(ledNaranjaSem2, OUTPUT);
  pinMode(ledVerdeSem2, OUTPUT);   
  pinMode(1,INPUT);                    // El Botón para todo Naranja
  pinMode(13,OUTPUT);
       
}

// the loop routine runs over and over again forever:
void loop() {

  digitalWrite(ledNaranjaSem1,LOW);
  digitalWrite(ledNaranjaSem2,LOW);
  continuar = true;
  
  digitalWrite(ledRojoSem1, HIGH);   // turn the LED on (HIGH is the voltage level)
  digitalWrite(ledVerdeSem2, HIGH);   // turn the LED on (HIGH is the voltage level)
  espera(5*duracion);
  if (continuar){
    digitalWrite(ledVerdeSem2, LOW);   // turn the LED oFF (LOW is the voltage level)
    digitalWrite(ledNaranjaSem2, HIGH);   // turn the LED on (HIGH is the voltage level)
    espera(duracion);
    if (continuar){
      digitalWrite(ledNaranjaSem2, LOW);   // turn the LED off (LOW is the voltage level)
      digitalWrite(ledRojoSem1, LOW);   // turn the LED off (LOW is the voltage level)
      digitalWrite(ledVerdeSem1, HIGH);   // turn the LED on (HIGH is the voltage level)
      digitalWrite(ledRojoSem2, HIGH);   // turn the LED on (HIGH is the voltage level)
      espera(5*duracion);
      if (continuar){
        digitalWrite(ledVerdeSem1, LOW);   // turn the LED oFF (LOW is the voltage level)
        digitalWrite(ledNaranjaSem1, HIGH);   // turn the LED on (HIGH is the voltage level)
        espera(duracion);   
        if (continuar){
          digitalWrite(ledNaranjaSem1, LOW);   // turn the LED off (LOW is the voltage level)
          digitalWrite(ledRojoSem2, LOW);   // turn the LED off (LOW is the voltage level)
        }
      }
    }
  }
}

void ponerNaranja(){
  digitalWrite(ledNaranjaSem2, HIGH);   // turn the LED off (LOW is the voltage level)
  digitalWrite(ledNaranjaSem1, HIGH);   // turn the LED off (LOW is the voltage level)
  digitalWrite(ledVerdeSem2, LOW);   // turn the LED off (LOW is the voltage level)
  digitalWrite(ledVerdeSem1, LOW);   // turn the LED off (LOW is the voltage level)
  digitalWrite(ledRojoSem2, LOW);   // turn the LED off (LOW is the voltage level)
  digitalWrite(ledRojoSem1, LOW);   // turn the LED off (LOW is the voltage level)
  delay(100);
  digitalWrite(ledNaranjaSem2, LOW);   // turn the LED off (LOW is the voltage level)
  digitalWrite(ledNaranjaSem1, LOW);   // turn the LED off (LOW is the voltage level)
  delay(50);
  
}

void espera(int duracTotal){
  int n;
  int fin = duracTotal/200;
  for (n = 0 ;fin > n;n++){
    delay(200);  //Espero 1/2 seg
    buttonState1 = digitalRead(1);  //Leer boton
    if (buttonState1 == HIGH) {
      while(buttonState1 == HIGH){
          ponerNaranja();
          buttonState1 = digitalRead(1);  //Leer boton
    }
    continuar= false;
    break;
    } 
  }
}

Aquí tenéis el video 

A modo de reflexión veo que va a ser importante hacer varias sesiones de programación (probaré con BlueJ) para que entiendan completamente las sentencias de control, la utilización de funciones, etc. sin entrar todavía en orientación a objetos.

Como siempre, cualquier aclaración o comentario ...

No hay comentarios:

Publicar un comentario