아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

아두이노 금고 만들기


1. 아두이노 금고 소개

아두이노 우노, LCD 모듈, 멤브레인 4x4 키패드, 서보모터 sg90을 이용한 간단한 금고입니다.

필요 부품: 아두이노 uno, LCD모듈(16*2), 멤브레인 4*4 키패드, 서브모터 sg90, 건전지(9V), 건전지홀더, 부저, 점퍼선

처음 LCD 화면에는 비밀번호를 입력하라는 “Password: “가 나타납니다. 비밀번호 4자리를 키패드로 입력하고 입력된 기호는 LCD 화면에 나타납니다. 비밀번호가 틀렸다면 ‘Access Denied’를 출력하고 다시 처음 화면으로 돌아갑니다. 반대로 비밀번호가 맞으면 문이 열렸다는 메시지와 함께 모터가 돌아가 문을 열 수 있으며, 문을 닫은 뒤 “*” 버튼을 눌러 다시 잠글 수 있습니다.

<외부 모습>

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

<내부 모습 >

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

2. 주요 부품 소개

  1)  4x4 키패드

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

(그림 출처 : circuitdigest.com)

가장 기본적인 4x4 키패드는 다음과 같이 16개의 스위치가 연결되어 있는 형태입니다. 16개의 스위치를 행열의 형태로 행과 열로 나눠 값을 입력받는 구조입니다. 그렇기 때문에 키패드의 단자는 행과 열의 합이며 4*4 키패드에서는 총 8개가 되고 차례대로 아두이노에 연결해 사용하시면 됩니다. 주로 2-10번 단자를 사용합니다.

#include <Keypad.h> //키패드 헤더파일

const byte ROWS = 4; //키패드 행의 개수
const byte COLS = 4; //키패드 열의 개수를 선언해줍니다.
byte rowPins[ROWS] = {9,8,7,6}; //행 핀번호 ->R1, R2, R3, R4
byte colPins[COLS] = {5,4,3,2}; //열 핀번호 ->C1, C2, C3, C4
char keys[ROWS][COLS] = { //키패드 행열 선언
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
Keypad keypad = Keypad(makeKeymap(keys),rowPins, colPins,ROWS,COLS); //키패드선언

///ex)
void loop(){
char key = keypad.getKey(); //키패드를 통해 기호 받아서 'key'에 저장
key = keypad.waitForKey(); //키패드가 눌리기 때까지 대기
}

키패드를 사용하기 위해서는 다음과 같이 키패드 객체를 선언해 주어야 합니다. 먼저 키패드의 행과 열 갯수를 정의한 다음 아두이노에 연결된 핀번호를 차례대로 적어줍니다. 행과 열을 받아 각 자리에 어떤 기호가 들어가는지 2차원 행열로 나열해 줍니다. 마지막으로 위와 같이 키패드의 객체를 선언해주면 키패드를 이용한 코드를 작성할 수 있습니다.

가장 많이 쓰이는 코드는 입력받은 키를 저장하는 keypad.getKey(); 입니다. 캐릭터 값으로 변수를 설정해 그 값을 저장합니다. 또한 키패드가 눌리지 않았는데 자동으로 넘어가는 경우를 방지하기 위해 keypad.waitForKey(); 함수를 사용합니다.

 2)   1602 LCD 모듈

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

LCD는 Liquid Crystal Display의 약자로 액정표시장치를 말합니다. 여기에서 액정 (Liquid Crystal)이란 액체처럼 유체의 성질을 가지면서 고체처럼 광학적 성질을 가지는 물질입니다. 또한 액정은 고체표면에 액정이 특정 방향으로 정렬할 수도 있어, 전기적 신호를 가해 원하는 방향으로 배열하여 빛을 투과시키거나 차단시킬 수 있습니다.
LCD는 이러한 액정의 성질을 이용합니다. 빛을 내는 백라이트, 백라이트에서 나온 빛을 한 방향으로  투과시키기 위한 편광판, 각 픽셀에 대한 액정 배열을 조절하여 투과하는 빛의 양을 제어하는 TFT, 그 다음으로 액정이 순서대로 위치하여 구성이됩니다. 또한 컬러 지원여부에 따라 컬러 필터가 추가될 수 있습니다.

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

1602 LCD 는 가로 세로 16*2 , 32글자를 출력이 가능합니다. 기존 LCD는 다음과 같이 16개의 핀 번호를 가지고 있으며 주로 1~6, 11~16번 총 12개의핀을 사용하여 화면에 글자를 출력합니다. 그렇다 보니 아두이노에서도 디지털 포트 6개 (GND, 5V외 4)를 사용해 포트 사용이 비효율적이라는 단점을 가지고 있습니다.

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

기존 LCD의 이러한 문제점을 해결하고자 아래와 같이 모듈이 결합된 형태인 I2C LCD 모듈을 주로 사용합니다. 12의 핀을 사용했던 전 형태와 달리 오른쪽 끝의 GND, VCC, SDA, SCL의 4개만 사용하여 아두이노에 연결해 사용할 수 있습니다. GND - GND, VCC- 5V, SDA-A4, SCL-A5에 연결해 사용해주시면 됩니다. 기존 LCD는 15번 포트에 저항을 연결해 선명도를 결정하였다면 I2C의 경우 파란색 박스 안을 스크류드라이버로 돌려가며 저항을 쉽게 조절해 줄 수 있습니다 (처음 LCD를 실행한 경우 글자가 보이지 않게 저항이 설정되어 있으니 원하는 밝기로 조절하셔야 합니다).

아두이노 키패드 잠금 장치 - adu-ino kipaedeu jamgeum jangchi

