728x90

# 프로그램 설명

1. Speaker, Echo, Trig 단자들을 각각 11, 7, 8define 하고 섭씨온도를27도로 정한다. 장애물이 낮은 도 ~ 높은 도의 범위의 거리가 아닌 경우 스피커의 소리를 끄기 위해서 최대 거리 25cm, 최소 거리 3cm로 전역 변수를 사용하여 선언한 후 초기화한다.. 왕복시간(us), 센서와 장애물 사이의 거리(cm), 소리의 이동 속도(cm/us)를 저장할 전역 변수를 선언하고 각 음의 주파수를 배열 scales에 초기화하고 각 음계를 스트링 배열 melody에 초기화한다. scales은 거리에 따라 각 음을 스피커에 출력하기 위해 사용되고 melody는 각 음계를 문자 형태로 시리얼 모니터에 출력하여 확인하기 위해 사용된다.

 

2. void setup() 부분에서 각 음계를 시리얼 모니터로 출력하기 위하여 시리얼 모니터 전송 속도를 설정하고 Trig 단자를 출력모드(초음파 방출), Echo 단자(HIGH 펄스를 잼)를 입력모드로 설정한다. 소리의 이동 속도를 구하는 공식을 이용하여 소리의 이동 속도(cm/us)를 구하여 변수 sSpeed_cm_us에 저장한다.

 

3. void loop() 부분에서 digitalWrite() 함수를 이용하여 Trig 단자의 신호를 LOW로 만들어 오동작을 방지한 후 10us 지연시킨다. 이 후 신호를 HIGH로 만들어 HIGH 펄스를 만든 후 10us 지연시킨 후 신호를 LOW로 만들어 8개의 40KHz 펄스로 구성된 초음파를 방출한다. 초음파가 장애물에 반사되어 돌아오면 HIGHEcho 단자에 들어온다. Echo 단자로 들어온 HIGH 펄스가 유지된 시간을 pulseIn(단자번호, 상태) 함수를 사용하여 구한 뒤 변수 duration에 저장한다. 이 때 구해진 시간은 왕복 시간이므로 2로 나눈 후 소리의 이동 속도를 곱하여 센서와 장애물 사이의 거리(cm)를 구하여 변수 distance에 저장한다.

 

4. 거리가 최소 범위와 최대 범위 사이에 속하지 않을 경우에는 스피커의 소리를 끈다.

 

5. 거리가 최소 범위와 최대 범위 사이에 속할 경우에는 각 음계별로 거리의 범위를 지정하여 거리에 지정된 음을 문자 형태로 시리얼 모니터에 출력하고 그 음을 스피커로 출력한 후 1초 동안 지연시킨 뒤 스피커 소리를 끈다. 각 음계에 따른 거리의 범위는 낮은 도는 3~5cm, 레는 6~8cm, 미는 9~11cm, 파는 12~14cm, 솔은 15~17cm, 라는 18~20cm, 시는 21~23cm, 높은 도는 23~25cm로 설정하였다.

 

6. 초음파 센서의 Vcc 단자(보라색 선)를 아두이노 5V, Trig 단자(파란색 선)GPIO 8Echo 단자(초록색 선)GPIO 7, GND(노란색 선)GND에 연결하고 스피커 단자의 신호선(빨간색 선)GPIO 11, GND(검은색 선)GND에 연결한다.

 

7. 종이(장애물)를 이용하여 거리를 조절하여 비행기학교종을 연주해보면서 시리얼 모니터에 출력되는 음계와 스피커로 출력되는 음계를 확인해보니 동일하였고 원하는 음계가 출력되었다.

# 소스

#define SPK_PIN 11   // Speaker 단자
#define ECHO_PIN 7   // Echo 단자
#define TRIG_PIN 8   // Trig 단자 
#define TEMPERATURE 27    // 섭씨 온도 
int maximumRange = 25; // 최대 범위
int minimumRange = 3;  // 최소 범위 
long duration, distance;  // 왕복시간, 센서와 장애물 사이의 거리
double sSpeed_cm_us;  // 소리의 이동 속도
int scales[]={262, 294, 330, 347, 392, 440, 494, 524};   // 각 음의 주파수 선언
String melody[]={"도","레","미","파","솔","라","시","도"};   // 각 음계 스트링으로 선언

