프로젝트

나도 메이커! 메이커스 여러분들의 작품/프로젝트를 공유하는 공간입니다.

빼빼로 금고 만들기

2016-03-16 17:11:36

 

안녕하세요!

 

만두입니다. 

벌써 2016년도에도 봄이 오고 있습니다. 봄바람 휘날리며~ 흩날리는 벚꽃 잎이~ 

봄은 참 설레는 계절인 것 같아요.

3월 14일 화이트데이도 지나가고, 이제 남은 데이는 빼빼로데이 뿐!

그래서 이번에 처음 만들어 본 프로젝트는 빼빼로데이를 겨냥한 '빼빼로 금고'입니다.

아두이노를 처음 접해보았는데 코코아팹 덕분에 쉽게 프로젝트를 마무리할 수 있었습니다.

코코아팹의 모든 메이커분들께 감사 인사 올립니다^ㅇ^

 

 

제가 예전에 어느 게시판에서 본 빼빼로 금고입니다.

궁금하신 분은 여기에서 원글을 확인하실 수 있습니다. -> http://pann.nate.com/talk/317134264

신기하기만 했는데, 이번에 제가 직접 만들어보고 싶다는 생각을 가지게 되었습니다.

기존 코코아팹 프로젝트에 올라와있는 금고 프로젝트와 매우 흡사합니다! 코코아팹.. 더럽.. (The Love..♥️)

 

 

 

선물용으로 만들 금고는 진짜 빼빼로를 사용해야 하지만...

저는.. 가난한공대생이므로.. 사진으로 대체했습니다...하.. 여러분들은 빼빼로 박스로 만들어보시길 바랍니다...

 

그럼 본격적으로 빼빼로 금고에 대해 소개를 해드리겠습니다!

 

 

 

동영상 시연

 

 

<금고 여는 순서>

1. 사전 등록한 네자리의 비밀 번호를 입력합니다. 일치하지 않을 경우 맞는 비밀 번호를 입력할 때까지 다음 단계로 넘어가지 않습니다. 

2. 비밀번호 일치시 금고의 문이 열립니다. 

3. 문을 닫고, 키패드의 '*'을 누르면, 금고가 잠깁니다.

 

 

 

<관리자 모드>

1. 금고 문이 열렸을 때 미리 지정해둔 관리자 번호를 누르면 관리자 모드로 진입하게 됩니다.

2. 변경하고 싶은 비밀번호를 입력합니다. 확인을 위해 다시 한 번 입력합니다.

3. 둘의 입력값이 같다면 성공적으로 비밀 번호가 변경됩니다.

4. 비밀번호 확인이 가능합니다.

 

 

 

부품 목록

 

NO 부품명 수량 상세설명
1 오렌지 보드 1  
2 서보모터 1 SG-90
3 16x2 LCD 1  
4 피에조 부저 1  
5 가변저항 1 1K
6 키패드 1  
7 스프링 1 용수철 누름(40mm)
8 잠금 고리 1  

 

부품명 오렌지 보드 서보모터 16x2 LCD 피에조 부저 키패드
파트
 

 

 

 

 

하드웨어 Making

 

 

브레드보드 레이아웃

 

 

회로도(스케메틱)

 

 

 

 

 

만드는 방법

 

1. 케이스 만들기

 저는 빼빼로가 프린팅 된 A4용지를 붙일 예정이었기 때문에 편리하게 A4용지 사이즈로 제작하였습니다.

빼빼로 상자로 만드시는 분들은 연인을 사랑하는만큼 많은 빼빼로를 이용하여 만들어보시면 어마어마하게 큰 금고가 완성되겠죠!

저는 금고 상단에 부품들을 넣었습니다.

아구가 안맞아보이는건 기분탓이겠죠..?

괜찮아요. 저는 A4용지로 다 가릴 예정이니까요^^!

 

 

조금 더 가까이에서 다시 한 번 보실까요?

 

 

2. 금고 잠금장치 배치

 금고 기능은 서보모터와 다*소에서 파는 생활용품을 이용하여 구현해보았습니다.

ㄷ자 고리를 붙이셔도 좋을 것 같습니다.

잠금시에는 고정되있다가 잠금을 해제하면 서보모터가 돌아가고, 스프링으로 인해 상자가 앞으로 밀려나오게 됩니다.

이쑤시개는.. 저 부분이 실리콘 소재라서

서랍을 강제로 당길 때 서보모터의 캡(하얀색) 부분이 부러질 것을 대비하여 붙여놓았습니다.

 

'ㅡ' 모양으로 눕혀져있는 서보모터의 캡이

서랍에 붙어있는 잠금장치의 가운데 공간으로 들어가고

