注釈

こんにちは、SunFounderのRaspberry Pi & Arduino & ESP32愛好家コミュニティへようこそ!Facebook上でRaspberry Pi、Arduino、ESP32についてもっと深く掘り下げ、他の愛好家と交流しましょう。

参加する理由は?

  • エキスパートサポート:コミュニティやチームの助けを借りて、販売後の問題や技術的な課題を解決します。

  • 学び&共有:ヒントやチュートリアルを交換してスキルを向上させましょう。

  • 独占的なプレビュー:新製品の発表や先行プレビューに早期アクセスしましょう。

  • 特別割引:最新製品の独占割引をお楽しみください。

  • 祭りのプロモーションとギフト:ギフトや祝日のプロモーションに参加しましょう。

👉 私たちと一緒に探索し、創造する準備はできていますか?[ここ]をクリックして今すぐ参加しましょう!

2.1.8 キーパッド

はじめに

キーパッドはボタンの矩形配列です。このプロジェクトでは、それを使用して文字を入力します。

必要な部品

このプロジェクトでは、以下のコンポーネントが必要です。

../_images/list_2.1.5_keypad.png

キット全体を購入すると非常に便利です。リンクは以下のとおりです:

名前

このキットのアイテム

リンク

Raphael Kit

337

Raphael Kit

以下のリンクから個別に購入することもできます。

コンポーネントの紹介

購入リンク

GPIO拡張ボード

購入

ブレッドボード

購入

ジャンパーワイヤー

購入

抵抗器

購入

キーパッド

-

回路図

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

実験手順

ステップ1: 回路を組み立てます。

../_images/image186.png

ステップ2: コードファイルを開きます。

cd ~/raphael-kit/c/2.1.8/

ステップ3: コードをコンパイルします。

gcc 2.1.8_Keypad.cpp -lwiringPi

ステップ4: 実行します。

sudo ./a.out

コードを実行した後、キーパッドの押されたボタンの値(ボタン値)が画面に表示されます。

注釈

実行後に動作しない、またはエラーメッセージ「wiringPi.h: No such file or directory」が表示された場合は、 WiringPiのインストールと確認 を参照してください。

コード

#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){ //when initialize wiring failed,print message to screen
        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;
}

コード説明

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

マトリックスキーボードの各キーを配列 keys[] に宣言し、各行と列のピンを定義します。

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

これは、ボタン値を読み取り、印刷するメイン関数の部分です。

関数 keyRead() は、各ボタンの状態を読み取ります。

KeyCompare() および keyCopy() は、ボタンの状態が変わったかどうか(つまり、ボタンが押されたか、またはリリースされたか)を判断するために使用されます。

keyPrint() は、現在のレベルが高レベルであるボタン(ボタンが押されている)のボタン値を印刷します。

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

この関数は、各行に順番に高レベルを割り当て、列のキーが押されると、キーが位置している列が高レベルを取得します。2層のループ判断の後、キーの状態のコンパイルが配列( reasult[] )を生成します。

「3」のボタンを押すと:

../_images/image187.png

RowPin [0] には高レベルが書き込まれ、colPin[2] は高レベルを取得します。 ColPin [0] , colPin[1], colPin[3] は低レベルを取得します。

これにより、0,0,1,0が得られます。rowPin[1]、rowPin[2]、rowPin[3]に高レベルが書き込まれると、colPin[0]〜colPin[4]は低レベルを取得します。

ループ判断が完了すると、配列が生成されます:

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];
    }
}

これらの2つの関数は、キーの状態が変わったかどうかを判断するために使用されます。例えば、「3」を押して手を放したときや「2」を押したとき、keyCompare()はfalseを返します。

KeyCopy()は、各比較の後に、a配列(last_key_pressed[BUTTON_NUM])に現在のボタン値を再書きするために使用されます。これにより、次回の比較が可能になります。

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

この関数は、現在押されているボタンの値を印刷するために使用されます。ボタン「1」が押されている場合、「1」が印刷されます。ボタン「1」が押され、ボタン「3」が押されている場合、「1, 3」が印刷されます。

現象の画像

../_images/image188.jpeg