Arduino 4×4薄膜鍵盤模組實驗(一):按鍵掃描程式原理說明

下圖左是一款常見的薄膜按鍵模組(hex keypad),有4×4或3×4(少了最右邊一行的A, B, C, D鍵),它的內部如同下圖右邊的電路所示,是由16個按鍵(開關)交織而成。有些按鍵模組直接使用按鍵(微觸)開關組裝,連接電路與程式都和本文相同。

薄膜按鍵模組(hex keypad)

4×4按鍵模組有8個接腳,分成列、行兩組,可以接在Arduino的任意8個接腳,筆者將它接在數位6~13腳:

4x4按鍵模組連接Arduino

為了簡化接線,可以使用「長腳型」排針,將其中兩個腳用尖嘴鉗稍微折彎,即可插入Arduino的排母:

「長腳型」排針

排針上頭的黑色塑膠,可以用蠻力讓它移到中間的位置,以便銜接兩邊的排母:

使用排針銜接Arduino和薄膜按鍵模組

4×4薄膜鍵盤的Arduino按鍵偵測程式

撰寫Arduino按鍵偵測程式,最簡單也是最好的方式,就是採用既有的程式庫。本單元將示範使用Keypad程式庫,把偵測到的按鍵字元顯示在序列埠監控視窗。請按此下載Keypad程式庫(原始出處在這篇keypad介紹文),解壓縮之後,置入Arduino的libraries路徑:

Keypad程式庫

底下的程式,修改自Keypad程式庫的“HelloKeypad”範例,使用此程式庫,我們的程式碼需要定義按鍵模組的行(col)、列(row)數、連接Arduino的腳位以及按鍵所代表的字元

編譯並上傳程式碼,再開啟「序列監控視窗」,按下薄膜鍵盤的任何按鍵,該字元將顯示在序列埠監控視窗。

按鍵偵測與掃描原理

為了方便解說,筆者把4×4按鍵簡化成3×1,像下圖這樣串連三個開關,連接到同一個微控制器的輸入腳。此外,因為要簡化開關電路,所以要啟用微控器內部的上拉電阻(請參閱《超圖解Arduino互動設計入門》第四章「啟用微控器內部的上拉電阻」一節,4-13頁):

掃描按鍵的原理

假設開關的「行1」~「行3」輸入端全都輸入高電位,無論開關是否被按下,Arduino將接收到高電位(1)。為了檢測到其中按鍵被按下,程式必須依序將「行1」~「行3」腳位設定成低電位。

掃描按鍵的原理

輪到「行2」腳輸入低電位,此時,微控器的輸入腳也將接收到低電位(0),由此可知連接「行2」的「開關B」被按下了

掃描按鍵的原理

輪到「行3」腳輸入低電位,由於「開關C」未被按下,因此微控器的輸入腳接收到高電位(1)。

掃描按鍵的原理

到此,偵測按鍵的程式必須再次回到「行1」,輸入低電位…如此反覆循環掃描,才能持續偵測到某個按鍵是否被按下。實際的程式需要運用雙重迴圈,才能分批掃描每一列:

掃描按鍵的雙重迴圈

雙重迴圈的練習,請參閱《超圖解Arduino互動設計入門》第8章「LED矩陣動畫與多維陣列程式設計」一節,8-28頁。

自行撰寫掃描按鍵的程式

根據以上說明,自行撰寫掃描按鍵的程式碼:

Keypad程式庫的運作方式大致上面的程式相同,主要是多了消除彈跳(debounce)的程式(相關說明請參閱第四章「解決開關訊號的彈跳問題」一節,4-15頁),而且按鍵掃描的間隔時間是透過比對時間差,而非使用delay。上面的程式用於幫助理解掃描按鍵的原理,在實際專案製作上,請使用Keypad程式庫。

未完,待續…

延伸閱讀

2 thoughts on “Arduino 4×4薄膜鍵盤模組實驗(一):按鍵掃描程式原理說明

  1. 請問一下
    1.
    Keypad() 這函式是只能接受 Keypad( char , byte , byte , int , int ) 這樣的型態嗎?
    byte colPins[KEY_COLS] = {9, 8, 7, 6};
    byte rowPins[KEY_ROWS] = {13, 12, 11, 10};
    這兩行腳位宣告,我把型態變成int後就在Keypad()出現 no matching function

    2.
    #define KEY_ROWS 4 // 按鍵模組的列數
    #define KEY_COLS 4 // 按鍵模組的行數
    如果把這兩行定義變成
    int KEY_ROWS = 4;
    int KEY_COLS = 4;
    後面只要跟這兩變數有關的都會錯誤,說沒有宣告…
    這是為什麼呢?

    1. hi vivian:

      因為Arduino的C程式,不允許使用變數定義陣列的範圍,請改用常數,例如:

      const byte KEY_ROWS = 4; // 按鍵模組的列數
      const byte KEY_COLS = 4; // 按鍵模組的行數

      thanks,
      jeffrey

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *