본문 바로가기

IT/아두이노

아두이노 초음파센서와 부저를 이용한 피아노 만들기

반응형

안녕하세요.

오늘은 초음파센서와 부저를 활용해 피아노를 만들어보겠습니다.

 

1. 사용 부품

  • 초음파 센서
  • 부저
  • 브레드보드
  • F-F 점퍼선 6개
  • 아두이노 우노
  • 아두이노 PC 연결 케이블(USB Type-B)

2. 회로 연결

  • 부저의 (+)극은 아두이노의 디지털 11번 핀에 연결했습니다.
  • 부저의 (-)극은 아두이노의 GND 핀에 연결했습니다.
  • 초음파 센서의 VCC 핀은 아두이노의 5V 핀에 연결했습니다.
  • 초음파 센서의 GND 핀은 아두이노의 GND 핀에 연결했습니다.
  • 초음파 센서의 Echo 핀은 아두이노의 디지털 8번 핀에 연결했습니다.
  • 초음파 센서의 Trig 핀은 아두이노의 디지털 9번 핀에 연결했습니다.

 

3. 코드

#define Trig 9		//변수 Trig에 초음파 센서의 Trig에 연결하는 핀 설정
#define Echo 8		//변수 Echo에 초음파 센서의 Echo에 연결하는 핀 설정
#define Buzz 11		//변수 Buzz에 부저에 연결하는 핀 설정

//아래는 부저의 음계를 설정하는 코드
#define Do 261	// 도
#define Re 293	// 레
#define Mi 329	// 미
#define Pa 349	// 파
#define Sol 392	// 솔
#define Ra 440	// 라
#define Si 493	// 시
#define Do2 523	// 도

//아래는 아두이노 초기화 시 한번만 실행되는 코드
void setup() {
  Serial.begin(9600);			//시리얼 통신 시작
  pinMode(Trig, OUTPUT);		//Trig 핀은 초음파를 쏘아내는 핀이므로 출력 핀으로 설정
  pinMode(Echo, INPUT);			//Echo 핀은 초음파를 받아들이는 핀이므로 입력 핀으로 설정
  pinMode(Buzz, OUTPUT);		//Buzz 핀은 출력하는 핀으로 설정                  
}

//아래는 아두이노에 전원이 들어가있으면 계속 반복되는 코드
void loop()
{
  //시간값은 변수 duration에, 거리값은 변수 distance에 저장합니다.
  long duration, distance;
  
  digitalWrite(Trig, LOW);	//Trig 핀을 초기화합니다.
  delayMicroseconds(2);		//2마이크로초만큼 대기합니다.
  digitalWrite(Trig, HIGH);	//Trig핀을 이용해 초음파를 쏩니다.
  delayMicroseconds(5);		//5마이크로초만큼 대기합니다.
  digitalWrite(Trig, LOW);	//Trig 핀을 초기화합니다.
  
  //초음파가 반사되어 돌아온 시간을 변수 duration에 저장합니다.
  //이때 시간의 단위는 마이크로초(ms)입니다.
  duration = pulseIn (Echo, HIGH); 
  
  //(물체까지의 거리) = (초음파가 반사되어 돌아온 시간) x 340 / 2 / 10,000
  //음파의 속력은 340m/s = 34,000cm/s
  //물체까지의 거리는 왕복값이 아니라 편도 값으로 계산해야하므로 2를 나눠줍니다.
  //마이크로초를 초(s)로 변환하기 위해 10,000을 나눠줍니다.
  //1초는 1,000,000마이크로초입니다.
  //아래 코드는 cm 기준으로 작성한 코드입니다.
  distance = duration * 17 / 1000;
  
  //시리얼모니터 상에 duration 값과 distance 값을 출력합니다.
  Serial.print("Time : ");
  Serial.print(duration);
  Serial.println("ms");
  Serial.print("Distance : ");
  Serial.print(distance); 
  Serial.println("cm");
  
  //0.3초의 딜레이를 줍니다.
  //아두이노의 delay()함수는 밀리세컨드(ms) 기준이므로 1초의 딜레이를 주기 위해서는 1,000의 값을 줘야합니다.
  delay(300);


  //거리에 따라 부저의 음계를 설정합니다.
  //if(조건)문은 만약 조건이 참이라면 아래 명령어를 실행해줍니다.
  //else if(조건)문은 if문과 함께 사용하며, 조건이 참이라면 아래 명령어를 실행해줍니다.
  //else문은 만약 모든 조건이 참이 아니라면, 아래 명령어를 실행해줍니다.
  //만약 거리가 1cm이상이고 5cm이하이면 아래 명령어를 실행합니다.
  if (distance >= 1 && distance <= 5)
   {
    //tone(핀번호, 소리주파수, 소리지속시간)함수를 이용해 음을 울립니다.
    //지속시간은 ms기준입니다.
    tone(Buzz, Do, 250);
    delay(500);
    noTone(Buzz);			//noTone()함수를 이용해 부저를 끕니다.
   }
   //만약 거리가 7cm이상이고 9cm이하라면 아래 명령어를 실행합니다.
   else if (distance >= 7 && distance <= 9)
   {
    tone(Buzz, Re, 250);
    delay(500);
    noTone(Buzz);
   }   
   else if (distance >= 10 && distance <= 13)
   {
    tone(Buzz, Mi, 250);
    delay(500);
    noTone(Buzz);
   }   
   else if (distance >= 14 && distance <= 16)
   {
    tone(Buzz, Pa, 250);
    delay(500);
    noTone(Buzz);
   }  
   else if (distance >= 17 && distance <= 19)
   {
    tone(Buzz, Sol, 250);
    delay(500);
    noTone(Buzz);
   }
   else if (distance >= 20 && distance <= 22)
   {
    tone(Buzz, Ra, 250);
    delay(500);
    noTone(Buzz);
   }
   else if (distance >= 23 && distance <= 26)
   {
    tone(Buzz, Si, 250);
    delay(500);
    noTone(Buzz);
   }
   else if (distance >= 27 && distance <= 29)
   {
    tone(Buzz, Do2, 250);
    delay(500);
    noTone(Buzz);
   }
   //조건이 충족되지 않는다면 아래 명령어를 실행합니다.
   else
   {
    noTone(Buzz);
   }
   
}

