라즈베리파이, 아두이노

[간단한 아두이노 코딩] 11. 피에조 부저 사용하기 + 젓가락 행진곡

포도알77 2020. 11. 24. 10:21

피에조 부저 사용하기 + 젓가락 행진곡

 

1. 피에조 부저란

 피에조 부저는 크리스털 혹은 세라믹 결정체에 전압을 가하여 응축,신장 하는 압전효과를 이용하여 진동을 만들어내어 소리를 낸다. 소리의 크기를 코드상으로 설정하지 못하지만 싸고 간단하여 많이 사용된다.

 

 부저는 능동형과 수동형이 있으며, 능동형의 경우 전류가 흐르면 소리가 발생하지만 수동 부저는 인가된 전원의 주파수에 따라 소리의 높낮이가 결정된다. 능, 수동 구분법이 많이 존재하는데, 단순히 전원을 인가시켜보는 것이 가장 빠르다.

 

 

2. 옥타브별 음계

 피에조 부저를 이용해서 소리를 내기 위해서는 옥타브별 음계에 대한 주파수를 이용하면 된다. 각 주파수는 아래와 같다.

옥타브
음계

0

1

2

3

4

5

6

7

8

C(도)

16

33

65

131

262

523

1046.5

2093

4186

C♯

17

35

69

139

277

554

1109

2217.5

4435

D(레)

18

37

73

147

294

587

1175

2349

4699

D♯

20

39

78

156

311

622

1244.5

2489

4978

E(미)

21

41

82

165

330

659

1318.5

2637

5274

F(파)

22

44

87

175

349

698.5

1397

2794

5588

F♯

23

46

92.5

185

370

740

1480

2960

5920

G(솔)

25

49

98

196

392

784

1568

3136

6272

G♯

26

52

104

208

415

831

1661

3322.5

6645

A(라)

28

55

110

220

440

880

1760

3520

7040

A♯

29

58

116.5

233

466

932

1865

3729

7459

B(시)

31

62

123.5

247

494

988

1975.5

3951

7902

 

3. 회로 구성

 회로는 아래와 같이 단순하게 구성하면 된다. 만약 소리를 줄이고 싶다면 저항을 하나 연결해줘도 좋다. 단, 아두이노에서는 하나의 부저만 사용할 수 있다.

 

 

4. 소스코드

 단순히 소리내는 조금 아쉬워서 젓가락 행진곡을 출력했다. 단순히 출력하기에는 소스코드가 너무 길어질 것 같아서, 배열에 출력 음계와 시간 그리고 반복 횟수를 담았다.

 

// 피에조 PWM 핀
int spk_pin = 2;

// 4, 5옥타브 주파수
enum code { 
  o4do=261, o4re=293, o4mi=329, o4fa=349, o4sol=391, o4la =440, o4si = 493,
  o5do=523, o5re=587, o5mi=659, o5fa=698, o5sol=783, o5la =880, o5si = 987
 };

// 젓가락 행진곡
// { 계, 출력시간, 횟수 }
int song[][3] = {
  // 솔솔솔솔솔솔 솔솔솔솔솔
  // 시시시시시시 도도도도시라
  { o4sol, 200, 12},
  { o4si, 200, 6},
  { o5do, 200, 4},
  { o4si, 200, 1},
  { o4la, 200, 1},
  
  // 솔솔솔솔솔솔 솔솔솔솔솔
  // 시시시시시시 도도도도솔미도
  { o4sol, 200, 12},
  { o4si, 200, 6},
  { o5do, 200, 4},
  { o4sol, 200, 1},
  { o4mi, 200, 1},
  { o4do, 200, 1},
  
  // 주파수 0을 할당하여 쉼표 역할
  { 0, 800, 1},

  // 미레도시라솔 솔솔라솔파파파솔파미 파솔
  // 2회
  { o5mi, 400, 1},
  { o5re, 400, 1},
  { o5do, 400, 1},
  { o4si, 200, 1},
  { o4la, 400, 1},
  { o4sol, 500, 1},
  
  { o4sol, 200, 2},
  { o4la, 200, 1},
  { o4sol, 200, 1},
  { o4fa, 500, 1},
  { o4fa, 200, 2},
  { o4sol, 200, 1},
  { o4fa, 300, 1},
  { o4mi, 500, 1},
  
  { o4fa, 200, 1},
  { o4sol, 500, 1},

  { o5mi, 400, 1},
  { o5re, 400, 1},
  { o5do, 400, 1},
  { o4si, 200, 1},
  { o4la, 400, 1},
  { o4sol, 500, 1},
  
  { o4sol, 200, 2},
  { o4la, 200, 1},
  { o4sol, 200, 1},
  { o4fa, 500, 1},
  { o4fa, 200, 2},
  { o4sol, 200, 1},
  { o4fa, 300, 1},
  { o4mi, 500, 1},
  { o4mi, 300, 2},
  
  { 0, 800, 1},
  // 도솔미도
  { o5do, 200, 1},
  { o4sol, 200, 1},
  { o4mi, 200, 1},
  { o4do, 200, 1},
};

void setup() {
  pinMode(spk_pin, OUTPUT); 
}

void loop() {
  // sizeof(배열)/sizeof(배열의 첫원소)으로 전체 배열 길이를 구함
  for(int i = 0 ; i < sizeof(song)/sizeof(*song); i++){
    // 3번째 데이터의 횟수만큼 루프
    for(int j = 0 ; j < song[i][2]; j++){
      // tone 함수는 
      // tone(핀, 주파수, 출력시간)
      tone(spk_pin, song[i][0], song[i][1]);
      // 300ms 딜레이 부여
      delay(300); 
    }
  }
}
페이스북으로 공유카카오톡으로 공유카카오스토리로 공유트위터로 공유URL 복사