Nota

Ciao, benvenuto nella community di SunFounder Raspberry Pi & Arduino & ESP32 Enthusiasts su Facebook! Immergiti più a fondo in Raspberry Pi, Arduino ed ESP32 con altri appassionati.

Perché unirti?

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

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

  • Anteprime esclusive: Ottieni accesso anticipato a nuovi annunci di prodotti e anteprime.

  • Sconti speciali: Goditi sconti esclusivi sui nostri prodotti più recenti.

  • Promozioni festive e omaggi: Partecipa a omaggi e promozioni festive.

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

2.1.8 Tastierino

Introduzione

Un tastierino è una matrice rettangolare di pulsanti. In questo progetto, lo 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

ELEMENTI IN QUESTO KIT

LINK

Kit Raphael

337

Raphael Kit

Puoi anche acquistarli separatamente dai link sottostanti.

INTRODUZIONE COMPONENTE

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 sul tastierino (valore del pulsante) verranno stampati sullo schermo.

Nota

Se non funziona dopo l’esecuzione o compare un messaggio di errore: "wiringPi.h: No such file or directory", consulta Installazione e verifica di 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){ //se l'inizializzazione di wiring fallisce, stampa un messaggio sullo 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 di 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 giudicare se lo stato di un pulsante è cambiato (ovvero un pulsante è stato premuto o rilasciato).

keyPrint() stamperà il valore del pulsante il cui livello corrente è alto (il pulsante è 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 nella colonna viene premuto, la colonna in cui si trova il tasto ottiene un livello alto. Dopo che il ciclo di controllo a doppio livello è completato, lo stato del tasto genererà un array (result[]).

Quando viene premuto 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] sono scritti nel livello alto, colPin[0]~colPin[4] otterranno il livello basso.

Dopo che il ciclo di controllo è completato, 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 giudicare 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. In modo che 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” è premuto, verrà stampato “1”. Se il pulsante “1” è premuto e anche il pulsante “3” è premuto, verrà stampato “1, 3”.

Immagine del fenomeno

../_images/image188.jpeg