Nota

Ciao, benvenuto nella community di SunFounder Raspberry Pi & Arduino & ESP32 su Facebook! Approfondisci le tue conoscenze su Raspberry Pi, Arduino ed ESP32 insieme ad altri appassionati.

Perché unirti a noi?

  • Supporto Esperto: Risolvi i problemi post-vendita e le sfide tecniche con l’aiuto della nostra comunità e del nostro team.

  • Impara e Condividi: Scambia suggerimenti e tutorial per migliorare le tue competenze.

  • Anteprime Esclusive: Ottieni accesso anticipato ai nuovi annunci di prodotti e alle anteprime.

  • Sconti Speciali: Approfitta di sconti esclusivi sui nostri prodotti più recenti.

  • Promozioni Festive e Giveaway: Partecipa a concorsi e promozioni festive.

👉 Pronto a esplorare e creare con noi? Clicca su [Qui] e unisciti subito!

2.1.8 Tastiera

Introduzione

Una tastiera è una matrice rettangolare di pulsanti. In questo progetto, la utilizzeremo per inserire caratteri.

Componenti Necessari

In questo progetto, abbiamo bisogno dei seguenti componenti.

../_images/list_2.1.5_keypad.png

È sicuramente conveniente acquistare un kit completo, ecco il link:

Nome

COMPONENTI IN QUESTO KIT

LINK

Raphael Kit

337

Raphael Kit

Puoi anche acquistarli separatamente dai link seguenti.

INTRODUZIONE AI COMPONENTI

LINK PER L’ACQUISTO

Scheda di estensione GPIO

ACQUISTA

Breadboard

ACQUISTA

Cavi Jumper

ACQUISTA

Resistore

ACQUISTA

Tastierino

-

Schema Elettrico

../_images/image315.png ../_images/image316.png

Procedure Sperimentali

Passo 1: Costruisci il circuito.

../_images/image186.png

Passo 2: Apri il file del codice.

cd ~/raphael-kit/c/2.1.8/

Passo 3: Compila il codice.

gcc 2.1.8_Keypad.cpp -lwiringPi

Passo 4: Esegui.

sudo ./a.out

Dopo l’esecuzione del codice, i valori dei pulsanti premuti sulla tastiera (valore del pulsante) verranno visualizzati sullo schermo.

Nota

Se non funziona dopo l’esecuzione o appare un errore come: "wiringPi.h: No such file or directory", fai riferimento a Installa e Controlla wiringPi.

Codice

#include <wiringPi.h>
#include <stdio.h>

#define ROWS  4
#define COLS  4
#define BUTTON_NUM (ROWS * COLS)

unsigned char KEYS[BUTTON_NUM] {
'1','2','3','A',
'4','5','6','B',
'7','8','9','C',
'*','0','#','D'};

unsigned char rowPins[ROWS] = {1, 4, 5, 6};
unsigned char colPins[COLS] = {12, 3, 2, 0};

void keyRead(unsigned char* result);
bool keyCompare(unsigned char* a, unsigned char* b);
void keyCopy(unsigned char* a, unsigned char* b);
void keyPrint(unsigned char* a);
void keyClear(unsigned char* a);
int keyIndexOf(const char value);

void init(void) {
    for(int i=0 ; i<4 ; i++) {
        pinMode(rowPins[i], OUTPUT);
        pinMode(colPins[i], INPUT);
    }
}

int main(void){
    unsigned char pressed_keys[BUTTON_NUM];
    unsigned char last_key_pressed[BUTTON_NUM];

    if(wiringPiSetup() == -1){ //quando l'inizializzazione wiring fallisce, stampa messaggio a schermo
        printf("setup wiringPi failed !");
        return 1;
    }
    init();
    while(1){
        keyRead(pressed_keys);
        bool comp = keyCompare(pressed_keys, last_key_pressed);
        if (!comp){
            keyPrint(pressed_keys);
            keyCopy(last_key_pressed, pressed_keys);
        }
        delay(100);
    }
    return 0;
}

void keyRead(unsigned char* result){
    int index;
    int count = 0;
    keyClear(result);
    for(int i=0 ; i<ROWS ; i++ ){
        digitalWrite(rowPins[i], HIGH);
        for(int j =0 ; j < COLS ; j++){
            index = i * ROWS + j;
            if(digitalRead(colPins[j]) == 1){
                result[count]=KEYS[index];
                count += 1;
            }
        }
        delay(1);
        digitalWrite(rowPins[i], LOW);
    }
}

bool keyCompare(unsigned char* a, unsigned char* b){
    for (int i=0; i<BUTTON_NUM; i++){
        if (a[i] != b[i]){
            return false;
        }
    }
    return true;
}

void keyCopy(unsigned char* a, unsigned char* b){
    for (int i=0; i<BUTTON_NUM; i++){
        a[i] = b[i];
    }
}

void keyPrint(unsigned char* a){
    if (a[0] != 0){
        printf("%c",a[0]);
    }
    for (int i=1; i<BUTTON_NUM; i++){
        if (a[i] != 0){
            printf(", %c",a[i]);
        }
    }
    printf("\n");
}

void keyClear(unsigned char* a){
    for (int i=0; i<BUTTON_NUM; i++){
        a[i] = 0;
    }
}

int keyIndexOf(const char value){
    for (int i=0; i<BUTTON_NUM; i++){
        if ((const char)KEYS[i] == value){
            return i;
        }
    }
    return -1;
}

Spiegazione del Codice

unsigned char KEYS[BUTTON_NUM] {
'1','2','3','A',
'4','5','6','B',
'7','8','9','C',
'*','0','#','D'};

unsigned char rowPins[ROWS] = {1, 4, 5, 6};
unsigned char colPins[COLS] = {12, 3, 2, 0};

Dichiara ogni tasto della tastiera a matrice nell’array keys[] e definisci i pin su ogni riga e colonna.

while(1){
        keyRead(pressed_keys);
        bool comp = keyCompare(pressed_keys, last_key_pressed);
        if (!comp){
            keyPrint(pressed_keys);
            keyCopy(last_key_pressed, pressed_keys);
        }
        delay(100);
    }

Questa è la parte della funzione principale che legge e stampa il valore del pulsante.

La funzione keyRead() leggerà lo stato di ogni pulsante.

KeyCompare() e keyCopy() vengono utilizzati per verificare se lo stato di un pulsante è cambiato (cioè se un pulsante è stato premuto o rilasciato).

keyPrint() stamperà il valore del pulsante il cui livello corrente è alto (il pulsante è stato premuto).

void keyRead(unsigned char* result){
    int index;
    int count = 0;
    keyClear(result);
    for(int i=0 ; i<ROWS ; i++ ){
        digitalWrite(rowPins[i], HIGH);
        for(int j =0 ; j < COLS ; j++){
            index = i * ROWS + j;
            if(digitalRead(colPins[j]) == 1){
                result[count]=KEYS[index];
                count += 1;
            }
        }
        delay(1);
        digitalWrite(rowPins[i], LOW);
    }
}

Questa funzione assegna un livello alto a ciascuna riga a turno e, quando il tasto della colonna viene premuto, la colonna in cui si trova il tasto ottiene un livello alto. Dopo la valutazione del ciclo a due livelli, lo stato del tasto compilerà un array (reasult[]).

Quando si preme il tasto 3:

../_images/image187.png

RowPin [0] scrive nel livello alto, e colPin[2] ottiene il livello alto. ColPin [0], colPin[1], colPin[3] ottengono il livello basso.

Questo ci dà 0,0,1,0. Quando rowPin[1], rowPin[2] e rowPin[3] vengono scritti a livello alto, colPin[0]~colPin[4] ottengono livello basso.

Dopo che la valutazione del ciclo è completata, verrà generato un array:

result[BUTTON_NUM] {
0, 0, 1, 0,
0, 0, 0, 0,
0, 0, 0, 0,
0, 0, 0, 0};
bool keyCompare(unsigned char* a, unsigned char* b){
    for (int i=0; i<BUTTON_NUM; i++){
        if (a[i] != b[i]){
            return false;
        }
    }
    return true;
}

void keyCopy(unsigned char* a, unsigned char* b){
    for (int i=0; i<BUTTON_NUM; i++){
        a[i] = b[i];
    }
}

Queste due funzioni vengono utilizzate per verificare se lo stato del tasto è cambiato, ad esempio quando si rilascia il pulsante “3” o si preme “2”, keyCompare() restituisce false.

KeyCopy() viene utilizzato per riscrivere il valore corrente del pulsante nell’array a (last_key_pressed[BUTTON_NUM]) dopo ogni confronto. Così possiamo confrontarli la prossima volta.

void keyPrint(unsigned char* a){
//printf("{");
    if (a[0] != 0){
        printf("%c",a[0]);
    }
    for (int i=1; i<BUTTON_NUM; i++){
        if (a[i] != 0){
            printf(", %c",a[i]);
        }
    }
    printf("\n");
}

Questa funzione viene utilizzata per stampare il valore del pulsante attualmente premuto. Se il pulsante “1” viene premuto, verrà stampato “1”. Se il pulsante “1” viene premuto e il pulsante “3” viene premuto, verranno stampati “1, 3”.

Immagine del Fenomeno

../_images/image188.jpeg