[아두이노] 곰세마리멜로디(피에조부저)

IOT/아두이노|2019. 2. 5. 14:32

[아두이노] 곰세마리멜로디(피에조부저)



1. 악보


2. 멜로디 배열변수 만들기

음계+음길이

위의 악보에서 음계랑 음길이를 메모장에서 간단히 표시해 보자.

도도도도도
4 8 8 4 4
미솔솔미도
4 8 8 4 4
솔솔미솔솔미
8 8 4 8 8 4
도도도
4 4 2

솔솔미도
4 4 4 4 
솔솔솔
4 4 2
솔솔미도
4 4 4 4 
솔솔솔
4 4 2

솔솔미도
4 4 4 4
솔솔솔라솔
8 8 8 8 2
도솔도솔
4 4 4 4
미레도
4 4 2

5옥타브음계

5옥타브 음계 도레미파솔라시도 이것만 이용 합니다.

5옥타브 음계에서 벗어난 음계를 사용할 경우 위 사이트 가셔서 다른 옥타브 음계를 참조하셔서 사용하시면 됩니다. 귀찮은 분들은 전음계를 다 복사해와서 만드셔도 됩니다.

#define NOTE_C5  523   //도
#define NOTE_D5  587   //레
#define NOTE_E5  659   //미
#define NOTE_F5  698   //파
#define NOTE_G5  784   //솔
#define NOTE_A5  880   //라
#define NOTE_B5  988   //시
#define NOTE_C6  1047  //도

멜로디배열변수

계이름을 매크로변수(#define) 이름으로 배열변수에 저장하시면 됩니다. 그냥 도를 523으로 저장해도 되지만 이름으로 표현하시면 음계를 쉽게 구별할 수 있기 때문에 숫자보다는 변수 이름으로 만들어서 코딩하는걸 추천 드려요.

int melody[] = {
NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,               //도도도도도
NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,               //미솔솔미도
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,       //솔솔미솔솔미
NOTE_C5,NOTE_C5,NOTE_C5,                               //도도도
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,                       //솔솔미도
NOTE_G5,NOTE_G5,NOTE_G5,                               //솔솔솔
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,                       //솔솔미도
NOTE_G5,NOTE_G5,NOTE_G5,                               //솔솔솔
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,                       //솔솔미도
NOTE_G5,NOTE_G5,NOTE_G5,NOTE_A5,NOTE_G5,               //솔솔솔라솔
NOTE_C6,NOTE_G5,NOTE_C6,NOTE_G5,                       //도솔도솔
NOTE_E5,NOTE_D5,NOTE_C5                                //미레도
};

멜로디음길이배열변수

각 음계의 음길이가 각기 다르기 때문에 4분음표, 8분음표, 2분음표 등의 박자길이를 숫자로 해서 멜로디음길이배열변수를 만들어서 순차적으로 음계랑 음길이를 나중에 코딩에서 합쳐서 음을 만들어 내기 위해서 배열변수로 해서 음계과 음길이를 따로 만듭니다.

int noteDurations[]={
4,8,8,4,4,
4,8,8,4,4,
8,8,4,8,8,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
8,8,8,8,2,
4,4,4,4,
4,4,2
};

3. 회로도 구성


준비물 : 피에조부저 1개, 아두이노우노


지난 시간의 회로도와 동일합니다.


4. 코딩


지난 시간의 코딩에서 2번의 멜로디를 만든 배열변수를 추가를 하여 약간 코딩을 변경하시면 됩니다.

#define NOTE_C5  523    //도
#define NOTE_D5  587    //레
#define NOTE_E5  659    //미
#define NOTE_F5  698    //파
#define NOTE_G5  784   //솔
#define NOTE_A5  880   //라
#define NOTE_B5  988   //시
#define NOTE_C6  1047 //도


int tonepin = 12;


int melody[] = {
NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,NOTE_C5,
NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_G5,NOTE_G5,NOTE_E5,
NOTE_C5,NOTE_C5,NOTE_C5,

NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_G5,
NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_G5,

NOTE_G5,NOTE_G5,NOTE_E5,NOTE_C5,
NOTE_G5,NOTE_G5,NOTE_G5,NOTE_A5,NOTE_G5,
NOTE_C6,NOTE_G5,NOTE_C6,NOTE_G5,
NOTE_E5,NOTE_D5,NOTE_C5
};

int noteDurations[]={
4,8,8,4,4,
4,8,8,4,4,
8,8,4,8,8,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
4,4,2,
4,4,4,4,
8,8,8,8,2,
4,4,4,4,
4,4,2
};


void setup() { 
} 
void loop() {
  for (int i = 0; i < 49; i++) {
    
    int Durations = 1000/noteDurations[i];    // 음계의 음길이 계산
    tone(tonepin, melody[i], Durations);    
    int pauseBetweenNotes = Durations *1.3 ;
    delay(pauseBetweenNotes);
    noTone(tonepin);
  }

}

이번에는 loop()에 반복수행하도록 한번 표현해봤습니다.

int Durations = 1000/noteDurations[i];    // 음계의 음길이 계산

음의 출력이 melody[i], noteDurations[i]로 매칭되어 음이 나오게 됩니다.

음길이 계산식이 원래 고정 1000/4여서 외부에 변수로 표현했지만 실제 곰세마리악보에서 보듯이 음길이가 다르기 때문에 melody[i], noteDurations[i]를 맞추기 위해서 for문 안에다 표현을 하였습니다.

그리고 보기 좋게 하기 위해서 따로 Durations로 변수를 만들어서 i번째 음길이를 가져와서 음길이를 계산한 표현을 하였습니다. 물론 tone(tonepin, melody[i], 1000/noteDurations[i])으로 표현해도 되겠지만 코딩은 각각 구분짓고 경계를 나누어 코딩하는게 시각적 가독성이 좋습니다. 그래서 일부로 이건 음길이 계산이다라고 별도로 한줄로 표현한 것이죠.

나머지 코딩부분은 이전 시간의 코딩과 동일합니다. 다른점은 멜로디 음계와 음길이를 별도로 배열변수에 저장했다는 것이죠.

5. 결과

실제로 회로도 구성이 쉬워서

라즈베리파에 설치한 아두이노 IDE 을 통해 바로 아두이노에 프로그램을 이식했습니다.


문제는 동영상 촬영했는데 소리는 원래 크게 들렸는데 녹화시 너무 작게 소리가 들어가서 실제 실험동영상은 올리는 것을 포기 했고 사진만 올립니다.

마무리


사실 tone(), noTone(), delay() 세함수를 제어하는 것일 뿐 별다른게 없습니다. 물론 음길이 공식이 1000/noteDurations와 Durations*1.3 으로 딜레이 시간을 준 공식을 추가된 것은 있지만 함수는 3개뿐이 사용 안했고 응용도 저 세개 함수만 사용한 실험이였습니다.

단지 멜로디를 만들기 위해서 배열변수로 코딩량만 늘어났을 뿐이죠. 코딩량은 늘어났지만 사실 멜로리 코딩은 위 악보에서 음계와 음길이를 추출하는 것은 쉽기 때문에 거기서 실제 배열변수로 만드는것은 어렵지 않게 2번 내용을 보시면 하실 수 있을거라고 생각됩니다.

예전에 자전거 멜로디를 만들어서 실험했지만 최근 음악 관련 포스팅을 할때 곰세마리악보를 이용해서 이번 아두이노에서도 곰세마리악보를 이용해 멜로디를 만들어 봤네요.

한번 다른 악보를 보고 멜로디를 만들어보세요.


댓글()