3° esempio SERVO MOTORE + KEYPAD
Per sviluppare questo progetto occorre costruire il circuito (serve un servo motore e tastierino numerico a membrana) visualizzato nella seguente immagine:
Per svolgere questo esempio occorre scaricare la libreria: keypad.zip. Per installarla occorre caricare il file zippato tramite il menu "Add Library", presente all'interno dell'IDE di Arduino, come mostrato nella figura sottostante.
Al termine dell'importazione i files contenuti in keypad.zip vengono ricopiati nella cartella C:\Users\<User>\Documents\Arduino\libraries. Se ci sono problemi nell'installazione occorre svuotare la cartella di libreria appena creata (Keypad) e ripetere l'operazione.
I pin del Keypad vanno connessi seguendo lo schema riportato:
Codice Sorgente
Obiettivo progetto: Costruire un programma che interpreti la sequenza numerica digitata sul Keypad come se fosse l'angolo dove posizionare il braccio del servo motore. Associare al tasto # il significato di "reset" ovvero riporta il braccio del servo ad una posizione di "riposo" (supponiamo corrisponda all'angolo zero) mentre al tasto * il significato di "invio" della sequenza numerica digitata.
soluzione:
Analizziamo come possiamo interpretare l'input che ci arriva dal keypad. Partiamo dall'istruzione di lettura
char key =keypad.getKey();
Questo implica che i dati letti dal keypad vengano intesi come caratteri e non come numeri. In altre parole se premo il tasto uno verrà acquisito il simbolo '1' e non il valore numerico 1. E' necessario quindi creare quindi un meccanismo che a fronte di una sequenza di simboli '1' '6' '3' realizzi la decodifica nel valore numerico corrispondente 163 e lo salvi in un'opportuna variabile (angolo ad esempio).
Ricordo che per il computer il simbolo '7' è un carattere (un codice ascii) privo di qualsiasi significato numerico. Nella tabella ascii (che rappresenta il modo in cui i simboli vengono "registrati" nel computer) viene messo in evidenza il codice binario a 8 bit associato ad ogni glifo. Ad ogni sequenza binaria di 8 bit è associato in modo univoco un numero in base 10, evidenziato nella tabella sottostante.
Pertanto per estrarre il valore numerico corrispondente ad un simbolo numerico occorre effettuare un'operazione di questo tipo:
valoreInteroCorrispondente='7'-'0';
Infatti il C vedendo nell'espressione l'operatore numerico meno interpreta i simboli come numeri e li decodifica nella corrispondente rappresentazione binaria e quindi nel corrispondente valore numerico in base 10
valoreInteroCorrispondente=55-48;
che restituisce come risultato 7 che effettivamente corrisponde all'interpretazione numerica del simbolo '7'. Se gli angoli fossero rappresentati da una sola cifra, per decodificare il simbolo premuto sul keypad in una variabile numerica mi basta utilizzare questa istruzione:
Angolo=key-'0';
Le cifre però sono più di una (abbiamo supposto che la sequenza relativa al nostro angolo sia terminata dalla pressione del tasto *!) e pertanto dobbiamo ricorrere a questa tecnica.
Creiamo una variabile globale angolo e inizializziamola a zero:
Angolo=0;
Supponiamo ora di premere come primo tasto del keypad il simbolo '1'. L'istruzione seguente
Angolo=Angolo*10+key-'0';
valorizza inizialmente la variabile angolo a 1 (angolo valeva 0 per cui la moltiplica per 10 non ha alcun effetto!). Supponiamo ora di premere come secondo tasto il simbolo '6'. L'istruzione vista in precedenza
Angolo=Angolo*10+key-'0';
valorizza ora la variabile angolo a 16 (angolo valeva 1 per cui la moltiplica per 10 ha come effetto l'aggiunta di 10 al valore numerico associato al secondo tasto). Supponiamo ora di premere come terzo tasto il simbolo '3'. L'istruzione vista in precedenza
Angolo=Angolo*10+key-'0';
valorizza infine la variabile angolo a 163 (angolo valeva 16 per cui la moltiplica per 10 ha come effetto l'aggiunta di 160 al valore numerico associato al terzo tasto). Il valore contenuto in angolo quindi è la decodifica numerica della sequenza di simboli '1' '6' '3'.
Questa istruzione, messa nel loop(), è quindi capace di decodificare la sequenza dei simboli premuti sul keypad nel corrispondente valore numerico che potrà poi essere usato per impostare la posizione del braccio del servo motore.
Il seguente sketch, che utilizza le classi definite in <Servo.h> e in <Keypad.h>, rappresenta una delle possibili soluzioni al nostro progetto
/* ----------------------------------------------------------------------------------- Dimostra l'utilizzo della libreria KeyPad abbinato ad un servo motore ----------------------------------------------------------------------------------- */ #include <Keypad.h> #include <Servo.h> Servo myservo; // creo un oggetto di tipo Servo - posso crearne al massimo 8 const byte ROWS = 4; //4 righe const byte COLS = 3; //3 colonne char keys[ROWS][COLS] = { {'1','2','3'}, {'4','5','6'}, {'7','8','9'}, {'*','0','#'} }; byte rowPins[ROWS] = {8, 7, 6, 5}; // Pin di arduino connessi ai pin 1,2,3 e 4 delle righe del keypad byte colPins[COLS] = {4, 3, 2}; // Pin di arduino connessi ai pin 5,6,7 delle righe del keypad Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS ); int Angolo=0; void setup() { Serial.begin(9600); myservo.attach(13); // collego il attaches the servo on pin 9 to the servo object myservo.write(0); // posiziono il servo alla posizione iniziale } void loop() { char key = keypad.getKey(); if (key != NO_KEY) { if (key=='#') Angolo=0; else if (key=='*') { // Imposto l'angolo sul motore if ( (Angolo<180) && (Angolo>=0) ) { myservo.write(Angolo); // imposto l'angolo del servo tramite la variabile pos Serial.print("Angolo impostato: "); Serial.println(Angolo); } else { Serial.print("Angolo errato: "); Serial.println(Angolo); } Angolo=0; } else Angolo=Angolo*10+(key-'0'); } }
L'esecuzione del seguente codice produce il seguente output sul monitor seriale: