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)
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; } //-------------------------------------------------------------------------------------