소리로 전등을 켜고 끄거나 또는 주차 중인 차 안에 설치하여 주변에 차가 움직이는 소리가 나면 카메라가 동작하는(심지어는 소리가 나는 곳으로 카메라가 향하도록 서보를 동작시키는 등) 기능을 구현해 보기 위해 우선 간단한 사운드 센서 모듈을 DX에서 구입해 보았다.
하드웨어)
- 소리를 감지하는 소형 마이크, 감도를 조절하는 노브, 그리고 아두이노 등과 연결하는 3 개의 핀으로 이루어짐
- 신호 핀은 위 사진에서 가운데 OUT에 해당하는 핀 하나이며, 소리를 감지한 경우 HIGH에서 LOW로 바뀐다!
- OUT 핀을 아두이노 UNO 보드의 D2에 연결
- 나머지 5V, GND도 마무리 연결
구현)
- 가장 간단하게는 loop() 함수 내에서 적당한 delay를 주며 센서 OUT 핀 값을 digitalRead() 하고 그 값이 LOW 인지 체크하는 방법이 있다.
- 그러나, 이 방식은 delay가 너무 긴 경우, 사운드 발생 이벤트를 놓칠 가능성이 있다. 그렇다고 delay를 너무 짧게 주면 digitalRead() 호출이 너무 많은 문제점을 갖고 있다. 특히 배터리로 운영하는 경우에는 배터리가 빨리 닳을 것이다.
- 언제 어떤 빈도로 발생할 지 모르는 이벤트를 감지하는 가장 좋은 방법은 바로 인터럽트(Interrupt)다.
- 인터럽트가 발생하면 loop() 함수를 잠시 멈추고 인터럽트 루틴으로 점프했다가 다시 돌아온다.
아두이노 인터럽트 설명)
- 인터럽트는 디지털 핀을 사용한다.
- 그러나, 모든 핀이 인터럽트를 지원하지는 않고 각 보드마다 특정 핀에서만 지원한다.
- 아두이노 UNO를 포함한 대부분의 아두이노 보드는 2 개의 디지털 핀을 지원한다.
- 인터럽트 번호라는 새로운 개념을 사용하며 이는 핀 번호와 무관하다. 번호는 0번부터 시작한다.
- 아두이노 UNO에서 인터럽트 번호와 디지털 핀 번호의 관계는 다음과 같다:
- 인터럽트 0번 –> 디지털 핀 2번
- 인터럽트 1번 –> 디지털 핀 3번
- 한편, 레오나르도는 5 개의 핀, 메가2560은 6 개의 핀에서 인터럽트를 지원한다.
소프트웨어)
volatile int state = 0;
void detectSound() {
state = 1;
}
void setup() {
Serial.begin(9600);
attachInterrupt(0, detectSound, LOW); // on Uno, D2
}
void loop() {
if (state == 1) {
Serial.println("Sound!");
state = 0;
}
delay(100);
}
- 인터럽트 등록 함수 attachInterrupt(0, detectSound, LOW)의 의미는 다음과 같다:
- 0: 인터럽트 0번 사용
- detectSound: 인터럽트가 발생하면 detectSound() 함수 호출
- LOW: 인터럽트와 연관된 디지털 핀의 상태가 LOW가 되면 인터럽트 발생
- 인터럽트 서비스 루틴(ISR)인 detectSound()에서는 전역 변수 state 값만 변경하고 신속하게 함수를 끝낸다. 이것이 일반적인 관례다.
- loop() 함수에서는 detectSound() 함수가 변경했을 지 모르는 state 변수를 보고 그에 알맞는 행위를 한다.
참고 자료)
- Sound Detection Sound Sensor Module for Smart Car – Black: $4.20에 구입 http://dx.com/p/sound-detection-sound-sensor-module-for-smart-car-black-140801
- Arduino “attachInterrupt()”: http://arduino.cc/en/Reference/attachInterrupt




