[매드] 아두이노 강좌 - 33. 라면 타이머 만들기

안녕하세요~ 매드 입니다.
주에 1회만 하는데도 이게 의외로 부담이 되네요 ㅠㅠ
기존에 하던 컨텐츠가 다 떨어지기도 했고 고급 강좌로 진행할려니 1시간이라는 시간에 무언가 만들어 내는 것이 저한테 부담되기도 하네요 ㅠ

그래도!! 한번 갈때까지 가보겠습니다. 상상으로 만들어내는건 무한하니까요! 하하;;
이번에는 이전에 했던걸로 라면 타이머 한번 만들어 봤습니다.

만들기는 했는데 ... 막상써보니 효용성은 좀 떨어지네요 ㅠ


33-1. 타이머

<타이머(출처:구글사진)>

맙소사. 맞습니다. 그냥 타이머 입니다. 이번 시간에 만드는건 사실 그냥 타이머 입니다. 이전에 했던 CLCD와 펌웨어를 이용하여 타이머를 만드는 것이죠!

ㅠㅠ 여기서 명언 하나 되세기고 가도록 하겠습니다.

'세상에 이미 있는건 만들어진걸 사는게 정신건강에 좋다 ㅠ'

ㅋㅋ 진리입니다. 이미 있는건 만들어진걸 사세요... 정신건강이나 돈, 시간 다 따져도 이득입니다.

저희가 만드는건 START 버튼, STOP 버튼만 있고 업카운트를 통해 특정 시간이 되면 비프음이 울리는 동작이 되겟네요.


32-2. 하드웨어 연결

<keypad shield(출처:구글사진)>

하드웨어 연결은 단순합니다. keypad shield를 아두이노 우노와 결합해주시면 됩니다!


<keypad shield(출처:구글사진)>


아두이노 우노에 keypad 쉴드를 장착하면 몇가지 핀을 사용하지 못하는데요. 위에 보시면 키패드 쉴드에서 남아있는 핀을 사용할 수 있습니다.

13,12,11,3,2,1,0 이렇게 핀을 사용할 수 있게되어있네요!

그중에 부져는 11번핀에 연결해서 사용해 보도록 하겠습니다. 액티브,패시브 부저 다 상관 없을 것 같네요. 액티브면 PWM 넣어서 소리만들면 되고 패시브면 HIGH 신호만을 통해서 삐~~ 소리가 나오도록 하면 되니까요~ ㅎㅎ

부저는 11번 핀과 GND를 묶어서 만듭니다. ㅎ

이후에는 펌웨어 강좌를 확인하시고 아래 코드를 긁어서 쓰시면 될 것 같네요!

MsTimer2 라이브러리를 사용하는 점 잊지 마시기를 바랍니다~



33-3. 펌웨어

- 멜로디 없는 것

#include <LiquidCrystal.h>
#include <MsTimer2.h>

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

unsigned int sec = 0;
unsigned char select_flag = 0;


// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;

  return btnNONE;  // when all others fail, return this...
}

void ramen_time()
{
  if( select_flag ) {
    sec++;
  }
  else {
    sec = 0;
  }
}

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);              // start the library
  MsTimer2::set(1000, ramen_time); // 1s timer
  MsTimer2::start();
}

void loop()
{
  lcd.setCursor(0, 0);
  lcd.print("RAMEN TIMER"); // print a simple message
  lcd.setCursor(0, 1);           // move to the begining of the second line
  lcd.print(sec / 60); // min
  lcd.setCursor(2, 1);
  lcd.print(":");
  lcd.setCursor(3, 1);
  lcd.print(sec % 60); // sec
  lcd_key = read_LCD_buttons();  // read the buttons

  switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
    case btnRIGHT:
      {
        break;
      }
    case btnLEFT:
      {
        break;
      }
    case btnUP:
      {
        break;
      }
    case btnDOWN:
      {
        break;
      }
    case btnSELECT:
      {
        select_flag = !select_flag;
        break;
      }
    case btnNONE:
      {
        break;
      }
  }
  delay(100);
  lcd.clear();
}


- 부져 추가

#include <LiquidCrystal.h>
#include <MsTimer2.h>
#include "pitches.h"

LiquidCrystal lcd(8, 9, 4, 5, 6, 7);

const char BUZZER = 11;

int melody[] = {
  NOTE_C4, NOTE_G3, NOTE_G3, NOTE_A3, NOTE_G3, 0, NOTE_B3, NOTE_C4
};
// note durations: 4 = quarter note, 8 = eighth note, etc.:
int noteDurations[] = {
  4, 8, 8, 4, 4, 4, 4, 4
};

int lcd_key     = 0;
int adc_key_in  = 0;
#define btnRIGHT  0
#define btnUP     1
#define btnDOWN   2
#define btnLEFT   3
#define btnSELECT 4
#define btnNONE   5

unsigned int sec = 0;
unsigned char select_flag = 0;


// read the buttons
int read_LCD_buttons()
{
  adc_key_in = analogRead(0);      // read the value from the sensor
  // my buttons when read are centered at these valies: 0, 144, 329, 504, 741
  // we add approx 50 to those values and check to see if we are close
  if (adc_key_in > 1000) return btnNONE; // We make this the 1st option for speed reasons since it will be the most likely result
  // For V1.1 us this threshold
  if (adc_key_in < 50)   return btnRIGHT;
  if (adc_key_in < 250)  return btnUP;
  if (adc_key_in < 450)  return btnDOWN;
  if (adc_key_in < 650)  return btnLEFT;
  if (adc_key_in < 850)  return btnSELECT;

  return btnNONE;  // when all others fail, return this...
}

void ramen_time()
{
  if ( select_flag ) {
    sec++;
  }
  else {
    sec = 0;
  }
}

void setup()
{
  Serial.begin(9600);
  lcd.begin(16, 2);              // start the library
  MsTimer2::set(1000, ramen_time); // 1s timer
  MsTimer2::start();
}

void loop()
{
  lcd.setCursor(0, 0);
  lcd.print("RAMEN TIMER"); // print a simple message
  lcd.setCursor(0, 1);           // move to the begining of the second line
  lcd.print(sec / 60); // min
  lcd.setCursor(2, 1);
  lcd.print(":");
  lcd.setCursor(3, 1);
  lcd.print(sec % 60); // sec
  lcd_key = read_LCD_buttons();  // read the buttons

  if( sec >= 240 ) {
    for (int thisNote = 0; thisNote < 8; thisNote++) {
      lcd_key = read_LCD_buttons();  // read the buttons

      int noteDuration = 1000 / noteDurations[thisNote];
      tone(BUZZER, melody[thisNote], noteDuration);

      int pauseBetweenNotes = noteDuration * 1.30;
      delay(pauseBetweenNotes);
      // stop the tone playing:
      noTone(BUZZER);
    }
  }

  switch (lcd_key)               // depending on which button was pushed, we perform an action
  {
    case btnRIGHT:
      {
        break;
      }
    case btnLEFT:
      {
        break;
      }
    case btnUP:
      {
        select_flag = 0;
        break;
      }
    case btnDOWN:
      {
        break;
      }
    case btnSELECT:
      {
        select_flag = 1;
        break;
      }
    case btnNONE:
      {
        break;
      }
  }

  delay(200);
  lcd.clear();
}






다음 시간에는 페북으로 한번 요청왔던 건인데 물체를 만져서 소리내는 걸 만들어 보도록 하겠습니다.

기획 없이 그냥 막 만드니까 완성도 떨어지는 제품들이 나오네요 ㅠㅠ 힝
일단은 이대로 몇번더 해보고 잘안되면 기획부터 작업해서 좀 더 완성도 높은 제품을 만들어봐야겠네요!!

그럼 다음 주에 뵐께요~~

댓글 쓰기

0 댓글