Montaje 4: Cerradura digital de seguridad

Requisitos:

  • 4 LEDs, 4 resistencias de 220 ohmios
  • 4 pulsadores, 4 resistencias de 1Kohmio.
  • Un motor dc
  • 2 Finales de carrera

Planteamiento: La primera secuencia de 4 pulsaciones nos cierra la puerta. Para abrirla, tendremos que repetir la misma secuencia. Pero, cuidado, sólo tenemos 3 intentos y si fallamos, se bloqueará y se dispara la alarma.

Presentación: Cómo comparar los elementos de dos cadenas.

En el ejercicio anterior aprendimos aguardar secuencias de pulsaciones. Para completar este montaje necesitamos dos cosas más:

  • Distinguir la primera secuencia de las demás
  • Compararla con otras

La distinción la hacemos con un contador, la variable c, que aumenta en uno cada vez que se completa una secuencia, y guardando los dos casos en cadenas distintas

 if(c= =0){                                
   codePuls[m]=seriePuls[m]+4;             
 }                                        
 else{                                   
   serieLeds[m]=seriePuls[m]+4;            
 }

La comparación se va preparando al distinguirlas pues elegimos guardar todas las pulsaciones con los valores de los PINes de los LEDs asociados, porque así nos servirán también para reproducir los intentos fallidos.

Se realiza contando comparando elemento a elemento de las dos cadenas y sumando 1 a la variable aciertos cada vez que coinciden. Esto se hace iterando sobre las posiciones en las cadenas en el procedimiento compruebacode( ).

Ya sólo queda usar unos condicionales para que:

  • la primera vez se cierre, con un if/else
  • en las siguientes si se acierta se abra y si no se reproduzca, lo que es un condicional if/else incrustado en el else del condicional anterior
  • junto con un while bloqueen el programa si se rebasa el nº permitido de intentos.

Debe notarse cómo se reinician las variables en cada caso:

  • si se acierta se reinician todas, incluída la cuenta de las secuencias
  • si se falla sólo se reinicia la cuenta de los aciertos en cada secuencia

Variantes:

  • Puedes cambiar tanto el nº de intentos como la longitud del código. Ten en cuenta que el nº de elementos en la declaración de las cadenas que guardan las secuencias tiene que ser igual o mayor que la longitud del código.

VIDEO DEL MONTAJE 4

