재료

  • 캐릭보드 싱글박스 1개

오늘은 캐릭보드의 지난 실습을 응용하여, 점심시간이 되면 캐릭터가 배고프다는 알람을 울리고 다른 캐릭터가 신호를 맞받아 함께 알람을 울리는 캐릭보드를 만들어보겠습니다.

두 가지 캐릭터가 필요하겠지요?

저는 한 캐릭터는 대한이, 다른 캐릭터는 아빠로 정했습니다.

점심시간을 설정하고 점심시간이 되면 대한이가 '대한이 배고파!'라고 외칩니다.

신호를 들은 아빠는 '아빠도 배고파!'라고 응답하고 함께 빛을 내며 바나나송을 부릅니다.

만약 회사나 학교에 이런 알람 캐릭터를 두면 점심시간 땡!과 동시에 맛난 밥을 먹으러 나갈 수 있겠죠?


준비물

캐릭보드, 아두이노 나노, 아두이노 나노 케이블, RTC모듈, 적외선 발신부(대한이), 적외선 수신부(아빠), 네오픽셀, MP3모듈, 스피커, 스탠드, 캐릭터 (캐릭보드 구성 보러가기)


0. 자신만의 알람소리 만들기

두 캐릭터 모두 알람소리가 필요합니다. 기존에 있던 것을 사용하셔도 좋습니다.

저는 저만의 배꼽시계 알람을 위하여 유튜브에서 다음 동영상을 이용했습니다.

대한이는 '대한이 배고파' 아빠는 '아빠도 배고파'를 알람소리로 이용합니다.


유튜브의 음원을 MP3파일로 추출하고, MP3파일을 간단히 편집하는 과정은 각각 웹사이트에서 진행할 수 있습니다.

링크를 통해 들어가서 자신만의 간단한 알람소리를 만들어보세요!


1. SD카드에 알람소리 넣기

sd카드에 자신의 알람 음원을 넣어주세요.

1) 먼저 sd카드를 리더기에 꼽고 컴퓨터에 연결합니다.



2) mp3폴더 안에 자신의 알람소리를 넣습니다.



3) 제목은 000#Title 형식으로 설정합니다. ex) 0009대한이배고파.mp3



2. 캐릭보드 모듈 연결하기

대한이에는 적외선 발신부, 아빠에는 적외선 수신부를 연결해야합니다.

나머지 스피커, 네오픽셀 등의 모듈은 매뉴얼 마지막 부분의 회로도를 참고하세요!

1) 대한이의 적외선 발신부


요렇게 연결을 완료한 대한이입니다.




2) 아빠의 적외선 수신부


연결을 완료한 아빠입니다!




3. 아두이노 코드 업로드하기

코드는 자신이 하고 싶은대로 변경해서 사용하면 됩니다.

저는 대한이 코드를 업로드하면 오늘의 점심시간을 'a201707141230'과 같은 형식으로 입력하도록 했습니다. 그러면 아빠 코드를 업로드하고 점심시간이 되면 대한이와 아빠가 보라색 빛을 내면서 배고파 알람을 울리게 됩니다.


두 캐릭터를 컴퓨터에 연결합니다.


1) 대한이 코드

대한이 캐릭터에 다음 코드를 업로드하고 시리얼 창에서 오늘의 점심시간을 입력합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#include <Time.h>
#include <TimeLib.h>
#include <Wire.h>
#include <DS1307RTC.h>
#include <DFPlayer_Mini_Mp3.h>
#include <IRremote.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
 
SoftwareSerial mp3Serial(12,13);
 
#define neopixelPIN 6
Adafruit_NeoPixel strip=Adafruit_NeoPixel(5,neopixelPIN,NEO_GRB+NEO_KHZ800);
IRsend irsend;
 
int RECV_PIN = 11;
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean checkIR = false;
int threetimes=0;
 
 
int red;
int green;
int blue;
 