(I2C LCD 모듈 / 사진 출처 : addicore ,자료 출처 : https://kocoafab.cc/tutorial/view/727)


#include <LiquidCrystal_I2C.h> //LCD모듈 헤더파일 (I2C유무 차이 주의)

LiquidCrystal_I2C lcd(0x27,16,2); //LCD핀번호 선언
//-- 주소값 맞는지 확인

void setup(){
lcd.init(); //LCD 화면 초기화
lcd.backlight(); //LCD 백라이트 키기
lcd.noBacklight(); //LCD 백라이트 끄기
}

void loop(){
lcd.setCursor(0,0); //커서 위치 조절 (column, row)
lcd.print("Password:"); // LCD 화면에 원하는 값 출력
}

먼저 LiquidCrystal_I2C.h의 헤더파일을 열어야 하는데 아두이노에 기본적으로 저장되어 있는 LiquidCrystal.h와는 다릅니다. 다음으로  LCD의 주소값과 가로 세로의 크기를 적어 객체를 선언해 줍니다.. 그럼 LCD I2C의 기본 함수를 사용할 수 있습니다. 많이 쓰이는 함수는 위와 같습니다.

백라이트와 화면에 표시되는 기호는 각 다른 함수를 통해 제어할 수 있습니다. 먼저 백라이트의 경우, backlight();로 키고 noBacklight();로 끌 수 있습니다. 화면 출력은 print("~");의 형태로 할 수 있으며 어느 위치에 출력하고 싶은지에 따라 setCursor(column,row)로 커서를 이동해 원하는 값을 출력할 수 있습니다.

 3)  부저 및 sg-90 -> '미로찾기' 프로젝트 및 학기 초 온라인 세미나 참고

3. 기타 소프트웨어 관련

  • 아두이노, LCD(I2C), 키패드 라이브러리 설치 (헤더파일을 쳤을 때 글씨가 빨간색으로 나와야 함!)

아두이노를 처음 다운로드 받으면 기본적인 라이브러리는 내장되어 있지만 LCD 모듈을 위한 LCD I2C 파일과 키패드 라이브러리를 따로 다운로드받아서 넣어줘야 합니다.

아두이노 실행 > 라이브러리 포함하기 > 라이브러리 관리 > 원하는 라이브러리 찾아 설치

또는 아래 zip 파일을 다운받아 아두이노 실행 > 스케치 > 라이브러리 포함하기 > .ZIP추가

https://www.arduinolibraries.info/libraries/liquid-crystal-i2-c

https://www.arduinolibraries.info/libraries/keypad

.

  • LCD 주소값 알아내기(코드)

https://playground.arduino.cc/Main/I2cScanner/

위 사이트에서 코드 다운로드 받아서 업로드 > 툴 >시리얼모니터 에서 0x_ _ 확인하기 (20 or 27 or 3F).

4. 작성 코드 예시

#include <Wire.h>
#include <LiquidCrystal_I2C.h> //LCD헤더파일
#include <Keypad.h> //키패드 헤더파일
#include <Servo.h> //서브모터 헤더파일

LiquidCrystal_I2C lcd(0x27,16,2); //LCD핀번호 선언
int buzzer = 12; //부저센서 12핀

//키패드
char PW[5] = {'1','2','3','4','\0'}; //비밀번호
const byte ROWS = 4; //키패드 행의 개수
const byte COLS = 4; //키패드 열의 개수
byte rowPins[ROWS] = {9,8,7,6}; //행 핀번호
byte colPins[COLS] = {5,4,3,2}; //열 핀번호
char keys[ROWS][COLS] = { //키패드 행열 선언
{'1','2','3','A'},
{'4','5','6','B'},
{'7','8','9','C'},
{'*','0','#','D'}
};
Keypad keypad = Keypad(makeKeymap(keys),rowPins, colPins,ROWS,COLS); //키패드선언

//서보모터
Servo myservo; //서보모터를 제어하기 위한 Servo객체 생성

//실행
void setup(){
lcd.init(); //LCD 초기화
lcd.backlight(); //lcd배경 빛 키기
myservo.attach(11); //서보모터 11번 핀으로 선택
myservo.write(0); //서보모터 0으로 시작
}

void loop(){
char key = keypad.getKey();
char str[5]={'0','0','0','0','\0'}; //입력받은 string 생성
lcd.setCursor(0,0);
lcd.print("Password:");

int i=9, j=0;
for (j=0;j<4;j++){ //비밀번호 4자릿수를 입력받음
{
key = keypad.waitForKey();
tone(buzzer,294,250);//레
lcd.setCursor(i,0); //출력받은 키를 커서를 옮겨가며 출력
lcd.print(key);
str[j] = key; //받은 비밀번호를 스트링에 저장
i++;
}
}

if(strcmp(PW,str)==0) //비밀번호가 정확할 때
{
unlock();
}
else //비밀번호가 틀렸을 때
{
tone(buzzer,262,200);
tone(buzzer,262,200);
lcd.init();
lcd.print("Access Denined");
delay(2000);
lcd.init(); //LCD 초기화
}

}

void unlock() //unlock 함수
{
tone(buzzer,392,200);
lcd.init();
lcd.setCursor(0,0);
lcd.print("Unlocked");
lcd.setCursor(0,1);
lcd.print("press * to lock");
myservo.write(90); //서보모터가 돌아가 문을 열 수 있음

char lock = keypad.getKey(); //'*'을 눌러 다시 잠금
lock = keypad.waitForKey();
if(lock = '*'){
lcd.init();
lcd.setCursor(0,0);
myservo.write(0);
lcd.print("Locked");
delay(2000);
}
}