# 프로그램 설명
1. Speaker, Echo, Trig 단자들을 각각 11, 7, 8로 define 하고 섭씨온도를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 펄스로 구성된 초음파를 방출한다. 초음파가 장애물에 반사되어 돌아오면 HIGH가 Echo 단자에 들어온다. 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 8번, Echo 단자(초록색 선)를 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);
}
}
}
# 실행 결과 (시리얼 모니터 화면)
- ‘비행기’를 연주했을 때의 실행결과
- ‘학교종’을 연주했을 때의 실행결과
'전공 공부 > 아두이노프로그래밍' 카테고리의 다른 글
analogWrite() 함수 이용하여 390Hz의 periodic interrupt를 발생시키는 프로그램 (0) | 2021.01.22 |
---|---|
장애물까지의 거리를 mm단위로 반환하는 함수 (4) | 2021.01.18 |
적외선 센서 (0) | 2021.01.18 |
장애물회피센서, 라인트레이서 (0) | 2021.01.18 |
적외선 장애물회피센서, 만능기판에 설치한 LED (0) | 2021.01.18 |