String inputString="";
boolean stringComplete=false;
boolean stringYear=false;
String input_year="";
String input_month="";
String input_day="";
String input_hour="";
String input_min="";
 
int year_int=0;
int month_int=0;
int day_int=0;
int hour_int=0;
int min_int=0;
 
tmElements_t tm;
 
void setup(){
  Serial.begin(9600);
  strip.begin();
  mp3Serial.begin(9600);
  mp3_set_serial(mp3Serial);
  delay(1);
  mp3_set_volume(20);
}
void loop() {
 
  if (Serial.available() > 0) {
    inputString = Serial.readString();
    if (inputString.charAt(0== 'a') {
      Serial.println("Time Setting");
      timeConverter();
    }
  }
 
  if (RTC.read(tm)) {
    //시간 출력하기 (시리얼창)
    Serial.print("computer : ");
    Serial.print(tmYearToCalendar(tm.Year));
    Serial.print("/");
    Serial.print(tm.Month);
    Serial.print("/");
    Serial.print(tm.Day);
    Serial.print("  ");
    Serial.print(tm.Hour);
    Serial.print(":");
    Serial.print(tm.Minute);
    Serial.println();
    delay(500);
    //알람시간체크하기
    if (tmYearToCalendar(tm.Year) == year_int && tm.Month == month_int 
&& tm.Day == day_int && tm.Hour == hour_int && tm.Minute == min_int && threetimes<=2) {
      Serial.println("배고파요!!");
      //rainbow();
      //lightChase(strip.Color(red, green, blue));
      red=255; green=0; blue=255;
      for (int i = 0; i < 5; i++) { //불 켜기
        strip.setPixelColor(i, strip.Color(red, green, blue));
        strip.show();
      }
      mp3Serial.listen();
      if (mp3Serial.isListening()) { //소리켜기
        Serial.println("Play 9");
        mp3_play(9);
        delay (5000);
        mp3_stop();
        threetimes += 1;
      }
      sendIR(0xc);
      for (int i = 0; i < 5; i++) { //불 끄기
        strip.setPixelColor(i, strip.Color(000));
        strip.show();
      }
    }
    else { //설정한 시간이 아닐 때, 불 끄기
      for (int i = 0; i < 5; i++) { //불 끄기
        strip.setPixelColor(i, strip.Color(000));
        strip.show();
      }
    }
  }
  if(threetimes==3)
  {
    red=255; green=0; blue=255;
      for (int i = 0; i < 5; i++) { //불 켜기
        strip.setPixelColor(i, strip.Color(red, green, blue));
        strip.show();
      }
      mp3Serial.listen();
      if (mp3Serial.isListening()) { //소리켜기
        delay(2000);
        Serial.println("Play 1");
        mp3_play(1);
        delay (7000);
        mp3_stop();
        threetimes += 1;
      }
  }
}
 
//Data Check---------------------------------------------------------------
void timeConverter() { //읽어온 데이터를 알람시간으로 바꾸기
  //serial input to char
  Serial.print("Set Alarm Time : ");
  input_year = inputString.substring(15);
  Serial.print(input_year);
  Serial.print("/");
  input_month = inputString.substring(57);
  Serial.print(input_month);
  Serial.print("/");
  input_day = inputString.substring(79);
  Serial.print(input_day);
  Serial.print("   ");
  input_hour = inputString.substring(911);
  Serial.print(input_hour);
  Serial.print(":");
  input_min = inputString.substring(1113);
  Serial.println(input_min);
  //to int
  year_int = input_year.toInt();
  month_int = input_month.toInt();
  day_int = input_day.toInt();
  hour_int = input_hour.toInt();
  min_int = input_min.toInt();
}
void sendIR(int hex) {
  for(int i=0;i<3;i++){
    irsend.sendSony(hex,20);
    delay(100);
    }
    delay(500);
    Serial.println("IR has been sent");
    Serial.println(hex,HEX);
    irrecv.enableIRIn();
}
cs



2) 아빠 코드

