Lezione 8: Utilizziamo il KeyPad con Arduino

Lezione 8: Utilizziamo il KeyPad con Arduino

In questa ottava puntata su Arduino, introdurremo un nuovo strumento, utile per tanti diversi progetti: il KeyPad.

P0006463_new_com4

Il meccanismo di funzionamento è davvero semplice. Esso è formato da 7 cavi, che rappresentano 4 righe e 3 colonne. Attraverso la pressione di un tasto, c’è una variazione di tensione sul Pin collegato ad Arduino e quest’ultimo è in grado di rilevare il relativo valore.

Attraverso questo device è davvero possibile fare tantissimi progetti, come ad esempio una simulazione di un piccolo Bancomat, proteggere una porta d’entrata e tanto altro. Vediamo qualche esempio per Arduino.

Esempi di programmazione del KeyPad

Requisiti Hardware:

  • Arduino d8023dded193db365b86e925197efd2e.image.240x240
  • KeyPadP0006463_new_com4
  • LED Schermata 2013-05-24 alle 09.40.56
  • Relay 0-96d41f35-800
  • Servo servo

Requisiti Software:

1° Programma: Hello KeyPad

In questo piccolo programma, vedremo come mostrare su seriale il tasto premuto sul KeyPad

/* @file HelloKeypad.pde
|| @version 1.0
|| @author Alexander Brevig
|| @contact [email protected]
||
|| @description
|| | Demonstrates the simplest use of the matrix Keypad library.
|| #
*/
#include <Keypad.h>

const byte ROWS = 4; //four rows
const byte COLS = 3; //three columns
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {8,7,6,5}; //connect to the row pinouts of the keypad
byte colPins[COLS] = {4,3,2}; //connect to the column pinouts of the keypad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
}

void loop(){
  char key = keypad.getKey();

  if (key){
    Serial.println(key);
  }
}

Il funzionamento del programma dal punto di vista hardware è già stato spiegato precedentemente. Dal punto di vista software, la situazione è davvero semplice. Sfruttando le librerie già presenti sul sito di Arduino, il loop() è davvero immediato da capire: una volta che viene premuto qualcosa, si entra in if, che stampa sul seriale il relativo valore, semplice no ? Il collegamento del KeyPad con Arduino è semplice, basta guardare la seguente foto.

Foto 30-11-13 16 04 57

In pratica, prendendo il KeyPad dal lato frontale, basta collegare i cavi in modo parallelo, partendo dal Pin 8 fino al Pin 2.

Ecco il video che mostra il KeyPad in azione con Arduino:

 2° Programma: KeyPad che permette di proteggere qualcosa

Questo secondo programma può essere modificato dall’utente. In pratica, questo codice, non fa altro che permette di inserire un codice con il KeyPad, verificarlo tramite Arduino e se tale codice è corretto, accende un LED. In realtà è possibile fare qualsiasi cosa, come ad esempio accendere una lampada, aprire una porta con un servo. Lascio questo codice, in modo che chiunque possa implementarlo a suo piacimento.

/**
Questo programma permette di far inserire da un utente un codice con il KeyPad. Qualora il codice inserito sia corretto, viene accesso un LED.
Per inviare il codice, una volta digitato interamente è necessario premere *. Mentre per spegnere il LED, oppure re-digitare il codice è necessario premere #
Autore Giacomo Bellazzi
Versione 1.0
*/
#include <Keypad.h>
#define LED 13
const byte ROWS = 4; //quattro righe
const byte COLS = 3; //tre colonne
char keyInsert[6];
// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;
// Codice segreto
char code[7]= "112233";
char keys[ROWS][COLS] = {
  {'1','2','3'},
  {'4','5','6'},
  {'7','8','9'},
  {'*','0','#'}
};
byte rowPins[ROWS] = {8,7,6,5}; //i Pin a cui sono connesse le righe del KeyPad
byte colPins[COLS] = {4,3,2}; // i Pin a cui sono connesse le colonne del KeyPad

Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );

