프로젝트

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

아두이노 전화번호부를 만들어 봅시다.

2015-01-07 11:13:57

개요 및 부품 목록


어렷을 적 밑의 사진과 같은 전화번호부를 많이 보았습니다. 최근에는 스마트폰이 많이 보급이 되어서 스마트폰에 저장해 놓고 많이 쓰면서 전화번호부가 사라졌는데요,

옛 추억을 살려볼 겸 직접 전화번호부를 만들어보는 것은 어떤가요? 아두이노를 이용하여 자신만의 멋있는 전화번호부를 기획해 보세요.


이번 컨텐츠에서는 아두이노를 이용하여 간단한 전화번호부를 만들어 보겠습니다. SD카드를 연결하여 이름과 전화번호 등을 저장하고, 전원 버튼을 붙여서 원할때만 켜고 끌수 있도록, 또 버튼을 이용하여 직접 번호를 입력 / 저장 할수 있도록 하겠습니다.

시작전 개념 이해하기

부품 목록

NO 부품명 수량 상세설명
1 오렌지보드 1  아두이노 
2 LCD  16X2 LCD
3 SD카드  SD카드 모듈 추가
4 Push button  상태 유지 버튼 
5 택트 스위치 4  버튼 
6 Power plug  Arduino Power plug adapter cable
7 가변저항 10KΩ 가변저항 
8 10KΩ저항 저항 
9 브레드보드 브레드보드 
10 점퍼케이블  49 점퍼케이블 

부품명 오렌지보드 LCD SD카드 모듈 Push button 택트 스위치
파트
부품명 Power plug  가변저항 10KΩ저항 브레드보드 점퍼케이블
파트

하드웨어 Making 및 소프트웨어 Coding

회로도


브레드보드 레이아웃




하드웨어 만들기


1. 사진과 같이 박스를 LCD크기만큼 잘라 줍니다. 자른 부위에 LCD를 끼우면 고정이 됩니다.(골판지 박스 같은 것을 이용하실 경우 LCD를 끼울때 찢어지지 않도록 테이프를 붙여줍니다.)
   (고정이 안될경우 안쪽에서 테이프 같은 것으로 고정시켜 줍니다.)


2. 버튼은 선만 넣을 수 있을 정도로 박스를 자르고 선을 넣은 후, 순간접착제 같은 것으로 붙여 줍니다.
  (버튼을 붙인 후 각 버튼이 어떤 기능을 하는지 적어 주시면 사용하실 때 편합니다.)

  UP버튼은 A0번, Down버튼은 A1번, 한칸 앞으로 넘기는 버튼은 A4번, Edit / Save 버튼은 A5번 입니다.



3. 그 다음 전원을 연결할 Power plug가 나올만큼 박스를 자른 후 Power plug를 안쪽에서 고정시켜 줍니다.



4. 마지막으로 안에서 선을 연결 하신 후 Power plug와 연결된 버튼을 밖으로 빼줍니다.
   좁은 박스 안에서 선을 연결하실려면 불편하니 LCD나 버튼에 선을 연결하실 때 충분한 길이의 선을 연결하셔서 박스 밖에서 선을 연결 후 넣으시면 편합니다.


5. 박스를 닫고 외형을 깔끔하게 마무리 하시면 완성됩니다.


소프트웨어 코딩

//Arduino Phone book v1.0 - By Gigi Butbaia
#include <LiquidCrystal.h>
#include <SD.h>

LiquidCrystal lcd(7, 6, 5, 4, 3, 2); // Define lcd

int bUp = A0;  // Define Up Button
int bDown = A1; // Define Down Button
int bLeft = A4; // Define Left Button
int bEdit = A5; // edit/save button

boolean editMode = false; // Edit Mode, activated when clicked edit Button

File data; // File where all data is stored