'*' 버튼을 이용하여 잠그면

이쑤시개가 붙은 방향으로 90도 틀어지게 됩니다.

 

서랍을 밀어주는 스프링, 금고를 잠가주는 서보모터를 조금 더 자세히 보실까요?

 

'

하드웨어는 이것이 끝입니다! 넘나 간단한 것..

이제 프린트한 종이만 겉에 붙여주면 완성입니다.

✮☆✮☆✮☆짜란✮☆✮☆✮☆

원래 붙어있던 하트모양 장식은 어디갔냐구요? 바로.. 여러분 마음 속에 들어가있을겁니다..(*ㅡ_ㅡ*)

 

짜잔~

 

 

 

소프트웨어 코딩

/*
    제목: DIY 빼빼로 금고
    내용: 빼빼로 금고를 만들어보자
 */
#include "SoftwareSerial.h"
#include <LiquidCrystal.h>
#include <Keypad.h>
#include <Servo.h> 

Servo locker;

// LCD 초기화
LiquidCrystal lcd(13, 12, 11, 9, A1, A0); 

// 비밀번호 세팅
char secretCode[4] = {'1', '2', '3', '4'}; 

char input[4];
char newInput[4];
char key;

// 관리자 비밀번호 세팅
char adminCode[3] = {'#', '#', '#'}; 
char adminInput[3];


int position = 0;
int wrong = 0;
int i = 0;
int j = 0;
int pos = 0;
int a = 0;
int n = 0;
const byte rows = 4;
const byte cols = 4;
boolean c = false;

char keys[rows][cols] =
{
    {'1', '2', '3', 'A'},
    {'4', '5', '6', 'B'},
    {'7', '8', '9', 'C'},
    {'*', '0', '#', 'D'}
};

byte rowPins[rows] = {8, 7, 6, 5};
byte colPins[cols] = {4, 3, 2, 1};

// 키패드 오브젝트 생성
Keypad keypad = Keypad(makeKeymap(keys), rowPins, colPins, rows, cols); 

// 음계 표준 주파수(4옥타브) : 도, 레, 미, 파, 솔, 라, 시, 도
int tones[] = {261, 294, 330, 349, 392, 440, 494, 523};

void setup() {
    Serial.begin(9600);
    lcd.begin(16, 2);

    // 서보모터를 오렌지보드 10번핀에 부착
    locker.attach(10); 

    // 서보모터의 디폴트 각도 지정
    locker.write(0); 

    // 서보모터 핀모드
    pinMode(10,INPUT); 

    // 피에조부저 핀모드
    pinMode(A5, OUTPUT); 
}


void loop() {
    while (a == 0) {
        // 비밀번호 입력 모드
        inputKey();
        
        // 비밀번호 확인
        password();
        
        // 현재 상태 LCD에 보여줌
        passwordCheck();       
    }

    // 만약 비밀번호가 맞다면
    if (a == 1) {
        lcd.clear();
        lcd.setCursor(0, 0);
        pinMode(10,OUTPUT);

        // 서보모터 90도로 회전하며 금고 열림
        locker.write(90);      
    
        
        lcd.print("  ONLY FOR YOU");
        delay(2000);
        pinMode(10,INPUT);
        key = keypad.waitForKey();
    
        if (key == '*') {  
            lockOn();
        }
    
        else if (key == '#') {
            // admin mode를 위한 input 가능해짐.
            Serial.println("Admin Mode Available ");
            inputAdmin();
        }
    }
}


// 금고 잠금
void lockOn() {
    // flag 다시 0으로 초기화 
    a = 0;
                      
    lcd.clear();
    lcd.setCursor(0,0);
    pinMode(10,OUTPUT);
      
    lcd.print("    Lock ON");

    // 서보모터 0도로 회전하며 금고 잠금
    locker.write(0);     
    ringPiezo(99);
      
    delay(2000);
    pinMode(10,INPUT);  
}


void inputAdmin() {
    lcd.clear();
    lcd.setCursor(0, 0);
    pinMode(10,OUTPUT);
  
    lcd.print("Admin mode");  
    delay(1000);
    pinMode(10,INPUT);  
    
    for (i = 0; i < 3; i++) {
        key = keypad.waitForKey();
    
        if (key == '#') {
            Serial.print(i);
            input[i] = key;
        }
      
        else if (key == '*') {
            // 중간에 * 누를 시 lock되고 admin mode 빠져나옴
            lockOn(); 
            break;
        }
  
        if (i == 2) {
            Serial.println("");
            Serial.println("Go to Admin Mode");
          
            adminMode();
        }
    }
}