void setup(){
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
}

void loop(){
  char key = keypad.getKey();
  if (i==0){
    Serial.println("Insert PIN to verify...");
    i++;
  }
  if (key != NO_KEY && j<6){
    Serial.print("*");
    //Serial.println(key);
    keyInsert[j]=key;
    j++;
  }
   if(key == '*') {
      Serial.println();
      Serial.println("Verifyng the code...");
      delay(1000);
      for(s=0; s<6;s++){
        if(keyInsert[s]==code[s]){
          x++;
      }
    } 
      if(x==6){
      Serial.println("The code is correct"); 
      digitalWrite(LED,HIGH); 
      //TODO possibili ulteriori implementazioni
      }else{
         Serial.println("The code is incorrect, please retry");
         delay(2000);
         x=0;
         i=0;
         j=0;
       }

      }  
    if(key == '#'){
        x=0;
        i=0;
        j=0;
        digitalWrite(LED,LOW); 
    }    
}

Il codice risultato essere leggermente un po’ più complesso del primo, tuttavia attraverso i commenti presenti è facile intuire il meccanismo di funzionamento dei vari blocchi di codice. In pratica vengono letti i valori inseriti attraverso il KeyPad. Una volta terminata l’immissione dei 6 caratteri, si preme il comando * e Arduino valuta se il codice inserito è lo stesso di quello presente in memoria. Questo avviene attraverso un ciclo for e un if che verificano se i 6 valori  sono uguali.

Ecco il video che mostra il funzionamento del programma :

 

3°Programma: Utilizziamo il OTP e il KeyPad

Questo programma è stato realizzato da Luca Dentella, un appassionato di Arduino. Questo programma si basa sull’utilizzo del metodo di sicurezza OTP, che viene usato da chi ha un Online Banking. Per chi non sapesse cosa sia l’OTP, ecco una definizione tratta da Wikiepdia:

Una One-Time Password (password usata una sola volta) è una password che è valida solo per una singola sessione di accesso o una transazione. La OTP evita una serie di carenze associate all’uso della tradizionale password (statica). Il più importante problema che viene risolto da OTP è che, al contrario della password statica, esso non è vulnerabile agli attacchi con replica. Ciò significa che, se un potenziale intruso riesce ad intercettare una OTP che è stata già utilizzata per accedere a un servizio o eseguire una transazione, non sarà in grado di riutilizzarla, in quanto non sarà più valida. D’altra parte, una OTP non può essere memorizzata da una persona. Essa richiede quindi una tecnologia supplementare per poter essere utilizzata.[1]

Come vengono generate le password OTP ?

Gli algoritmi di generazione delle OTP in genere fanno uso di numeri casuali. Ciò è necessario perché altrimenti sarebbe facile prevedere l’OTP futuro osservando i precedenti. Gli algoritmi OTP che sono stati realizzati sono abbastanza diversi tra loro. I vari approcci per la generazione di OTP sono elencati di seguito.

  • Algoritmi basati sulla sincronizzazione temporale tra server di autenticazione e client che fornisce la password (le OTP sono valide solo per un breve periodo di tempo)
  • Algoritmi matematici che generano una nuova password in base alla password precedente (le OTP sono, di fatto, una catena di password legate tra loro, e devono essere utilizzate in un ordine predefinito)
  • Algoritmi matematici dove la password è basata su una sfida (per esempio, un numero casuale scelto dal server di autenticazione o dai dettagli della transazione) e/o su un contatore.

Ci sono anche diversi modi per rendere note all’utente le successive OTP da usare. Alcuni sistemi elettronici prevedono l’uso di speciali token che l’utente porta con sé, che generano le OTP e le mostrano utilizzando un piccolo display. Altri sistemi sono costituiti da un software che gira sul telefono cellulare dell’utente. Altri sistemi generano le OTP sul lato server e le trasmettono all’utente su un canale fuori banda, come ad esempio un canale di messaggistica SMS. Infine, in alcuni sistemi le OTP sono stampate su carta, che l’utente è tenuto a portare con sé.

In pratica l’OTP si basa su un calcolo di codice, che è formato da una password one time e da un algoritmo che proviene dall’attuale ora.

Per il calcolo del codice, viene incontro una semplice applicazione di Google. Per il download della parte di Arduino, trovato tutto il materiale sul post dell’autore del codice http://www.lucadentella.it/2013/09/14/serratura-otp/2/.

Per prima cosa, è necessario inserire hmackey all’interno del codice di Arduino; questo valore di ricava inserendo la password di default, all’interno di questo script, realizzato sempre da Luca Dentella http://www.lucadentella.it/OTP

otp_tool

 

Una volta copiato il codice nello Sketch per Arduino, basterà compilare e per quanto riguarda la parte legata ad Arduino, abbiamo finito. Ora è necessario installare il programma per il calcolo del codice OTP sul nostro Smartphone: Google Authenticator.

Ora che abbiamo installato il programma lo apriamo e attraverso la fotocamera, puntiamo lo smartphone sul codice QR che è stato generato in precedenza. Ora abbiamo finito e possiamo testare il programma, attraverso il seriale con Arduino.

Ecco un video che mostra l’utilizzo del programma:

 

KeyPad 4×4

F0HFBBFHFWSTA72.LARGE

Sul web è possibile trovare una versione del KeyPad con 16 caratteri, cioè con i numeri dallo zero al nove e le lettere AB,C,D. Il meccanismo di funzionamento è lo stesso, il codice varia leggermente. Ecco due esempi come mostrano l’utilizzo del KeyPad nella sua versione “più grande”:

4° Programma con KeyPad 4×4: HelloKeyPad 4×4

/*Questo programma mostra come usare la tastiera KeyPad 4x4 con Arduino Uno.
Il testo che viene premuto sulla KeyPad viene mostrato nel seriale
*/
#include <Keypad.h>