void setup() 
{
  //Configure LCD
  lcd.begin(16, 2); // Configure lcd as 8x2
  lcd.clear(); // Clear display
  
  //Create Buttons
  pinMode(bUp, INPUT); // Up Button
  pinMode(bDown, INPUT); // Down Button
  pinMode(bLeft, INPUT); // Left Button
  //pinMode(bright, INPUT);
  
  pinMode(bEdit, INPUT); // Edit/Save Button
  
  pinMode(10, OUTPUT);
  
  if(!SD.begin(10))
  {
    lcd.print("Error:");
    lcd.setCursor(0,1);
    lcd.print("SD Card");
    while(1); //todo edit
  }
  //data = SD.open("data.txt", FILE_WRITE);
  //data.println("TEST, SD CARD");
  //data.close();
  lcd.setCursor(0,0);
  lcd.print("Welcome");
  delay(2000);
  lcd.clear();
  
  data = SD.open("0.txt");
  String dat = "";

  while(data.available())
  {
    dat += char(data.read());
  }
  data.close();
      
  if(dat != ":")
  {
    lcd.setCursor(0,0);
    lcd.print(getValue(dat, ':', 0));
    lcd.setCursor(0, 1);
    lcd.print(getValue(dat, ':', 1));
    lcd.setCursor(0,0);
  }
  
}

//index
int i = 0;

//Text
int b = 0;

//Cursor Pos
int xcpos = 2; // xcpos - x cursor pos
int xcpos2 = 0;

//Configure Buttons
int previousbUp = LOW;
int previousbDown = LOW;
int previousbLeft = LOW;

int previousbEdit = LOW;

//Create Array of characters
char abc[54] = " ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz";
char num[12] = " 0123456789";

//Define two Strings for name and number
String theData;
String theNum;

//Number and data will be stored in this string
String fullData;

//Define boolean to check if we are writing name or number
boolean name = true;

