有些時候我們的專題製作需要有可以輸入資料的介面,對於Arduino來說當然不能直接加上電腦的鍵盤,而且別忘了,在開發階段時Arduino是連接到電腦,可以使用電腦的鍵盤輸入沒錯,但是一旦在產品階段時,Arduino不但失去了電腦螢幕,當然也就沒有電腦的鍵盤可以使用了,所以在實用上,如果需要輸入數字資料,通常我們會去找一個數字鍵盤模組來使用。而在這些模組中,最常用的是如下面所示的這種:

這種數字鍵盤模且主要有2種規格,一種是3×4的,一種則是4×4的,在這裡使用的是4×4的模組版本。為什麼使用這種模組?因為在Arduino官網中已經有現成的程式庫可以使用,只要匯入該程式庫,就可以用短短地幾行指令即可取得按鈕的輸入。以我們在這裡使用的這個模組來說,它有8條接腳,分別是列有4支,行有4支,只要依順序把它連接到Arduino相對應的腳位去就可以了。連接的方式如下:

然後下圖是連接完成之後的樣子:

在這個例子中,我們分別把這些接腳連接到2, 3, 4, 5, 6, 7, 8, 9這幾個GPIO接腳上,要留意的是,這個模組並不需要供給電源,只要這幾支接腳就好了,連接完畢之後,使用以下的程式即可在監控視窗中觀察每一個按鈕按下去之後會對應的數字和文字(請到這裡去下載Keypad.h):

#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5};
byte colPins[COLS] = {6,7,8,9};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
  Serial.begin(9600);
}
void loop(){
  char key = keypad.getKey();
  if (key != NO_KEY){
    Serial.println(key);
  }
}

這個程式中最重要的地方是一開始匯入Keypad.h標頭檔的地方,匯入之後才能夠使用Keypad keypad這個實例宣告指令以建立這個模組的處理介面程式。此外,常數ROWS以及COLS宣告了列和行的數量,keys字元陣列宣告每一個按鈕被按下去所代表的字元,你可以自由也變更這裡面的內容。我們在連接Arduino和這個鍵盤的時候所選用的連線順序會影響到實際對應的按鍵內容,對筆者來說,先把線連接好,如果按鈕對應出來的字元不是自己想要的,再去修改這個陣列的內容就好了,不需要再重新連線喔。

另外,rowPins以及colPins是定義在Arduino中資料連接腳位的號碼,如果你不是連接到2~9的話,記得要來這裡改一下。主程式中會一直監測是否有按鍵被按下,如果有的話,就直接把對應的字元輸出到監控視窗中。

那麼,如果要輸入一連串的數字或文字,直到按下#之後才停止呢?程式碼可以改為如下:

#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'1','2','3','A'},
  {'4','5','6','B'},
  {'7','8','9','C'},
  {'*','0','#','D'}
};
byte rowPins[ROWS] = {2,3,4,5};
byte colPins[COLS] = {6,7,8,9};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
void setup(){
  Serial.begin(9600);
}

char buf[100];
int count;
boolean quit;
void loop(){
  char key = keypad.getKey();
  if (key != NO_KEY){
    count = 0;
    if(key != '#') {
      Serial.println(key);
      quit = false;
      buf[count++] = key;
      while (!quit) {
        key = keypad.getKey();
        if(key != NO_KEY) {
          if(key == '#') {
            quit = true;
            buf[count] = '\0';
          } else {
            buf[count++] = key;
          }
          Serial.println(key);
        }
      }
      Serial.print("Your input is ");
      Serial.println(buf); 
    }
  }
}

在這個程式中,只要按鍵的內容不是’#’,就會開始把每一個字元記錄到buf這個字元陣列中,直接再次按下’#’之後,就會把輸入的字元集合在一串輸出到監控視窗中,透過這個方法,同學們就可以建立一個在Arduino中可以輸入數字的鍵盤介面了。執行的結果如下所示:

同學們可以想想看,如果上述的程式搭配上前面單元中所介紹的LCD液晶顯示模組,那麼是否可以擁有一個可以輸入數字獨立介面功能的裝置了呢?還有另外一個也是數字鍵盤的輸入模組是薄膜式的,如下所示,也是可以使用同樣的程式設計方法:

在把線路接上之後,程式設計如下:

#include "Wire.h"
#include "LiquidCrystal_I2C.h"
#include <Keypad.h>
const byte ROWS = 4;
const byte COLS = 4;
char keys[ROWS][COLS] = {
  {'D','C','B','A'},
  {'#','9','6','3'},
  {'0','8','5','2'},
  {'*','7','4','1'}
};
byte rowPins[ROWS] = {2,3,4,5};
byte colPins[COLS] = {6,7,8,9};
Keypad keypad = Keypad( makeKeymap(keys), rowPins, colPins, ROWS, COLS );
LiquidCrystal_I2C lcd(0x27,2,1,0,4,5,6,7,3,POSITIVE);

void setup() {
  Serial.begin(9600);
  lcd.begin(16,2);
  lcd.backlight();
  delay(1000);
  lcd.setCursor(0, 0);
  lcd.print("Your pin code:");
}
char buf[100];
int count;
boolean quit;
void loop() {
  char key = keypad.getKey();
  if (key != NO_KEY){
    count = 0;
    lcd.setCursor(0,1);
    lcd.print("                ");
    lcd.setCursor(0,1);
    if(key != '#') {
      Serial.println(key);
      lcd.print(key);
      quit = false;
      buf[count++] = key;
      while (!quit) {
        key = keypad.getKey();
        if(key != NO_KEY) {
          if(key == '#') {
            quit = true;
            buf[count] = '\0';
          } else {
            buf[count++] = key;
          }
          lcd.print(key);
          Serial.println(key);
        }
      }
      Serial.print("Your input is ");
      Serial.println(buf); 
      lcd.setCursor(0, 1);
      lcd.print("                ");
      lcd.setCursor(0, 1);
      lcd.print(buf);
    }
  }
}

上述程式就具有可以輸入數字或文字內容,並把它組合成一個字串給後續的程式碼中使用了。示範影片如下:

 

(984)