void setup() { 
  Serial.begin (9600); 
  pinMode(TRIG_PIN, OUTPUT);   // Trig 단자 OUTPUT모드로 설정
  pinMode(ECHO_PIN, INPUT);    // Echo 단자 INPUT모드로 설정
  // 소리의 이동 속도 [cm/us] 
  sSpeed_cm_us = (331.5 + 0.6*TEMPERATURE) * pow(10, 2) / pow(10, 6); 
 } 
 void loop() { 
  digitalWrite(TRIG_PIN, LOW);         // Trig 신호를 LOW로 만들어 오동작 방지
  delayMicroseconds(10);               // 10us 지연
  digitalWrite(TRIG_PIN, HIGH);        // 10us High Pulse 생성 
  delayMicroseconds(10);               // 10us 지연
  digitalWrite(TRIG_PIN, LOW);         // 센서 모듈이 40KHz의 pulse 8개 출력 
  
  // 초음파가 발사된 후 반사되어 돌아오는 왕복시간(us)을 반환
  duration = pulseIn(ECHO_PIN, HIGH);  
  // 초음파 센서와 장애물 사이의 거리 구함
  distance = duration/2 * sSpeed_cm_us;    
  
  if (distance > maximumRange || distance < minimumRange)  {  
	// 거리가 최소~최대 범위가 아닌 경우
    noTone(SPK_PIN);                  // 스피커 소리 끔
    delay(1000);
  } 
  else   {    // 거리가 최소~최대 범위인 경우
    if(distance>=3 and distance<=5){   // 3~5 범위는 '낮은 도' 
      Serial.print(melody[0]);         // 시리얼 모니터에 '도' 출력
      tone(SPK_PIN, scales[0]);        // 스피커로 '도' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=6 and distance<=8){   // 6~8 범위는 '레' 
      Serial.print(melody[1]);         // 시리얼 모니터에 '레' 출력
      tone(SPK_PIN, scales[1]);        // 스피커로 '레' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=9 and distance<=11){   // 9~11 범위는 '미' 
      Serial.print(melody[2]);          // 시리얼 모니터에 '미' 출력
      tone(SPK_PIN, scales[2]);         // 스피커로 '미' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=12 and distance<=14){   // 12~14 범위는 '파' 
      Serial.print(melody[3]);           // 시리얼 모니터에 '파' 출력
      tone(SPK_PIN, scales[3]);          // 스피커로 '파' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=15 and distance<=17){   // 15~17 범위는 '솔' 
      Serial.print(melody[4]);           // 시리얼 모니터에 '솔' 출력
      tone(SPK_PIN, scales[4]);          // 스피커로 '솔' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=18 and distance<=20){   // 18~20 범위는 '라' 
      Serial.print(melody[5]);           // 시리얼 모니터에 '라' 출력
      tone(SPK_PIN, scales[5]);          // 스피커로 '라' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=21 and distance<=23){   // 21~23 범위는 '시' 
      Serial.print(melody[6]);           // 시리얼 모니터에 '시' 출력
      tone(SPK_PIN, scales[6]);          // 스피커로 '시' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
    if(distance>=24 and distance<=25){   // 24~25 범위는 '높은 도' 
      Serial.print(melody[7]);           // 시리얼 모니터에 '도' 출력
      tone(SPK_PIN, scales[7]);          // 스피커로 '도' 옥타브 출력
      delay(1000);  
      noTone(SPK_PIN);
    }
  } 
}

 

# 실행 결과 (시리얼 모니터 화면)

- ‘비행기를 연주했을 때의 실행결과

- ‘학교종을 연주했을 때의 실행결과

 

반응형
  • 네이버 블러그 공유하기
  • 네이버 밴드에 공유하기
  • 페이스북 공유하기
  • 카카오스토리 공유하기