//Define int for screen position
int scrpos = 0;
void loop() 
{
 
  //Check if we are in editMode
  if(!editMode)
  {
    lcd.setCursor(0,0);
    if(digitalRead(bUp) == HIGH && previousbUp == LOW)
    {
      scrpos = 0;
      lcd.clear();
      i++;
      lcd.print(i);
      lcd.setCursor(2, 0);
      
      //Convert int to char*
      char index[20];
      String s = String(i) + ".txt";
      s.toCharArray(index, 20);
      
      data = SD.open(index);
      
      String dat = "";
      
      while(data.available())
      {
        dat += char(data.read());
      }
      data.close();
      
      if(dat != ":")
      {
        lcd.print(getValue(dat, ':', 0));
        lcd.setCursor(0, 1);
        lcd.print(getValue(dat, ':', 1));
        lcd.setCursor(0,0);
      }
      
      previousbUp = HIGH;
    }
    else if(digitalRead(bUp) == LOW && previousbUp == HIGH)
    {
      previousbUp = LOW;
    }
    
    if(digitalRead(bDown) == HIGH && previousbDown == LOW)
    {
      scrpos = 0;
      lcd.clear();
      i--;
      lcd.print(i);
      lcd.setCursor(2, 0);
      
      //Convert int to char*
      char index[20];
      String s = String(i) + ".txt";
      s.toCharArray(index, 20);
      
      data = SD.open(index);
      
      String dat = "";
      
      while(data.available())
      {
        dat += char(data.read());
      }
      data.close();
      
      if(dat != ":")
      {
        lcd.print(getValue(dat, ':', 0));
        lcd.setCursor(0,1);
        lcd.print(getValue(dat, ':', 1));
        lcd.setCursor(0,0);
      }
      previousbDown = HIGH;
    }
    else if(digitalRead(bDown) == LOW && previousbDown == HIGH)
    {
      previousbDown = LOW;
    }
    
    if(digitalRead(bLeft) == HIGH && previousbLeft == LOW)
    {
      scrpos++;
      lcd.scrollDisplayLeft();
      if(scrpos > 3)
      {
        for(int i = 0; i < scrpos; i++)
        {
          lcd.scrollDisplayRight();
        }
        scrpos = 0;
      }
      previousbLeft = HIGH;
    }
    else if(digitalRead(bLeft) == LOW && previousbLeft == HIGH)
    {
      previousbLeft = LOW;
    }
    
    if(digitalRead(bEdit) == HIGH && previousbEdit == LOW)
    {
      lcd.clear();
      lcd.print("Edit");
      lcd.setCursor(0,1);
      lcd.print("Mode");
      
      char index[20];
      String s = String(i) + ".txt";
      s.toCharArray(index, 20);
      
      SD.remove(index);
      
      delay(2000);
      lcd.clear();
      lcd.print(i);
      lcd.cursor();
      previousbEdit = HIGH;
      lcd.setCursor(2,0);
      editMode = true;
    }
    else if(digitalRead(bEdit) == LOW && previousbEdit == HIGH)
    {
      previousbEdit = LOW;
    }
  }
  if(editMode)
  {
    //lcd.setCursor(xcpos, 0);
    
    if(!(xcpos > 15))
    {
      lcd.setCursor(xcpos, 0);
      name = true;
    }
    else
    {
      lcd.setCursor(xcpos2, 1);
      name = false;
      /*if(xcpos2 > 7)
      {
        name = true;
        xcpos = 2;
        xcpos2 = 0;
      }*/
    }
    
    if(digitalRead(bUp) == HIGH && previousbUp == LOW)
    {
      b++;
      if(name)
      {
        if(b > 52)
        {
          b = 0;
        }
        else if(b < 0)
        {
          b = 52;
        }
        lcd.print(abc[b]);
      }
      else
      {
        if(b > 10)
        {
          b = 0;
        }
        else if(b < 0)
        {
          b = 10;
        }
        lcd.print(num[b]);
      }
      previousbUp = HIGH;
    }
    else if(digitalRead(bUp) == LOW && previousbUp == HIGH)
    {
      previousbUp = LOW;
    }
    
    if(digitalRead(bDown) == HIGH && previousbDown == LOW)
    {
      b--;
      if(name)
      {
        if(b > 52)
        {
          b = 0;
        }
        else if(b < 0)
        {
          b = 52;
        }      
        lcd.print(abc[b]);
      }
      else
      {
        if(b > 10)
        {
          b = 0;
        }
        else if(b < 0)
        {
          b = 10;
        }
        lcd.print(num[b]);
      }
      previousbDown = HIGH;
    }
    else if(digitalRead(bDown) == LOW && previousbDown == HIGH)
    {
      previousbDown = LOW;
    }
    
    if(digitalRead(bEdit) == HIGH && previousbEdit == LOW)
    {
      lcd.clear();
      lcd.println("Saving..");
      
      char index[20];
      String s = String(i) + ".txt";
      s.toCharArray(index, 20);
      
      data = SD.open(index, FILE_WRITE);
      
      fullData = theData + ":" + theNum;
      
      data.print(fullData);
      data.close();
      delay(1200);
      
      lcd.clear();
      i = 0;
      lcd.setCursor(0,0);
      lcd.print("0");
      
      data = SD.open("0.txt");
      lcd.setCursor(2, 0);
      
      String dat = "";
      
      while(data.available())
      {
        dat += char(data.read());
      }
      data.close();
      
      if(dat != ":")
      {
        lcd.print(getValue(dat, ':', 0));
        lcd.setCursor(0,1);
        lcd.print(getValue(dat, ':', 1));
        lcd.setCursor(0,0);
      }
      
      previousbEdit = HIGH;
      lcd.noCursor();
      xcpos = 2;
      xcpos2 = 0;
      theData = "";
      theNum = "";
      b=0;
      editMode = false;
      
    }
    else if(digitalRead(bEdit) == LOW && previousbEdit == HIGH)
    {
      previousbEdit = LOW;
    }
    
    if(digitalRead(bLeft) == HIGH && previousbLeft == LOW)
    {
      //lcd.print(xcpos);
      if(name)
      {
        theData += abc[b];
        //lcd.setCursor(0, 1);
      }
      else
      {
        theNum += num[b];
      }
      //lcd.print(theData);
      
      if(!(xcpos > 15))
      {
        xcpos++;
        lcd.setCursor(xcpos, 0);
        name = true;
      }
      else
      {
        xcpos2++;
        lcd.setCursor(xcpos2, 1);
        name = false;
        if(xcpos2 > 15)
        {
          lcd.scrollDisplayLeft();
          //name = true;
          //xcpos = 2;
          //xcpos2 = 0;
        }
      }
      
      b = 0;
      previousbLeft = HIGH;
    }
    else if(digitalRead(bLeft) == LOW && previousbLeft == HIGH)
    {
      previousbLeft = LOW;
    }
  }
}