void adminMode()
{
    Serial.println("---- Admin Mode On ----");
  
    lcd.clear();
    pinMode(10,OUTPUT);
  
    lcd.setCursor(0, 0);
    lcd.print("1. P/W Change");   
    lcd.setCursor(0, 1);
    lcd.print("2. P/W Check"); 
  
    delay(2000);
    pinMode(10,INPUT);
    key = keypad.waitForKey();
  
    
    if (key == '1') {
        while (n == 0) {
            // 새 비밀번호 입력
            inputNewPassword();  
            
            // 새 비밀번호 다시 입력 
            inputNewPasswordAgain(); 
            
            // 위 두 번의 새 비밀번호 입력을 대조해봄
            newPassword(); 
            
            // 그 결과를 LCD로 띄움, wrong값 초기화
            newPasswordCheck(); 
            
        }
  
        if (a == 1) {
            // 두 값이 같을 때 비밀번호 변경
            setNewPassword(); 
        }
    }
    
    else if(key == '2') {
        // password check
        Serial.println("Password check");
    
        lcd.clear();
        pinMode(10,OUTPUT);
        
        
        lcd.setCursor(0, 0);
        lcd.print("Current Password");   
        
        
        for(int i = 0; i<4; i++) {
            lcd.setCursor(i + 6, 1);
            lcd.print(secretCode[i]);
            Serial.print(secretCode[i]);
        }
      
        delay(3000);
    }
}




void ringPiezo(int situation) {
    // 비밀번호 일치
    if (situation == 0) {
      
        for (int i = 0; i < 3; i++) {
            tone(A5, tones[2*i]);

            // 0.2초 동안 대기
            delay(200); 
        }

        tone(A5, tones[7]);
        delay(200);
        
        // 피에조 부저가 연결된 핀으로부터 square-ware를 생성을 중단하도록 설정합니다.
        noTone(A5); 
    }

    // *버튼으로 금고 lock
    else if(situation == 99) {
        tone(A5, tones[7]);
        delay(200); 
    
        for (int i = 0; i < 3; i++) {
            tone(A5, tones[4 - 2*i]);
            delay(200);
        }

        noTone(A5); 
    }

    // 비밀번호 불일치
    else {
        for (int i = 0; i < 3; i++) {
            tone(A5, tones[2]);
            delay(200);
        }
        noTone(A5);
    }
}



void inputKey() {
 
    lcd.clear();                      
    lcd.setCursor(0, 0);
    lcd.print("    Password");
    
    for (i = 0; i < 4; i++) {
        key = keypad.waitForKey();
        input[i] = key;
    
        if (input[0] == '#') {
            lcd.clear();
            lcd.setCursor(0, 0);

            // 첫 입력부터 # 버튼 누를 시   
            lcd.print("     '#' is");   
            lcd.setCursor(0, 1);
            
            // 삭제키라는 사실 알려줌
            lcd.print("   Delete Key"); 
            delay(2000);

            // 다시 비밀번호 첫자리 입력하도록
            i = i - 1; 
            lcd.clear();                      
            lcd.setCursor(0, 0);
            lcd.print("    Password");
        }
    
        else if (input[0] == '*') {
            lcd.clear();
            lcd.setCursor(0, 0);

            // 첫 입력부터 * 버튼 누를 시  
            lcd.print("     '*' is");    
            lcd.setCursor(0, 1);

            // 잠금키라는 사실 알려줌
            lcd.print("    Lock Key"); 
            delay(2000);

            // 다시 비밀번호 첫자리 입력하도록
            i = i - 1; 
            lcd.clear();                      
            lcd.setCursor(0, 0);
            lcd.print("    Password");
        }
      
        else if (i > 0 && input[i] == '#') {
            i = i - 1;
            lcd.setCursor(i + 6, 1);

            // 직전에 입력했던 key 삭제
            lcd.print(" "); 

            // 컴퓨터 모니터에도 보여줌
            Serial.println(""); 
            Serial.print("D");

            // 직전 key 다시 입력하도록
            i = i - 1; 
        }

        // * key는 패스워드에 포함되지 않도록
        else if (input[i] == '*') {
            i = i - 1;
        }
    
        else {
            lcd.setCursor(i + 6, 1);
            lcd.print("*");
            Serial.print(input[i]);
            Serial.print(",");
        }
    
      
        if (i == 3) {
            Serial.println("");
        }
    }
}


void password() {
    wrong = 0;
    for (j = 0; j < 4; j++) {
        if (secretCode[j] == input[j]) {
        }
        
        else if (secretCode[j] != input[j]) {
            wrong += 1;
        }
    }
}