const byte ROWS = 4; //quattro righe
const byte COLS = 4; //quattro colonne
byte colPins[4] = {5,4,3,2}; // Pin a cui sono connesse le colonne
byte rowPins[4] = {9,8,7,6}; // Pin a cui sono connesse le righe
char Keys[4][4]= //creo la matrice dei tasti della tastiera.
{
{'1','2','3','A'} ,
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
Keypad keyp = Keypad(makeKeymap(Keys), rowPins, colPins,4,4);

void setup(){
  Serial.begin(9600);
}

void loop(){
  char key = keyp.getKey();
  if (key){
    Serial.println(key);
  }
}

5°Programma con KeyPad 4×4: Codice Segreto con lettere

/**
Questo programma permette di far inserire da un utente un codice con il KeyPad. Qualora il codice inserito sia corretto, viene accesso un LED.
Per inviare il codice, una volta digitato interamente è necessario premere *. Mentre per spegnere il LED, oppure re-digitare il codice è necessario premere #
Autore Giacomo Bellazzi
Versione 1.0
*/
#include <Keypad.h>
#define LED 13
const byte ROWS = 4; //quattro righe
const byte COLS = 4; //quattro colonne
char keyInsert[6];
// Queste variabili servono come verifica del corretto inserimento del codice
int i = 0;
int j = 0;
int s = 0;
int x = 0;
// Codice segreto
char code[7]= "11ABCD";
char Keys[ROWS][COLS]= //creo la matrice dei tasti della tastiera.
{
{'1','2','3','A'} ,
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
byte colPins[4] = {5,4,3,2}; // Pin a cui sono connesse le colonne
byte rowPins[4] = {9,8,7,6}; // Pin a cui sono connesse le righe

Keypad keypad = Keypad( makeKeymap(Keys), rowPins, colPins, ROWS, COLS);

void setup(){
  Serial.begin(9600);
  pinMode(LED,OUTPUT);
}

void loop(){
  char key = keypad.getKey();
  if (i==0){
    Serial.println("Insert PIN to verify...");
    i++;
  }
  if (key != NO_KEY && j<6){
    Serial.print("*");
    //Serial.println(key);
    keyInsert[j]=key;
    j++;
  }
   if(key == '*') {
      Serial.println();
      Serial.println("Verifyng the code...");
      delay(1000);
      for(s=0; s<6;s++){
        if(keyInsert[s]==code[s]){
          x++;
      }
    } 
      if(x==6){
        Serial.println("The code is correct"); 
        digitalWrite(LED,HIGH); 
      //TODO possibili ulteriori implementazioni
      }else{
        Serial.println("The code is incorrect, please retry");
        delay(2000);
        x=0;
        i=0;
        j=0;
       }
      }  
    if(key == '#'){
        x=0;
        i=0;
        j=0;
        digitalWrite(LED,LOW); 
    }    
}

Conclusione

Spero che i programmi presentati in questo post, siano di facile lettura e sopratutto, siano possibili di ulteriori implementazioni.

 

ismanettoneblog

30 pensieri su “Lezione 8: Utilizziamo il KeyPad con Arduino

  1. salve io ho un problema con lo sketch, l’ho copiato e incollato ma mi da un errore qui

    Keypad keyp = Keypad(makeKeymap(Keys), rowPins, colPins,4,4);

    dice questo:

    ‘keypad’ does not name a type

    sa quale potrebbe essere il problema?

    1. Salve,
      questo problema è dovuto al fatto che non è presente nel suo PC la libreria per il Keypad #include . Per farlo bisognare scaricare dal sito ufficiale di Arduino tale libreria e copiarla all’interno della cartella Library dell’Arduino IDE

  2. Salve, volevo chiedere, e se al programma 2 vogliamo mettere piu codici e collegare arduino ad una scheda relè e ogni codice fa accendere un led della scheda relè?

    1. Salve,
      se non ho capito bene, la richiesta sarebbe di utilizzare un KeyPad per inserire vari codici, e per ciascuno di essi è associato un LED, giusto ?
      Per esempio:
      Codice – LED
      1234 – 1
      1468 – 2
      1357 – 3

      È corretto ?

      1. Ciao, innanzitutto complimenti per gli ottimi sketch
        ( assolutamente funzionanti e perfettamente commentati),
        non sono lo stesso Roberto, ma stavo propio cercando
        una soluzione al quesito che ha chiesto il mio omonimo e che Tu hai correttamente capito. Puoi aiutarmi ?

        1. Ciao,
          ci sono diversi soluzioni per poter realizzare la verifica di più codici nello stesso sketch. Il primo è quella di crearsi un metodo che verifica se un char code[] è valido, e inserire all’interno del loop tante chiamate alla funzione, quante sono i codici possibili (presta attenzione alla variabile x, che deve essere azzerata quando passi al codice successivo). L’altro metodo è un po’ più complicato, in quanto richiederebbe la creazione di libreria C++, per poter gestire oggetti. Ti consiglio di provare con la prima soluzione.

          1. Buon giorno
            Sono un principiante di programmazione ma molto appassionato di elettronica.
            Anch’io ho lo stesso problema di inserire più codici segreti all’interno dello sketch ma non ho capito la tua soluzione potresti come modificare lo sketch
            Grazie Gianni Gallo

  3. Con questo mi hai “salvato”:

    (presta attenzione alla variabile x, che deve essere azzerata quando passi al codice successivo)

    Grazie 🙂

    1. Ormai a furia di programmare, conosco bene tutti i possibili trabocchetti che ci sono quando qualcosa non va !

  4. ciao…ascolta ho un problema…quando faccio insert key lui mi inserisce già un asterisco e non mi fa andare niente…sai come si può ovviare al problema?
    complimenti comunque

  5. Buon giorno
    avrei un quesito da porre per un mio progettino.
    Utilizzando la libreria keypad posso inserire la funzione char key=keypadgetkey all’interno della funzione keypadevent?
    TKS Gianni Gallo

      1. Un ringraziamento per la tua disponibilità
        Ti faccio una breve descrizione.
        Sono impegnato in un progetto di contametri con l’utilizzo di un Arduino mega, con funzione di master, due arduino nano con funzioni di slave
        Ad ogni singolo slave solo collegati tre sensori hall che tengono il conteggio dei giri delle rispettive carrucole.
        Su richiesta del Master lo slave fornisce il dato relativo al contatore selezionato, inoltre il Master può inviare un impulso di reset del singolo contatore ed infine potrà impostare un valore di soglia da memorizzare nella eeprom dello slave al raggiungimento del quale si attiva un avviso luminoso.
        Poichè le funzioni sono in sintesi tre
        1) richiesta dato contatore
        2) Invio comando reset
        3) impostazione valore di soglia
        Ho pensato di utilizzare la funzione Keypad event presente nella libreria Keypad
        con la seguente logica:
        Alla selezione del tasto”C” invio richiesta dati contatore e visualizzazione sul display
        Alla selezione del tasto “A” invio di un comando che permette di azzerare il contatore
        Alla selezione del tasto “B” dovrei poter inserire tramite keypad un valore intero da poter memorizzare nella eeprom dello slave-

        Sinora sono riuscito a stabilire la comunicazione I2C tra Master e slave, a selezionare ogni singolo sensore ed ottenere il valore del contatore e visualizzarlo su un display
        Sono riuscito ad inviare un comando di reset hai singoli contatori.
        Ma quando seleziono il tasto “B” ho la sensazione che la funzione keypadgetkey non abbia effetto.
        E’ possibile che tale funzione non funzioni quando sono dentro la funzione keypadevent?

        Se vuoi posso postarti il codice

        Un grazie anticipato per ogni contributo
        Gianni Gallo

        1. Salve,
          dovrei aver capito il progetto e il problema, però se mi mandi via email il codice posso capire meglio la situazione.

  6. ciao
    un domanda facile facile….quanto può essere lontana la keypad da arduino? vorrei usare due keypad per inserire dei dati (tipo imposta temp) in luoghi relativamente lontani da micro. tipo micro in caldaia. key1 piano terra key2 piano primo

    grazie

    andrea

    1. Tipicamente i fili che si usano per collegare i sensori ad Arduino non sono più di lunghi di qualche metro. In questo caso, visto che si parla di distanze maggiori, ti consiglio di usare dei sensori wireless, come ad esempio quelli che viaggiano sui 433 MHz, che hanno una discreta copertura. Prossimamente farò qualche guida su Photon, un nuovo micro-controllore dalle grandi possibilità. Una di queste guide riguarderà un progetto simile.

      1. avevo valutato anch’io una soluzione del genere, ma l’ho scartata per i costi, ad oggi ho due tastiere e una decina di sensori, se metto a tutti dei dispositivi wireless mi costa un botto…un’alternativa potrebbe essere RS485 ed un micro economico che faccia solo da gestore per un ingresso e un’uscita, o che legga la tastiera e gestisca un LCD per visualizzare la tastiera. che ne pensi?

        andrea

        1. Si possono realizzare dei micro-controllori con 5 euro, che comunicano Wireless sulla frequenza 433 MHz con un Arduino base. Tali dispositivi hanno attiny85 e il kit rx/tx 433 MHz. Qualora avessi altri dubbi, rimango a tua disposizione.

  7. Salve, vorrei chiedere se fosse possibile utilizzare un pin di lunghezza minore con la tastiera 4×4.
    Poi vorrei utilizzarla per far muovere un servomotore e aprire una sbarra, posso utilizzare lo sketch del progetto “KeyPad che permette di proteggere qualcosa”?
    Grazie in anticipo per le risposte.

    1. Salve,
      si è possibile cambiare il codice con uno di lunghezza minore. Per quanto riguarda il controllo di un serve motore, non c’è problema.

  8. Salve.
    Vorrei chiedere se è possibile, nel programma numero 2, definire 2 tastiere. Una da utilizzare per l’inserimento del codice segreto, l’altra da utilizzare in un secondo momento. E s’è possibile, come faccio a definire un Keypad keypad = Keypad( makeKeymap… per la seconda tastiera, senza andare in contrasto con il Keypad keypad = Keypad( makeKeymap… della prima tastiera?
    Grazie

    1. Salve,
      tecnicamente basterebbe crearsi un altro oggetto di tipo KeyPad è assegnare i vari pin. Tuttavia, con un Arduino uno non ci sono tanti pin per gestire due tastiere. Tuttavia si potrebbe ri-utilizzare la medesima, una volta per inserire il codice segreto e un’altra volta per inserire dei valori.

  9. Salve ISMANETTONEBLOG ,innanzitutto ti faccio i miei complimenti, perchè i tuoi progetti mi sono sati molto d’aiuto!Volevo chiederti io ho un problema; Allora ho realizzato un sistema d’allarme con un keypad, sensore pir e display Lcd I2C. Fin qui tutto bene, funziona perfettamente, inserisco il codice , se è corretto ,mi attiva l’allarme oppure se non è corretto mi dice che è sbagliato e mi fa inserire di nuovo il codice , l’unico problema è che non so come fare a disattivare l’allarme quando il sensore pir rileva un movimento, ovvero voglio attivare e disattivare l’allarme in qualsiasi momento.Spero mi possa aiutare.Grazie…

    1. Salve,
      grazie per i complimenti. Diciamo che ci sono diversi soluzioni, tutte però basate su un valore booleano, che stabilisce se l’allarme è attivo o no. Una prima soluzione, è quello di inserire un codice diverso da quello di autorizzazione, che una volta inserito, fa cambiare lo stato dell’allarme. L’altra soluzione è quella di collegare ad Internet l’Arduino, un po’ come faccio in un altro progetto. C’è da ricordare che nel caso dovesse andare via la corrente ad Arduino, viene caricato il valore di default se non si salva tale dato in una memoria non volatile.

  10. Salve,
    innanzitutto complimenti perchè solo qui ho trovato una descrizione chiara ed un programma funzionante, quindi a nome di tutti grazie. Io però avrei un problema e spero davvero che possiate aiutarmi. Partendo dal programma numero 5, vorrei fare 4 modifiche:
    -inserire uno schermo a cristalli liquidi dove far apparire tutti i vari comandi;
    -inserire un timer programmabile dal keypad, al termine del quale si attiva un relè;
    -fare in modo che se il codice viene inserito errato per due volte consecutive, si attiva comunque il su detto relè;
    -poter impostare il codice di sicurezza direttamente dal keypad.
    mi sembrano modifiche abbastanza semplici concettualmente, ma nel programma non so davvero dove mettere le mani, mi potreste aiutare. Vi sarei immensamente riconoscente. Grazie mille in anticipo.

    1. Salve,
      sono contento che il mio articolo sia stato interessante. Le modifiche da fare, non sono proprio semplicissime, nel senso che bisogna avere una buona conoscenza del linguaggio di programmazione di Arduino. Per il collegamento con un display LCD, ci sono diversi riferimenti sul sito ufficiale di Arduino. Per quanto riguarda il discorso timer, c’è una libreria che permette di stabilire quando passano tot. secondi ed effettuare un’operazione (link).
      Per quanto riguarda il discorso tentativi, si può utilizzare una variabile intera, che contata quante volte è stato sbagliato il codice e si azzera quando è corretto.
      Inserire il codice di sicurezza da Keypad non è di per se un problema, l’unica cosa è dove salvare tale valore. Le variabili utilizzate dallo sketch sono salvate sulla memoria volatile del micro (come una ram) e quindi al riavvio del dispositivo le informazioni sono perse. È possibile usare una micro-SD esterna, oppure la EPROM, che però ha un numero limitato di scritture.

      Rimango a disposizione per ulteriori chiarimenti.

I commenti sono chiusi.