LAINO의 개발노트

아두이노 피에조 부저를 활용한 노래 연주하기 본문

임베디드 , ARM, 아두이노/프로젝트

아두이노 피에조 부저를 활용한 노래 연주하기

Laino 2017. 9. 11. 23:24

 

피에조 부저의 사진이다

 

깃허브 주소 https://github.com/podcastm1/ArduinoTTanTTaRa

 

정말 오랜만에 올리는 글 같습니다.
너무 바쁘기도 했고, 제가 관리를 소홀히 한 문제도 있는것 같습니다.
각설하고 오늘은 피에조 부저를 이용한 노래연주하는 프로젝트를 해볼까 합니다.

 

아두이노를 이용한 피에조 부저를 이용한 뮤즈의 스노하레이션 연주입니다.

 

피에조 부저의 능동 소자를 이용해서 아두이노에서 간단한 멜로디 (부저음) 들을 표현 할 수 있는데요 이를 응용하여 노래를 연주해보겠습니다.

 

먼저 기본적으로 http://www.hardcopyworld.com/gnuboard5/bbs/board.php?bo_table=tech_etc&wr_id=140를 참고해 기본적인 피에조 부저의 메커니즘과 소스를 이해합니다.

 

다음은 저 소스를 기반으로 한 제 소스입니다.

 

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
/*************************************************
 * Public Constants
 *************************************************/
#include "pitches.h"
#define melodyPin 6
 
unsigned long prevPlayTime = 0;
unsigned long playDuration = 0;
long currentMelody = 0;
 
//Mario main theme melody
int melodySize = 750;
unsigned long melody[] = {
  NOTE_A4, NOTE_E5, NOTE_E6, NOTE_CS6, NOTE_B6, NOTE_GS6, NOTE_A6, NOTE_A6,
  00000, NOTE_A6, NOTE_GS6, NOTE_A6,
  NOTE_GS6, NOTE_FS6, NOTE_E6, NOTE_E6,
  NOTE_GS6, NOTE_B6,
  NOTE_A6, 0, NOTE_A6, NOTE_GS6, NOTE_A6,
  NOTE_CS7, NOTE_A6, NOTE_GS6,NOTE_GS6, NOTE_E6,
  NOTE_FS6, NOTE_CS7, NOTE_CS7, NOTE_A6, NOTE_FS6, NOTE_CS6,
  NOTE_A5, NOTE_E7,
  //END 전주
  NOTE_E6, NOTE_FS6, NOTE_E6, NOTE_E6, NOTE_FS6, NOTE_E6,
  NOTE_B5, NOTE_CS6, NOTE_B5, NOTE_A5,
  NOTE_B5, NOTE_CS6, NOTE_CS6, NOTE_CS6,
  0, NOTE_A6,NOTE_GS6, NOTE_E6,NOTE_E6,NOTE_D6, NOTE_CS6, NOTE_CS6,
  NOTE_CS6, NOTE_D6, NOTE_A5, NOTE_A5, NOTE_D6, NOTE_CS6,
  NOTE_CS6, NOTE_A5, NOTE_GS5, NOTE_GS5, NOTE_A5, NOTE_B5,
  NOTE_B5, NOTE_GS5, NOTE_GS5, NOTE_E5, NOTE_GS5, NOTE_B5,
  NOTE_D6, NOTE_D6, 0 , NOTE_E6,NOTE_E6,0,
  //2장 도돌이표
  NOTE_E6, NOTE_FS6, NOTE_E6, NOTE_E6, NOTE_FS6, NOTE_E6,
  NOTE_E6, NOTE_CS6, NOTE_E6, NOTE_B5, NOTE_B5, NOTE_A5,
  NOTE_B5, NOTE_E6, NOTE_FS6, NOTE_A5,
  0, NOTE_A6, NOTE_GS6, NOTE_GS6, NOTE_E6,//1줄
  NOTE_A5,NOTE_A5,NOTE_A5,NOTE_A5,NOTE_D6,NOTE_D6,
  NOTE_E6,NOTE_A5,NOTE_B5,NOTE_B5,NOTE_FS5,NOTE_A5,NOTE_D5,NOTE_A5,
  NOTE_A5,NOTE_CS5,//2
  
  NOTE_FS5,NOTE_D6,NOTE_FS6,NOTE_D6,NOTE_GS6,
  //NOTE_GS5,NOTE_E5,NOTE_E5,NOTE_GS5,
  NOTE_GS5,NOTE_E6,NOTE_GS6,NOTE_E6,NOTE_B6,
  NOTE_B6,NOTE_A6,NOTE_GS6,NOTE_A6,NOTE_GS6,NOTE_E6,NOTE_B5,NOTE_GS5,//3
  
  NOTE_FS6,NOTE_D6,NOTE_FS6,NOTE_A6,
  NOTE_GS6,NOTE_A6,NOTE_GS6,NOTE_GS6,
  NOTE_FS6,NOTE_D6,NOTE_FS6,NOTE_A6,
  NOTE_B6,NOTE_E6,NOTE_E6,//4
  
  NOTE_FS6,NOTE_D6,NOTE_FS6,NOTE_A6,NOTE_A6,
  0,NOTE_FS6,NOTE_GS6,NOTE_GS6,NOTE_A6,NOTE_B6,
  NOTE_E7,0,NOTE_E7,0,NOTE_E7,NOTE_CS7,NOTE_D7,NOTE_DS7,
  NOTE_CS7,0,NOTE_A6,
  NOTE_C8,NOTE_B7,NOTE_A7,NOTE_G7,NOTE_F7,NOTE_E7,NOTE_D7,
  NOTE_C7,NOTE_B6,NOTE_A6,NOTE_G6,NOTE_F6,NOTE_E6
  };
//Snow halation main them tempo
unsigned long tempo[] = {
   888 ,848 ,82,
   8 ,8 ,8 ,8 ,8 ,888,
   488 ,2,
   22,
   28 ,8 ,8 ,8,
   48 , 88 ,3,
   38 ,8 ,8 ,8 ,8,
   1,
   1,
   //전주
   4,8,8,4,8,4,
   4,4,4,4,
   4,8,8,2,
   8,8,8,88,8,8,8,
   4,8,8,8,4,8,
   4,8,8,8,4,8,
   2,8,8,8,8,8,
   8,8,4,8,8,4,
   //2장 도돌이표
   4,8,8,4,8,8,
   4,4,8,4,3,4,
   4,4,4,4,
   8,4,8,8,3//1줄
   
   4,8,8,8,4,8,
   4,8,8,8,4,8,
   1,1,//2
   
   4,4,4,8,8,
  // 3,8,8,3,
   4,4,4,8,8,
   8,8,8,8,8,8,8,8,//3
   
   4,4,4,4,
   4,8,8,2,
   4,4,4,4,
   4,8,1.5,//4
   
   4,4,4,8,8,
   8,4,8,8,4,8,
   8,8,8,8,8,8,8,8,
   4,4,8,
   28,28,28,28,28,28,28,
   28,28,28,28,28,28//휘익
};
 
 
void sing() {
    if(millis() < prevPlayTime + playDuration) {
        // music is playing. do nothing
        return;
    }
    // stop the tone playing:
    noTone(8);
 
    if(currentMelody >= melodySize)
        currentMelody = 0;
    // to calculate the note duration, take one second
    // divided by the note type.
    //e.g. quarter note = 1000 / 4, eighth note = 1000/8, etc.
    int noteDuration = 1000/tempo[currentMelody];
 
    tone(melodyPin, melody[currentMelody], noteDuration);
    prevPlayTime = millis();
    playDuration = noteDuration * 1.30;
 
    currentMelody++;
}
 
 
 
void setup() {
  pinMode(melodyPin, OUTPUT);
}
 
void loop() {
  // Do what you want
 
  // play music
  sing();
}
cs

 

처음 부분부터 첫 하이라이트 직전까지 구현 했습니다. 깃허브에 올려두고 오다가다 청음하고 커밋해야겠습니다.

PR 요청은 환영합니다!

 

추후 음이랑 음표을 헤더파일쪽으로 따로 분리하여 둘 생각입니다.

 

PS. 짜면서 안건데 생각보다 소스 용량이 매우 큽니다 전곡 다 못들어갈거같아서 다음 포스팅때는 SD카드 모듈을 사용하는 방안으로 소스를 수정해보도록 하겠습니다.


2019-6-16 추가

왜 지금생각하면 이런 오타쿠같은 곡을 골랐는지 모르겠다 끙 ㅡㅡ; 그당시 피아노가 좋아서 했는데 골랐는데 흠

Comments