CODIGO FUENTE

 Copyright (C) 2006  Juan Carlos Alonso de Mena
 This program is free software; you can redistribute it and/or modify it under the terms
 of the GNU General Public License as published by the Free Software Foundation;
 See the GNU General Public License for more details?

 int cadenaLeds[]={6,7,8,9};
 int cadenaPuls[]={2,3,4,5};
 int serieLeds[]={0,0,0,0};
 int seriePuls[]={0,0,0,0};
 int codePuls[]={0,0,0,0};
 int motor1=12;
 int motor2=13;
 int findecarrera1=10;
 int findecarrera2=11;
 int n=0;
 int m=0;
 int c=0;
 int aciertos=0;
 int nintentos=3;
 void setup (){
   for(n=0;n<4;n++){
     pinMode(cadenaLeds[n],OUTPUT);
     pinMode(cadenaPuls[n],INPUT);
   }
   pinMode(findecarrera1,INPUT);
   pinMode(findecarrera2,INPUT);
   pinMode(motor1,OUTPUT);
   pinMode(motor2,OUTPUT);
 }
 void flash(){
   for(n=0;n<4;n++){
     digitalWrite(cadenaLeds[n],HIGH);
   }
   delay(200);
   for(n=0;n<4;n++){
     digitalWrite(cadenaLeds[n],LOW);
   }
   delay(200);
 }
 void cierra(){                                    //el motor se activa en un sentido hasta que toca el final
                                                   // de carrera
   while(digitalRead(findecarrera1)==LOW){
     digitalWrite(motor1,HIGH);
   }
   digitalWrite(motor1,LOW);
 }
 void abre(){                                      //el motor se activa en sentido contrario hasta que toca
                                                   // el otro final de carrera
   while(digitalRead(findecarrera2==LOW)){
     digitalWrite(motor2,HIGH);
   }
   digitalWrite(motor2,LOW);
 }
 void guardapuls(){
  while(digitalRead(2)==LOW&&digitalRead(3)==LOW&&digitalRead(4)==LOW&&digitalRead(5)==LOW){    //Esperando que se pulse alguno
     delay(100);
   }
   while(m<4){                                 //bucle que itera las 4 pulsaciones
     for(n=0;n<4;n++){                         //bucle que recoorre los 4 pulsadores para ver si se han pulsado
       if(digitalRead(cadenaPuls[n])==HIGH){  
         digitalWrite(cadenaLeds[n],HIGH);
         delay(200);
         digitalWrite(cadenaLeds[n],LOW);   
         seriePuls[m]=cadenaPuls[n];
         if(c==0){                       //si es la primera vez
           codePuls[m]=seriePuls[m]+4;   //la serie de pulsaciones forma el código de seguridad, 
         }                               //que guardamos ya en términos de los LEDs que acompañan a cada pulsador
         else{                           //si no es la primera vez
            serieLeds[m]=seriePuls[m]+4; //guardamos las pulsaciones traduciéndolas a los LEDs correspondientes
         }
         delay(200);
         m=m+1;                          //variable que guarda la cuenta de las pulsaciones
       }
     }
   }
 }
 void compruebacode(){                   //procedimiento que compara la serie del  código de seguridad  
   for(n=0;n<4;n++){                     //con la serie posterior de pulsaciones
     if(serieLeds[n]==codePuls[n]){                
       aciertos=aciertos+1;              //variable que lleva la cuenta de las pulsaciones que coinciden 
                                         // con las del código
     }
   }
 }
 void replay(){                                  
   for(n=0;n<4;n++){                   
     digitalWrite(serieLeds[n],HIGH);
     delay(200);
     digitalWrite(serieLeds[n],LOW);
     delay(200);
   }
 }
 void loop(){
   guardapuls();
   m=0;                                  //Ahora, cuando se ha terminado el while de     guardapuls() ya 
                                         //han pasado 4 pulsaciones y se vuelve a empezar la cuenta
   if(c==0){                             //si es la primera vez:
     cierra();                           // se cierra
     c=c+1;                              // se lleva la cuenta de las veces  
   }

//replay(); // si quitamos el comentario podemos comprobar si hemos guardado

                                         // bien las pulsaciones
   else{                                 //si no es la primera vez (no estamos guardando el código, 
                                         // estamos intentando abrir)
     compruebacode();                    //comprobamos las pulsaciones contando cuántas coinciden
     if(aciertos==4){                    //si coinciden las 4:
       abre();                           // se abre
       c=0;                              //reiniciamos la cuenta de las veces
       aciertos=0;                       // y la cuenta de los aciertos
     }
     else{                               //si no coinciden las 4:
       replay();                         //reproducimos las pulsaciones que hemos introducido
       aciertos=0;                       //y reiniciamos
       c=c+1;                            //pero llevando la cuenta de las veces (que nos sirve también
                                         // para contar los intentos de abrir)
     }
     while(c>nintentos){                 //si nos pasamos del nº de intentos entra en un bucle sin fin 
                                         //con destellos y se bloquea
       flash();
     }
   }
 }

Volver?

  Copyright (c) 2006  Juan Carlos Alonso de Mena

  Permission is granted to copy, distribute and/or modify this document under the terms of 
 the GNU Free Documentation License, Version 1.2 or any later version published by the
 Free Software Foundation; with no Invariant Sections, no Front-Cover Texts, and no
 Back-Cover Texts.  A copy of the license is included in the section entitled 
 GNU Free Documentation License?.