void passwordCheck() {
    ringPiezo(wrong);
    
    if (wrong == 0) {
        Serial.println("correct");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("    CORRECT");
        delay(2000);
        a = 1;
        lcd.clear();
    }
    
    else if (wrong != 0) {
        Serial.println("wrong");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("     WRONG");
    
        delay(2000);
        a = 0;
        lcd.clear();
        wrong = 0;
    }
}



void inputNewPassword() {
    // 비밀번호 변경
    Serial.println("Password change");
    
    lcd.clear();
    pinMode(10,OUTPUT);
  
    
    lcd.setCursor(0, 0);
    lcd.print("Input New P/W");

    for (i = 0; i < 4; i++) {
        key = keypad.waitForKey();
        input[i] = key;
      
        if (input[0] == '#') {
            lcd.clear();
            lcd.setCursor(0, 0);

            lcd.print("     '#' is");  
            lcd.setCursor(0, 1);
            lcd.print("   Delete Key"); 
            delay(2000);
        
            i = i - 1; 
            lcd.clear();                      
            lcd.setCursor(0, 0);
            lcd.print("Input New P/W");
        }
    
        else if (input[0] == '*') {
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("     '*' is");    
            lcd.setCursor(0, 1);
            lcd.print("    Lock Key"); 
            delay(2000);
        
            i = i - 1;
            lcd.clear();                      
            lcd.setCursor(0, 0);
            lcd.print("    Password");
        }
      
        else if (i > 0 && input[i] == '#') {
            i = i - 1;
            lcd.setCursor(i + 6, 1);
            lcd.print(" "); 
            Serial.println(""); 
            Serial.print("D");
        
            i = i - 1;
        }
    
        else if(input[i] == '*') {
            i = i - 1;
        }
    
        else {
            lcd.setCursor(i + 6, 1);
            lcd.print("*");
            Serial.print(input[i]);
            Serial.print(",");
        }
    
      
        if (i == 3) {
            Serial.println("");
        }
    }
}




void inputNewPasswordAgain() {
    Serial.println("New password Check Again.");
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("  Please Again");
    
    for (i = 0; i < 4; i++) {
    
        key = keypad.waitForKey();
        newInput[i] = key;
      
        if (newInput[0] == '#') {
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("     '#' is");   
            lcd.setCursor(0, 1);
            lcd.print("   Delete Key"); 
            delay(2000);
        
            i = i - 1; 
            lcd.clear();                      
            lcd.setCursor(0, 0);
            lcd.print("Input New P/W");
        }
      
        else if (newInput[0] == '*') {
            lcd.clear();
            lcd.setCursor(0, 0);
            lcd.print("     '*' is");      
            lcd.setCursor(0, 1);
            lcd.print("    Lock Key"); 
            delay(2000);
        
            i = i - 1; 
            lcd.clear();                      
            lcd.setCursor(0, 0);
            lcd.print("    Password");
        }
        
        else if (i > 0 && newInput[i] == '#') {
            i = i - 1;
            lcd.setCursor(i + 6, 1);
            lcd.print(" "); // 직전에 입력했던 key 삭제
            Serial.println(""); // 모니터에도 보여줌
            Serial.print("D");
        
            i = i - 1; // 직전 key 다시 입력하도록
        }
      
        else if (newInput[i] == '*') {
            i = i - 1;
        }
      
        else {
            lcd.setCursor(i + 6, 1);
            lcd.print("*");
            Serial.print(newInput[i]);
            Serial.print(",");
        }
      
        
        if (i == 3) {
            Serial.println(""); 
        }
    }
}



void newPassword() {
    Serial.println("new Password matching...");
    wrong = 0;
    
    for (j = 0; j < 4; j++) {
        if (input[j] == newInput[j]) {
        }
        
        else if (input[j] != newInput[j]) {
            wrong += 1;
        }
    }
}


void newPasswordCheck() {
    // 새 비밀번호가 일치하면
    if (wrong == 0) {
        Serial.println("setting new Password...");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("Setting Password...");
        delay(2000);
        n = 1;
    }
    
    else if (wrong != 0) {
        Serial.println("New password is NOT correct");
        lcd.clear();
        lcd.setCursor(0, 0);
        lcd.print("  NOT CORRECT!");
    
        delay(2000);
        n = 0;
        wrong = 0;
    }
}


void setNewPassword() {
    Serial.println("SET NEW PASSWORD");
    
    for (j = 0; j < 4; j++) {
      secretCode[j] = newInput[j];
      Serial.print(newInput[j]);
    }
    
    Serial.println("");
  
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("SET NEW PASSWORD");
  
    delay(2000);

    // 다시 n값 초기화
    n = 0; 
}

 

  

 

 

 

 

만두