위 코드는 크게 두 덩어리로 나뉘어집니다.

(1) 초음파 센서로 거리를 측정하는 코드

초음파 센서는 초음파가 물체에 부딪혀 돌아올때까지 걸리는 시간을 측정해줍니다.

하지만 초음파 센서가 거리까지 계산해주지는 않기 때문에 아래와 같은 식이 필요합니다.

다들 물리시간에 (거리) = (시간) x (속력)식을 배우셨을 겁니다.

우리는 거리를 구해야 하는데, 초음파 센서를 이용해 시간을 측정하였고,

소리의 속력은 340m/s라는 사실을 상식으로, 혹은 구글링을 통해 알고 있습니다.

따라서 위 식을 이용해 거리를 구할 수 있게 됩니다.

다만 초음파 센서가 측정하는 시간은 초음파가 물체에 반사되어 돌아오는 시간을 의미하므로,

물체와의 거리를 계산하려면 초음파 센서가 출력하는 시간을 2로 나누어줘야합니다.

또한, 초음파 센서가 출력하는 시간이 마이크로초라는 사실도 숙지하고 있어야 단위 변환을 할 수 있습니다.

 

(2) 거리 값에 따라 부저가 울리는 소리의 음계가 달라지도록 설정하는 코드

도, 레, 미, 파, 솔, 라, 시, 도의 소리가 다른 이유는

각 소리의 주파수가 다르기 때문입니다.

우리가 사용하는 부저는 다양한 주파수의 소리를 낼 수 있으므로,

각 계이름에 맞는 주파수를 변수에 담아 거리에 따라 특정 주파수가 담긴 변수의 값을 출력해줍니다.

예를 들어 '도'는 261Hz의 값을 가집니다.

그리고 물체와의 거리가 5cm일때 '도'를 연주하고 싶다면,

if문을 이용해 5cm 조건이 주어졌을때 '도'를 연주하도록 명령어를 넣어주면 됩니다.

나머지 음계도 조건에 따라 연주해주기 위해 else if와 else문을 사용합니다.

 

4. 결과

아두이노 IDE의 시리얼 모니터를 열면

측정된 거리값과 시간값을 표시합니다.

아래 영상은 실제 작동 영상입니다.

 

5. 마치며

저걸 어디 쓰지 싶었던 부저가 생각보다 쩌렁쩌렁 했고, 음계도 정확히 출력하는걸 보고 조금 놀랐습니다.

초음파 센서의 경우는 많이 사용해본 만큼 정확도에 큰 기대가 없었고,

실제로도 정확하지 않았습니다.

손바닥의 위치가 그대로인데도 초음파 센서의 오류로 거리값이 크게 측정되거나 작게 측정되어

다른 소리가 나기도 했었습니다.

 

모터처럼 직관적이진 않지만 나의 움직임에 따라 소리가 다르게 난다는 점에서

학생들이 즐거워할 수 있는 키트라는 생각이 들었습니다.

 

저는 도매키트라는 곳에서 초음파 센서와 부저를 이용한 피아노 키트를 구매했고, 아래 링크를 참조해주세요.

https://smartstore.naver.com/domekit/products/6004652980

 

아두이노 미니 키트 초음파 피아노 DM3927 : 도매키트

[도매키트] 코딩 교육 부품, 아두이노, 마이크로비트, 라즈베리파이 등을 업체에 도매가로 공급합니다.

smartstore.naver.com

 

반응형