Tastiera apriporta con arduino

In questo articolo viene descritto un dispositivo in grado di azionare un relè se viene digitata una corretta sequenza numerica su una tastiera. L’utilizzo è stato pensato come apriporta, ma non si vogliono porre limiti alla fantasia. Il codice, per un massimo di 20 cifre, può essere cambiato in qualsiasi momento tramite procedura direttamente dalla stessa tastiera e viene memorizzato nella memoria non volatile di un Arduino utilizzante un processore atmel 328 (arduino 1, nano, mini ….)  funzionante a 5V. Se non si ricorda più la combinazione, un pulsante, che non deve essere accessibile esternamente, resetterà il dispositivo ad un valore prestabilito.

E’ possibile inserire, come opzione, un display a 7 segmenti per visualizzare il tasto premuto.
Un led, che segnala anche se il dispositivo è attivo, è previsto come aiuto nella digitazione.
Il numero dei componenti è minimo. Nel caso di un apriporta con serratura elettrica a 12 V alternati, si può prelevare questa tensione direttamente dal trasformatore o dal citofono per alimentare il circuito.
Il consumo è ridotto alle decine di milliampere come massimo. La tastiera può essere autocostruita. Nel prototipo e sul definitivo ho preferito usare una tastiera a matrice ultrapiatta con adesivo.  E’ fatta per l’uso in ambiente esterno e si trova nel WEB a basso costo.
In aggiunta al relè, in parallelo e all’occorrenza, si può abbinare un buzzer piezoelettrico autooscillante per evidenziare l’attivazione.
FUNZIONAMENTO:
Il led si accende con un lampeggio ogni 6 secondi circa. Dopo circa 10 sec di inattività si resettano tutte le operazioni intraprese se non portate a termine.
Digitare il codice giusto e attendere 2 sec per apertura (sicurezza di codice corretto e conosciuto) – il LED lampeggia 3 volte e sul display appare il simbolo H. La durata della attivazione del relè puo essere definita cambiando il valore temporele in millisecondi
CAMBIO PASSWORD: premere il tasto # per 3 sec. Il LED si accende fisso per 2 sec. Appena spento, digitare il codice CORRENTE.  Se è giusto si attiva la chiave (come aver digitato codice per apertura) e il LED inizia a lampeggiare velocemente. Attendere la fine del lampeggio ed inserire il nuovo codice. Confermare tenendo premuto per 3 sec (fino a che la luce non diventa fissa) il tasto #
il codice resta memorizzato.
RESET codice: tenendo premuto il trasto reset per almeno 3 secondi inizierà sul display un conto alla rovescia che azzera il codice e lo riporta al valore iniziale 25122000 (Natale 2000)

 

http://webingenerale.com/wp-content/uploads/2014/03/schema_tastiera.jpg

SKETCH:

/*
by Roberto Contessi - luglio 2013
Chiave elettronica con memorizzazione del codice anche senza alimentazione
tastiera :
3 colonne facenti capo a:                        7 8 9
piedino 2 per la colonna con n. 1                4 5 6
piedino 3 per la colonna con n. 2                1 2 3
piedino 4 per la colonna con n. 3                R 0 #
piedino A2 per la riga con il 7
piedino A1 per la riga con il 4
piedino A0 per la riga con il 1
piedino A3 per la riga con il R

reset codici al codice di partenza --> 25122000 (Natale 2000)
tramite tasto collegato a A4

Piedino 5-11 da collegarsi ad un display 7 segmenti opzionale

piedino 13 led di verifica operazioni collegato ad un led alta efficienza

comando per azionamento rele' sul piedino 12 con definizione di temporele come tempo di attuazione rele in millisec

FUNZIONAMENTO:
Il led si accende con un lampeggio ogni 6 secondi circa.
digitare il codice giusto e attendere 2 sec per apertura (sicurezza di codice corretto e conosciuto)
il LED lampeggia 3 volte.
dopo circa 10 sec di inattività si resettano le operazioni intraprese.
CAMBIO PASSWORD: premere # per 3 sec il LED si accende fisso per 2 sec ALLA FINE del lampeggio ed entro 10 sec
digitare il codice CORRENTE. Se è giusto si attiva la chiave (come aver digitato codice per apertura) e il LED inizia a
lampeggiare velocemente per 3 sec. Attendere la fine del lampeggio ed inserire il nuovo codice.
Confermare tenendo premuto per 3 sec (fino a che la luce non diventa fissa) il tasto #
il codice resta memorizzato.
RESET codice: tenendo premuto il trasto reset per almeno 3 secondi inizierà sul display un conto alla rovescia che azzera il
codice e lo riporta al valore iniziale 25122000.
*/