적외선 신호를 받아서 빛을 내고 알람을 울리는 코드입니다. 아빠 캐릭보드에 업로드합니다. 포트를 아빠 캐릭터에 맞는 포트로 변경하고 업로드합니다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
#define PIN 6
#include <SoftwareSerial.h>
#include <DFPlayer_Mini_Mp3.h>
#include <IRremote.h>
#include <Adafruit_NeoPixel.h>
#ifdef __AVR__
#include <avr/power.h>
#endif
 
SoftwareSerial mp3Serial(1213);
Adafruit_NeoPixel strip=Adafruit_NeoPixel(5,PIN,NEO_GRB+NEO_KHZ800);
 
int red;
int green;
int blue;
int threetimes=0;
 
//IR
int RECV_PIN=11;
IRrecv irrecv(RECV_PIN);
decode_results results;
boolean checkIR = false;
 
void setup(){
  Serial.begin(9600);
  mp3Serial.begin(9600);
  mp3_set_serial(mp3Serial);
  delay(1);
  mp3_set_volume(20);
  irrecv.enableIRIn();
  strip.begin();
  for(int i=0;i<5;i++){//불을 끈다
          strip.setPixelColor(i,strip.Color(0,0,0));
          strip.show();
      }
  Serial.println("Set up...");
}
void loop() {
  if(receiveIR(0xc)==true){//0xc 신호를 받으면
    for(int i=0;i<5;i++){
      strip.setPixelColor(i,strip.Color(255,0,255));
      strip.show();
      }
      mp3Serial.listen();
      if(mp3Serial.isListening()){
        Serial.println("Play 9");
        mp3_play(9);
        delay(5000);
        mp3_stop();
        }
      for(int i=0;i<5;i++){//불을 끈다
          strip.setPixelColor(i,strip.Color(0,0,0));
          strip.show();
      }
      threetimes+=1;
  }
  if(threetimes==3){
    red=255; green=0; blue=255;
      for (int i = 0; i < 5; i++) { //불 켜기
        strip.setPixelColor(i, strip.Color(red, green, blue));
        strip.show();
      }
      mp3Serial.listen();
      if (mp3Serial.isListening()) { //소리켜기
        Serial.println("Play 1");
        mp3_play(1);
        delay (7000);
        mp3_stop();
        threetimes += 1;
      }
  }
}
boolean receiveIR(int hex){
  checkIR=false;
  if(irrecv.decode(&results)){
    Serial.print("Result.value = ");
    Serial.println(results.value);
    Serial.print("HEX = ");
    Serial.println(HEX);
    if(results.value==hex){
      Serial.println("Me, too");
      checkIR=true;
      }
      irrecv.resume();
      }
      delay(30);
      return checkIR;
}
cs



4. 실행 확인해보기

이제 캐릭보드에서 제대로 작동하는지 확인해봅시다.

저는 안타깝게도 아빠의 스피커 모듈이 제대로 되지 않아서 예상과 같은 결과를 얻지는 못하였습니다. 비디오를 반복해서 찍어보았지만 여러 모듈이 돌아가면서 오작동(;;)을 하는 바람에 가장 최선의 결과는 첨부한 동영상과 같습니다..

원래는 함께 바나나송을 부르는데 아빠에 오류가 나서 대한이만 부릅니다ㅠ.ㅠ

하지만 성공 케이스가 있었으므로 문제가 있는 코드는 아니었던 것 같은데, 여러분은 어떠셨나요?



캐릭보드를 응용해서 더욱 다양한 기능들을 구현해볼 수 있을것 같습니다.

다음 스토리에서 만나요!

댓글 0

MADE BY

10. 점심시간을 알리는 캐릭터들현재글 9. 앱으로 컨트롤하기(4) - 대화하기 이전글