Arduino 4×4薄膜鍵盤模組實驗(三):結合LCD顯示器的密碼輸入介面

本文將結合4×4薄膜按鍵以及文字型LCD顯示器,製作一個密碼輸入介面。程式一開始在LCD顯示兩列文字,第0列始終顯示“Knock, knock…”(敲、敲…)。第1列提示用戶輸入密碼(pin number):

若按下’*’鍵,可清除輸入的字元,重新輸入;按下’#’鍵,代表「確認」輸入。

按下”#”號之後,若密碼正確,則在第1列顯示“Welcome home!”(歡迎回家!):

若密碼錯誤,則在第1列顯示“***WRONG!!***”(錯誤!!):

I2C介面的LCD顯示器模組以及實驗材料

本單元的實驗材料如下:

  • Arduino Uno控制板,一片。
  • 4×4薄膜鍵盤,一個。
  • 1602文字型LCD顯示器模組,一個。
  • 自製LCD模組的序列轉接板或現成的I2C介面轉接板,一個。

文字型LCD顯示器模組,請依《超圖解Arduino互動設計入門》第九章「串列連接LCD顯示模組」一節說明,配合74LS164組裝好,或者,購買I2C介面的Hitachi HD44780U 1602 LCD點陣液晶模組,底下是I2C介面的轉接板和1602 LCD模組的外觀,轉接板和LCD模組上的排針和排插可能要自行焊接:

Hitachi HD44780U 1602 LCD點陣液晶模組

I2C介面的顯示器轉接板,都是依照LCD模組的接腳設計,兩者可直接焊在一起。結合LCD顯示器和I2C介面模組的模樣:

Hitachi HD44780U 1602 LCD點陣液晶模組

實驗電路接線

請依照下圖連接薄膜鍵盤和LCD序列顯示模組,即便是採用74LS164組裝的LCD模組的資料和時脈線,也能接在類比輸入埠,因為Arduino的類比輸入埠兼具數位輸出∕入功能

連接薄膜鍵盤和LCD序列顯示模組

實驗程式:清除LCD顯示字元

本單元程式需要補充說明的,應該只有清除顯示字元部份。清除顯示字元的方法,就是用「空白字元」蓋掉原本的字元。

用戶按下“*”鍵,程式需要從第1列第4行到第15行,填入空白字元:

清除LCD顯示字元

在顯示代表「歡迎回家」或者「錯誤!」的訊息之前,則需要清除整個第1列。筆者把清除文字的程式寫成名叫clearRow()的自訂函式,它將接收一個參數,代表從第1列的第n個位置開始清除。

執行 clearRow( 4 ),代表從第4個字元開始清除,函式裡的last值將是12,也就是從第4行開始,填入12個空白字元。

使用74LS164電路的LCD序列顯示器的完整程式碼如下,程式庫沿用書本第九章採行的LiquidCrystal_SR程式庫。

採用I2C介面的LCD顯示器程式

本單元程式採用的是這個I2C LCD顯示器程式庫,請注意,依I2C介面轉接板上的晶片或者韌體不同,驅動程式和I2C的位址可能不同,常見的位址有0x27, 0x38和0x3F,購買時請向商家確認。如果執行本單元的程式之後,LCD沒有顯示任何文字,請嘗試修改I2C位址,若是出現亂碼或者閃爍情況,請更換程式庫。

底下提供其他兩個具備I2C介面的1602 LCD程式庫當作參考:

不同程式庫的指令語法可能不一樣,請自行參閱程式庫的範例和說明。以本單元的程式庫為例,建立LCD物件的語法是:

並且經由底下的敘述初始化,以及選擇性地開啟背光:

完整的程式碼如下:

未完,待續…

延伸閱讀