#include <EEPROM.h> 

// variabili di collegamento dei fili a piedini di arduino
// segmentoA-G = segmenti del display display
// Tastiera 3 colonne e 4 righe (vedi tastiera computer e non telefono)
// riga del 7, 4, 1, e ultima in basso tasto R o (*)
// colonna del 1, 2, 3

#define temporele 2000
#define segmentoA 5
#define segmentoB 6
#define segmentoC 7
#define segmentoD 8
#define segmentoE 9
#define segmentoF 11
#define segmentoG 10

int col1=2;
int col2=3;
int col3=4;
int riga7=A2;
int riga4=A1;
int riga1=A0;
int rigaR=A3;
int led=13;
int relay=12;
int tastoreset=A4;
// contatori al posto della funzione mills
long conta=0;
long tresec=0;
long tresec1=0;
long lampo=0;
long sicura=0;
int chiave[20];    // chiave
int accumulo[20];  // tentativo chiave
int nuova[20];     // nuova chiave
int pnu=0;  // puntatore lunghezza chiave nuova
int punt=0; // puntatore del tentativo chiave
int pch=0;  // puntatore lunghezza chiave
boolean bingo=LOW;
// boolean vai=HIGH;
int prog=0; // variabile che definisce stato di programmazione 0=normale 1=richiesta cambio password
int told=99; // variabile per vedere se il tasto premuto è lo stesso

// the setup routine runs once when you press reset:
void setup() {                
  // initialize the digital pin as an output.
  pinMode(segmentoA, OUTPUT);     
  pinMode(segmentoB, OUTPUT);     
  pinMode(segmentoC, OUTPUT);     
  pinMode(segmentoD, OUTPUT);     
  pinMode(segmentoE, OUTPUT);     
  pinMode(segmentoF, OUTPUT);     
  pinMode(segmentoG, OUTPUT);     
  pinMode(col1, OUTPUT);     
  pinMode(col2, OUTPUT);     
  pinMode(col3, OUTPUT);     
  pinMode(riga7, INPUT);     
  pinMode(riga4, INPUT);     
  pinMode(riga1, INPUT);     
  pinMode(rigaR, INPUT);
  pinMode(led,OUTPUT);
  pinMode(relay,OUTPUT);
  digitalWrite(relay,LOW);
  pinMode(tastoreset,INPUT);
  //pinMode(led1,OUTPUT);
  digitalWrite(led,LOW);
  //digitalWrite(led1,LOW);
  delay(1000);  
  ntoBCD(99);
  // settaggio della chiave invece che leggere da eeprom
  pch=EEPROM.read(0);
  // mai programmata inserisco la mia data di nascita come codice iniziale in eeprom
  if (pch<50) { // massimo numero di caratteri = 50
    for (int p=0; p<pch+1; p++) { // leggo la chiave
       chiave[p]=EEPROM.read(p+1);
    }
  }
  else { // mai scritta EEPROM --> valore FF
     azzera_ee(); //azzera chiave
  }
}


void loop() {
 // alla lettura della tastiera se premuto un tasto
 int t=99;
 t=tastiera();
 conta++;
 lampo++;
 //-------------------------------------------------------------- watch dogs
 if (conta>200000){ // watch dogs --> reset per inutilizzo
   conta=0;
   punt=0;
   pnu=0;
   prog=0;
   tresec=0;
   digitalWrite(led,LOW);
 }
 // ------------------------------------------------------------- sempre lo stesso tasto premuto? 
  if (t==99 && told!=t) { //    appena rilasciato il tasto
   told=99;    // riporto il vecchio valore a 99
   tresec=0;
   tresec1=0;
   conta=0;
   lampo=0;
  }
 
//--------------------------------------------------------------- LAMPEGGIO LED IN STAND BY
 if (lampo>60500){    // azzeramento lampeggio
    digitalWrite(led,LOW);
    lampo=0;    
 }
 if (lampo==60000){ // LAMPEGGIO LED di presenza
    digitalWrite(led,HIGH);
 }
// -------------------------------------------------------------- ATTIVAZIONE CHIAVE 
 if (bingo && sicura<12000){ // CHIAVE CONFERMATA attesa fine sequenza 2 sec.
    sicura++;
 }
 if (bingo && sicura>=12000){ // CHIAVE CONFERMATA Fine attesa --> attiva attuatore.
    bingo=LOW;
    punt=0;
    sicura=0;
    ntoBCD(10); // attivazione sul display simbolo apertura (H)
    // lampeggio di avvertimento
    for (int i=0;i<4;i++) {
       digitalWrite(led,HIGH);
       delay(60);
       digitalWrite(led,LOW);
       delay(60);
    }
    // Attivazione relay
    digitalWrite(relay,HIGH);
    delay(temporele);
    digitalWrite(relay,LOW);
    ntoBCD(99); // azzero display
    
    // chiave confermata dopo richiesta di cambio password
    if (prog==1) {
       prog=2; //attivazione fase programmazione successiva
       for (int i=0;i<6;i++){
        digitalWrite(led,HIGH);
        delay(60);
        digitalWrite(led,LOW);
        delay(60); 
       }
    }
 }
//--------------------------------------------------------------- RILEVAMENTO TASTI 
 if (t<10 && told!=t){ // E' stato premuto un tasto
   // acquisisco numero digitato
   told=t;
   tresec1=0;
   accumulo[punt]=t;
   if (prog>1) { // creo nuova password fase di programmazione
      nuova[pnu]=t;
      pnu++;
   }
   // verifico se la sequenza è corretta
   for (int i=0; i<=punt; i++){        // per tutti i caratteri accumulati
       if (chiave[i]!=accumulo[i]){    // se non corrispondono i caratteri -> reset puntatori
         bingo=LOW;
         sicura=0;
         punt=0;
         accumulo[0]=55; // azzero primo carattere dell'array per verifica if sotto
       }     
   }
   if (pch == punt) {
      // CHIAVE CONFERMATA CORRETTA
      bingo=HIGH;
      sicura=0;
    }

   if (chiave[punt]==accumulo[punt] && punt!=pch) punt++; // n corrispondenti aumento puntatore se sequenza non completa
 }

// ---------------------------------------------------------- TASTO RESET PREMUTO
 if (t==20){ //Tasto R reset
   tresec1++;
   conta=0;
   if (tresec1>32000) { // partenza reset password
     tresec1=0;
     for (int i=9;i>-1;i--){
       ntoBCD(i);
        digitalWrite(led,LOW);
        delay(100);
        digitalWrite(led,HIGH);
        delay(500);
     }
     ntoBCD(99);
     // reset password a iniziale
     azzera_ee(); //azzera chiave
     prog=0;
     pnu=0;  

   }
  }


// ---------------------------------------------------------- TASTO #
 if (t==12){ //Tasto # verificare se tenuto premuto per 3 secondi
    tresec++;
    if (tresec>25000){ // valore per cui si valida la pressione del tasto
       tresec=0;
       // -----------------------------------------------------
       if (prog==0) prog=1; // prima fase del programma richiesta cambio password
       // -----------------------------------------------------
       if (prog==2){ // conferma pasasword
         pnu--; // il contatore si è incrementato dopo l'ultimo numero ora è giusto
         // qui scrivere il puntatore su EEPROM ************************************************************
         EEPROM.write(0,pnu); // puntatore
         for (int i=0; i<pnu+1; i++) { // nuovo array formato e pronto travaso su chiave
            chiave[i]=nuova[i];
            // qui scrivere la EEPROM **********************************************************************
            EEPROM.write(i+1,chiave[i]); // scrivi su EEPROM
         }
         pch=pnu;
         prog=0;
         pnu=0;  
       }
       // ----------------------------------------------------
       ntoBCD(11);
       digitalWrite(led,HIGH);
       delay(2000);
       ntoBCD(99);
       digitalWrite(led,LOW);
   }

 }
}