//Split received string from SD Card, for example data = AAA:BBB, getValue(data, ':', 0) = AAA, getValue(data, ':', 1) = BBB
String getValue(String data, char separator, int index)
{
  int found = 0;
  int strIndex[] = {0, -1};
  int maxIndex = data.length()-1;

  for(int i=0; i<=maxIndex && found<=index; i++){
    if(data.charAt(i)==separator || i==maxIndex){
        found++;
        strIndex[0] = strIndex[1]+1;
        strIndex[1] = (i == maxIndex) ? i+1 : i;
    }
  }

  return found>index ? data.substring(strIndex[0], strIndex[1]) : "";
}


// 출처 : Instructables - Arduino phone book(Butbaia)

소프트웨어 설명

Edit모드에서는 SD카드에 해당 번호를 파일명으로한 txt파일을 만들어 Edit 모드에서 입력한 텍스트를 저장합니다.


LCD화면에 전화번호를 출력하는 것도 마찬가지로 txt파일의 파일명을 가지고 파일의 내용을 불러와서 출력합니다.



if(name)
{
  theData += abc[b]; // 첫번째 줄에서는 알파벳을 입력합니다.
}
else
{
  theNum += num[b]; // 두번째 줄에서는 숫자를 입력합니다.
}
 Edit 모드에서는 LCD 첫번째 줄에는 영어, 두번째 줄에는 숫자만 입력이 됩니다.
 
 입력 방법은 Up버튼을 누르면 알파벳 순서대로 나오고, Down 버튼을 누르면 역순서로 나옵니다. 입력할 문자에 맞춘 후 다음 버튼을 누르면 됩니다. 모두 입력이 되셧으면 다시 Edit 버튼을 눌러주면 저장이 됩니다.
(시작할 때는 바로 Edit모드로 들어가니 0번은 이용하시지 않는것이 좋습니다. 또한 저장된 번호에 새로 입력 하실려면 해당 번호에서 Edit 버튼을 누르시면 전에 있던 데이터를 지우고 새로 저장이 됩니다.)

 if(digitalRead(bUp) == HIGH && previousbUp == LOW)
    {
      scrpos = 0;
      lcd.clear();
      i++;
      lcd.print(i);
      lcd.setCursor(2, 0);
      
      //Convert int to char*
      char index[20];
      String s = String(i) + ".txt";
      s.toCharArray(index, 20);
      
      data = SD.open(index);
      
      String dat = "";
      
      while(data.available())
      {
        dat += char(data.read());
      }
      data.close();
      
      if(dat != ":")
      {
        lcd.print(getValue(dat, ':', 0));
        lcd.setCursor(0, 1);
        lcd.print(getValue(dat, ':', 1));
        lcd.setCursor(0,0);
      }
      
      previousbUp = HIGH;
    }
    else if(digitalRead(bUp) == LOW && previousbUp == HIGH)
    {
      previousbUp = LOW;
    }
    
    if(digitalRead(bDown) == HIGH && previousbDown == LOW)
    {
      scrpos = 0;
      lcd.clear();
      i--;
      lcd.print(i);
      lcd.setCursor(2, 0);
      
      //Convert int to char*
      char index[20];
      String s = String(i) + ".txt";
      s.toCharArray(index, 20);
      
      data = SD.open(index);
      
      String dat = "";
      
      while(data.available())
      {
        dat += char(data.read());
      }
      data.close();
      
      if(dat != ":")
      {
        lcd.print(getValue(dat, ':', 0));
        lcd.setCursor(0,1);
        lcd.print(getValue(dat, ':', 1));
        lcd.setCursor(0,0);
      }
      previousbDown = HIGH;
    }
 일반 모드에서는 Up버튼을 누르면 다음 순서의 전화번호를 LCD에 출력하고, Down버튼을 누르면 전 순서의 전화번호를 LCD에 출력합니다.

 Edit모드에서 저장했던 txt파일을 해당 순서에 맞게 불러와서 해당 내용을 출력합니다.(내용이 없을 경우 현재 순서만 LCD에 출력합니다.)

 일반 모드에서 Edit버튼을 누르면 현재 순서의 Edit모드로 넘어갑니다.


판다마니아

아두이노, 전화번호부, LCD, 버튼, SD카드