25 thoughts on “Arduino 4×4薄膜鍵盤模組實驗(三):結合LCD顯示器的密碼輸入介面

  1. 老師:
    請問我用144*32的LCD顯示字元正確,但是一直無法顯示下一行,而用16*2的LCD可換下一行,但是字元都是亂碼?
    我是用74LS164IC的電路.

    #include
    #include // 引用LCD序列顯示器的程式庫
    LiquidCrystal_SR lcd(8,7,TWO_WIRE);
    void setup() {

    lcd.begin(16,2); // 初始化lcd物件

    lcd.home();

    lcd.write(“kiss me”);
    lcd.setCursor(0, 1); // 切換到第2行
    lcd.print(“PIN:”);
    lcd.cursor();
    }
    void loop(){
    }

  2. 使用原作者的範例用144*32的中文LCD,會出現一個笑臉圖左右移動,但是用16*2的LCD則是亂碼?

    1. hi dull-boy:

      因為144×32顯示器是「繪圖型LCD」,它採用的晶片和文字型LCD完全不同,所以程式庫不一樣,程式指令也可能不同。

      thanks,
      jeffrey

  3. 可是我用16*2的LCD會出現亂碼,原作者的函式庫3個版本我都用了,都是亂碼…
    只有144*32的LCD搭配最早版本的函式庫,能正常顯示字元,但是無法出現第2行的字串..

  4. 那104電容我覺得有接沒接都一樣,都試過了,並接在ic電源接腳,就同等並接在整個電路的電源,,兩個LCD我用並列傳輸的方式,都能正常顯示喔

  5. 老師抱歉再問你一下
    那如果使用A來設定新的一組密碼的話,那要如何讓程式判定新的密碼?

    1. 因為密碼存在passcode變數,所以程式碼還是一樣:

      thanks,
      jeffrey

  6. 老師不好意思,我想請問我已經寫出有關按鍵C的設定可是要如何核對舊的1234這組密碼如果核對正確再輸入新的密碼,我現在卡在這個問題點試過很多方法都會直接跳到上一段輸入正確的地方,拜託老師幫我指點了,謝謝老師。

    1. 請先寫下你預期的程式流程,例如:

      輸入密碼
      按下 ‘C’ 鍵
      若密碼正確
      則在LCD第0列顯示 “New Password:”
       輸入新的密碼
       輸入完畢後再次按下 ‘C’ 鍵儲存

      若密碼不正確,則顯示”WRONG!!”然後返回初始狀態。

      如果是這樣的話,
      程式要判斷 ‘C’ 鍵被按了幾次,
      你可以用一個變數來紀錄按下的次數,
      假設這個變數叫做 pressC,預設為0

      用戶首先輸入密碼,接著按下C鍵,底下的條件式將被執行:

      if (pressC == 0) {
       代表C鍵第一次被按下
       比對輸入值與passcode值

       pressC ++;
      } else {
       代表第2次按下C鍵
       把輸入值存入passcode // 這就紀錄新密碼啦~

       pressC = 0; // 清除按鍵紀錄
      }

      have fun!
      jeffrey

  7. 老師,我想再問一下pressC要宣告在一開始的部分還是放在if判斷句中就好了呢?
    可是如果用pressC那不就(key==’C’)這行就不必使用了嗎?
    謝謝老師好幾次的回答小弟感激不盡。

    1. ㄟ…如果搞不清楚的話,變數宣告就放在程式開頭,至於要不要(key==’C’),就看你的程式需要,還是那句話…你試試看就知道了。

      thanks,
      jeffrey

  8. void checkPinCode() {
    clearRow(0); // 從第0個字元開始清除LCD畫面
    lcd.noCursor();
    lcd.setCursor(0, 1); // 切換到第2行
    // 比對密碼
    if (inputCode == passcode) {
    lcd.clear();
    lcd.print(” Unlocked “);
    }else if(inputCode !=passcode){
    lcd.clear();
    lcd.print(“***False!!***”);
    ccount++;
    if(ccount>=3)//如果輸入密碼錯誤達到3次立即發出警報
    {
    lcd.clear();
    lcd.print(“****ALARM!!****”);
    tone(buzzer,1000);
    delay(1000);
    }
    }
    resetLocker();
    delay(3000);
    }
    老師我想問一下如果在ALARM時候不想讓他復歸可以加上什麼呢?

  9. else if(key==’C’){
    lcd.clear();
    lcd.print(“old password:”);
    lcd.setCursor(0, 1);
    lcd.cursor();
    if (inputCode == passcode) {
    lcd.clear();
    lcd.print(“newpassword”);
    lcd.setCursor(0, 1);
    lcd.cursor();
    pressC++;
    lcd.cursor();
    inputCode = “”;
    inputCode=passcode;
    pressC==0;
    }
    resetLocker;
    delay(300);
    }
    老師是這樣存進去passcode的嗎?
    如果不是的話可以可以幫我點明該如何存進去passcode
    謝謝老師!!

    1. 大致像這樣,程式未驗證:

      good luck!
      jeffrey

  10. 老師這是我改出來的部分程式驗證過也是可以的,也謝謝老師的教導,學生我感激不盡!!

發表迴響

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