// FUNZIONI
//----------------------------------------------------------------------------------
// Funzione che attiva il display
void ntoBCD(int x) {
  switch (x) {
    case 0:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,HIGH);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,LOW);
          break;
       case 1:
          digitalWrite(segmentoA,LOW);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,LOW);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,LOW);
          digitalWrite(segmentoG,LOW);
          break;
       case 2:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,LOW);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,HIGH);
          digitalWrite(segmentoF,LOW);
          digitalWrite(segmentoG,HIGH);
          break;
       case 3:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,LOW);
          digitalWrite(segmentoG,HIGH);
          break;
       case 4:
          digitalWrite(segmentoA,LOW);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,LOW);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,HIGH);
          break;
       case 5:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,LOW);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,HIGH);
          break;
       case 6:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,LOW);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,HIGH);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,HIGH);
          break;
       case 7:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,LOW);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,LOW);
          digitalWrite(segmentoG,LOW);
          break;
       case 8:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,HIGH);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,HIGH);
          break;
       case 9:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,HIGH);
          break;
       case 10:
          digitalWrite(segmentoA,LOW);
          digitalWrite(segmentoB,HIGH);
          digitalWrite(segmentoC,HIGH);
          digitalWrite(segmentoD,LOW);
          digitalWrite(segmentoE,HIGH);
          digitalWrite(segmentoF,HIGH);
          digitalWrite(segmentoG,HIGH);
          break;
       case 11:
          digitalWrite(segmentoA,HIGH);
          digitalWrite(segmentoB,LOW);
          digitalWrite(segmentoC,LOW);
          digitalWrite(segmentoD,HIGH);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,LOW);
          digitalWrite(segmentoG,HIGH);
          break;
       default:
          digitalWrite(segmentoA,LOW);
          digitalWrite(segmentoB,LOW);
          digitalWrite(segmentoC,LOW);
          digitalWrite(segmentoD,LOW);
          digitalWrite(segmentoE,LOW);
          digitalWrite(segmentoF,LOW);
          digitalWrite(segmentoG,LOW);
  }
  conta=0;
}

//----------------------------------------------------------------------------------
// Funzione che legge la tastiera - restituisce valore tasto
// 10 x R - 11 x #
int tastiera(){
  int tasto=99;
  digitalWrite(col1,HIGH);  
  if (digitalRead(riga7)) {tasto=7; goto finito;}  // tasto 7
  if (digitalRead(riga4)) {tasto=4; goto finito;}  // tasto 4
  if (digitalRead(riga1)) {tasto=1; goto finito;}  // tasto 1
  if (digitalRead(rigaR)) {tasto=11; goto finito;} // tasto R o *
  digitalWrite(col1,LOW);
  digitalWrite(col2,HIGH);
  if (digitalRead(riga7)) {tasto=8; goto finito;}  // tasto 8
  if (digitalRead(riga4)) {tasto=5; goto finito;}  // tasto 5
  if (digitalRead(riga1)) {tasto=2; goto finito;}  // tasto 2
  if (digitalRead(rigaR)) {tasto=0; goto finito;}  // tasto 0
  digitalWrite(col2,LOW);
  digitalWrite(col3,HIGH);
  if (digitalRead(riga7)) {tasto=9; goto finito;}  // tasto 9
  if (digitalRead(riga4)) {tasto=6; goto finito;}  // tasto 6
  if (digitalRead(riga1)) {tasto=3; goto finito;}  // tasto 3
  if (digitalRead(rigaR)) tasto=12;                // tasto #
  finito:
  digitalWrite(col1,LOW);
  digitalWrite(col2,LOW);
  digitalWrite(col3,LOW);
  if (digitalRead(tastoreset)==LOW) {tasto=20;}
  if (tasto<10){ // evita i rimbalzo del doppio numero e segnala tasto premuto
    digitalWrite(led,HIGH);
    ntoBCD(tasto);      // visualizzo numero digitato
    delay(120);
    digitalWrite(led,LOW);  
    ntoBCD(99);        // azzero display
  }
  return tasto;
}

// -----------------------------------------------------------------------------------
// Funzione scrittura EEPROM - Valore iniziale 25122000
void azzera_ee(){
     EEPROM.write(0,7); // puntatore
     EEPROM.write(1,2);
     EEPROM.write(2,5);
     EEPROM.write(3,1);
     EEPROM.write(4,2);
     EEPROM.write(5,2);
     EEPROM.write(6,0);
     EEPROM.write(7,0);
     EEPROM.write(8,0);
     pch=7; // lunghezza della chiave in caratteri -1 (parte da 0)
     chiave[0]=2;
     chiave[1]=5;
     chiave[2]=1;
     chiave[3]=2;
     chiave[4]=2;
     chiave[5]=0;
     chiave[6]=0;
     chiave[7]=0;
}
//-------------------------------------------------------------------------------------

 

Pubblicato da Roberto Contessi

Un tempo c'erano le valvole e i transistor e tanta più pazienza. Si aspettava la Fiera per trovare il pezzo che mancava e si comunicava via radio (IW3ENI). Ora ci sono i processori, internet e i PC. Cambiano i mezzi. La creatività è il desiderio di costruire rimangono. lavocediroberto@gmail.com

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *