본문 바로가기

아두이노-스케치

초음파 센서로 음악(도 레 미 ...) 연주하기 소스코드





초음파 센서로 거리를 얻어 거리에 따라 스피커나 피에조로 음악을 연주한다.

확인할 것


1. 툴 메뉴에서 아두이노 보드 확인

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
89
90
91
92
93
94
int echoPin = 12; //초음파 센서의 Echo 핀번호를 설정한다.
int trigPin = 13; //초음파 센서의 Trig 핀번호를 설정한다.
int speakerPin = 9
 
//49.4, 52.3, 55.4, 58.7, 62.2, 65.9, 69.9, 74, 78.4, 83.1, 88, 93.2, 
//98.8, 105, 111, 117, 124, 132, 140, 148, 157, 166, 176, 186, 
//198, 209, 222, 235, 249, 264, 
 
//int noteFreqArr[] = { //66 note
//279, 296, 314, 332, 352, 373, 
//395, 419, 444, 470, 498, 527, 559, 592, 627, 665, 704, 746, 
//790, 837, 887, 940, 996, 1050, 1110, 1180, 1250, 1320, 1400, 1490, 
//1580, 1670, 1770, 1870, 1990, 2100};
 
int noteFreqArr[] = { 5275926657047908879961050};
 
//int noteFreqArr[] = { //66 note 527, 592, 665, 704, 790, 887, 996, 1050};
//int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
 
void setup(){
    Serial.begin(9600);
      pinMode(trigPin, OUTPUT);
      pinMode(echoPin, INPUT);
    // trig를 출력모드로 설정, echo를 입력모드로 설정
      pinMode(speakerPin, OUTPUT);
}
 
void loop(){
      int intdistance;
      int noteLength = 500;
      float duration, distance;
      int length = 100;
      digitalWrite(trigPin, HIGH);
      delay(100);
      digitalWrite(trigPin, LOW);
      // 초음파를 보낸다. 다 보내면 echo가 HIGH 상태로 대기하게 된다.
  
      duration = pulseIn(echoPin, HIGH); // echoPin 이 HIGH를 유지한 시간을 저장 한다.
      distance = ((float)(340 * duration) / 10000/ 2;  // HIGH 였을 때 시간(초음파가 보냈다가 다시 들어온 시간)을 가지고 거리를 계산 한다.
      intdistance = (int)distance;
      Serial.print(intdistance);
      Serial.println("cm");
      // 수정한 값을 출력
  
      if(intdistance <= 32.0)
      {
          //playNote(noteFreqArr[intdistance], 10);
          if((intdistance >= 0& (intdistance <= 4))
             playTone(noteFreqArr[0], length);
          if((intdistance >= 5& (intdistance <= 8))
             playTone(noteFreqArr[1], length);
          if((intdistance >= 9& (intdistance <= 12))
             playTone(noteFreqArr[2], length);
          if((intdistance >= 13& (intdistance <= 16))
             playTone(noteFreqArr[3], length);
          if((intdistance >= 17& (intdistance <= 20))
             playTone(noteFreqArr[4], length);
          if((intdistance >= 21& (intdistance <= 24))
            playTone(noteFreqArr[5], length);
          if((intdistance >= 25& (intdistance <= 28))
             playTone(noteFreqArr[6], length);
          if((intdistance >= 29& (intdistance <= 32))
             playTone(noteFreqArr[7], length);
      }
  
      //delay(10);
}
 
void playNote(int note, int duration) 
{
     char names[] = { 'c''d''e''f''g''a''b''C' };
     //int tones[] = { 1915, 1700, 1519, 1432, 1275, 1136, 1014, 956 };
     int tones[] = { 2093,2349,2637,2793,3136,3520,3951,4186};
     // play the tone corresponding to the note name
 
     for (int i = 0; i < 30; i++
     {
           if (names[i] == note)  
           {
             playTone(tones[i], duration);
        }
     }
}
 
void playTone(int tone, int duration) 
{
     for (long i = 0; i < duration * 1000L; i += tone * 2
    {
         digitalWrite(speakerPin, HIGH);
         delayMicroseconds(tone);
         digitalWrite(speakerPin, LOW);
         delayMicroseconds(tone);
    }
}
cs



아래는 스피커의 BEEP 음을 1초 마다 내는 소스이다.

tone() 의 파라미터(출력핀, 주파수, 지속시간)를 조절하면 다양한 음을 만들 수 있다.



1
2
3
4
5
6
7
8
9
10
11
12
13
14
int speakerpin = 12//스피커가 연결된 디지털핀 설정
 
void setup() 
{
}
 
void loop() 
{
    tone(speakerpin,500,1000);  //500: 음의 높낮이(주파수), 1000: 음의 지속시간(1초)
      delay(2000); 
}
 
 
 
cs




아래는 도레미파솔라시도를 연주하는 소스코드이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
int speakerpin = 12//스피커가 연결된 디지털핀 설정
int note[] = {20932349263727933136352039514186}; //도레미파솔라시도
 
void setup() {
    int elementCount = sizeof(note) / sizeof(int);
      for (int i=0; i < elementCount; i++)    //note를 play
      {
        tone(speakerpin,note[i],500);
        delay(750);
      }
}
 
void loop() 
{
}
cs



참고사항: 출처 : http://deneb21.tistory.com/218


위와 같이 도레미파솔라시도를 연주할 경우 각각의 음계의 tone값을 적어주어야 한다. 만약 tone값을 모를 경우 멜로디를 만들기가 아주 힘들다. 이런 경우 사용할 수 있도록 tone값에 대해서 미리 정의해 놓은 pitches.h 라는 헤더파일을 만들어 이용하면 손쉽게 멜로디를 만들 수 있다.


※ 참조: https://www.arduino.cc/en/Tutorial/Tone


아래의 소스를 pitches.h 라는 이름으로 프로그램과 같은 폴더에 저장해 놓고 프로그램에서 include하여 사용하면 된다.



## pitches.h ##

아래의 소스를 pitches.h 라는 이름으로 프로그램과 같은 폴더에 저장


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
/*************************************************
 * Public Constants
 *************************************************/
#define NOTE_B0  31
#define NOTE_C1  33
#define NOTE_CS1 35
#define NOTE_D1  37
#define NOTE_DS1 39
#define NOTE_E1  41
#define NOTE_F1  44
#define NOTE_FS1 46
#define NOTE_G1  49
#define NOTE_GS1 52
#define NOTE_A1  55
#define NOTE_AS1 58
#define NOTE_B1  62
#define NOTE_C2  65
#define NOTE_CS2 69
#define NOTE_D2  73
#define NOTE_DS2 78
#define NOTE_E2  82
#define NOTE_F2  87
#define NOTE_FS2 93
#define NOTE_G2  98
#define NOTE_GS2 104
#define NOTE_A2  110
#define NOTE_AS2 117
#define NOTE_B2  123
#define NOTE_C3  131
#define NOTE_CS3 139
#define NOTE_D3  147
#define NOTE_DS3 156
#define NOTE_E3  165
#define NOTE_F3  175
#define NOTE_FS3 185
#define NOTE_G3  196
#define NOTE_GS3 208
#define NOTE_A3  220
#define NOTE_AS3 233
#define NOTE_B3  247
#define NOTE_C4  262
#define NOTE_CS4 277
#define NOTE_D4  294
#define NOTE_DS4 311
#define NOTE_E4  330
#define NOTE_F4  349
#define NOTE_FS4 370
#define NOTE_G4  392
#define NOTE_GS4 415
#define NOTE_A4  440
#define NOTE_AS4 466
#define NOTE_B4  494
#define NOTE_C5  523
#define NOTE_CS5 554
#define NOTE_D5  587
#define NOTE_DS5 622
#define NOTE_E5  659
#define NOTE_F5  698
#define NOTE_FS5 740
#define NOTE_G5  784
#define NOTE_GS5 831
#define NOTE_A5  880
#define NOTE_AS5 932
#define NOTE_B5  988
#define NOTE_C6  1047
#define NOTE_CS6 1109
#define NOTE_D6  1175
#define NOTE_DS6 1245
#define NOTE_E6  1319
#define NOTE_F6  1397
#define NOTE_FS6 1480
#define NOTE_G6  1568
#define NOTE_GS6 1661
#define NOTE_A6  1760
#define NOTE_AS6 1865
#define NOTE_B6  1976
#define NOTE_C7  2093
#define NOTE_CS7 2217
#define NOTE_D7  2349
#define NOTE_DS7 2489
#define NOTE_E7  2637
#define NOTE_F7  2794
define NOTE_FS7 2960
#define NOTE_G7  3136
#define NOTE_GS7 3322
#define NOTE_A7  3520
#define NOTE_AS7 3729
#define NOTE_B7  3951
#define NOTE_C8  4186
#define NOTE_CS8 4435
#define NOTE_D8  4699
#define NOTE_DS8 4978
cs



pitches.h를 이용하여 '학교종이 떙땡땡' 노래를 연주하는 소스코드가 아래에 있다.



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
#include "pitches.h"
 
int speakerpin = 12//스피커가 연결된 디지털핀 설정
 
//음계 데이터 (24개)
int melody[] = {NOTE_G7,NOTE_G7,NOTE_A7,NOTE_A7,NOTE_G7,
                NOTE_G7,NOTE_E7,NOTE_G7,NOTE_G7,NOTE_E7,
                NOTE_E7,NOTE_D7,NOTE_G7,NOTE_G7,NOTE_A7,
                NOTE_A7,NOTE_G7,NOTE_G7,NOTE_E7,NOTE_G7,
                NOTE_E7,NOTE_D7,NOTE_E7,NOTE_C7};
//음의길이, 4:4분음표, 2:2분음표
int noteDurations[] = {4,4,4,4,4,4,2,4,4,4,4,1,4,4,4,4,4,4,2,4,4,4,4,1};
 
void setup() 
{
     for (int thisNote = 0; thisNote < 24; thisNote++)
      {
        int noteDuration = 1000 / noteDurations[thisNote];
        tone(speakerpin, melody[thisNote], noteDuration); //소리를 낸다.
        int pauseBetweenNotes = noteDuration * 1.30;      //delay 계산식
        delay(pauseBetweenNotes);                         //delay
        noTone(speakerpin);                               //대상핀 출력 중단
      }
}
 
void loop() 
{
}
 
 
cs


-끝-