# 프로그램 설명
1. 스피커 단자, 인터럽트 단자를 각각 13, 2로 지정하고 필요한 전역 변수인 1초 지났는지 상태를 저장하는 변수 state, 인터럽트 카운트를 세는 변수 count, 초 세는 변수 sec를 선언하고 각각 0으로 초기화한다.
2. setup() 부분에 인터럽트 단자를 입력 모드로 설정하고 attachInterrupt() 함수를 사용해서 HIGH->LOW가 되는 FALLING 상태일 때 인터럽트 발생 시 처리할 isr를 지정한다. 현재 시간(초)을 시리얼 모니터에 출력하기 위해서 시리얼 전송 속도를 설정하고 PWM 단자인 5번 단자에 analogWrite() 함수를 사용해서 듀티비 50%인 신호를 출력한다.
3. isr() 함수는 인터럽트 발생 시 처리될 함수로 인터럽트가 발생하면 count를 하나씩 올려 인터럽트 횟수를 센다. 5번 단자는 980Hz 신호를 만들어내기 때문에 인터럽트 횟수가 980이 되면 1초가 지난 것이다. 이때 현재 시간(초)을 세는 변수를 하나 올리고 상태를 1로 바꾸어 1초가 지난 것을 알려주고 count 값을 0으로 초기화한다.
4. loop() 부분에서 60초가 되면 tone 함수를 사용해서 1초 동안 스피커에 500Hz인 음정을 출력하고 noInterrupts() 함수를 사용해서 모든 인터럽트를 금지한다. 1초가 지났다는 걸 저장하는 변수 state 가 1이 되면 state를 다시 0으로 초기화하고 현재 시간(초)을 출력한다.
5. 인터럽트 단자인 2번 단자와 PWM 단자인 5번 단자를 서로 연결하고 스피커 단자의 신호 단자를 13번 단자에 연결하고 GND 단자를 GND 단자에 연결한다.
# 소스
#define spkPin 13 // 스피커 단자
#define intPin 2 // 인터럽트 단자
volatile int state = 0; // 1초 지났는지 상태를 저장하는 변수
volatile int count = 0; // 인터럽트 횟수를 세는 변수
volatile int sec = 0; // 초를 세는 변수
void setup() {
pinMode(intPin, INPUT_PULLUP); // 인터럽트 단자를 입력 모드로 설정
// FALLING(HIGH->LOW) 일 때 인터럽트 발생 시 처리할 isr 지정
attachInterrupt(digitalPinToInterrupt(intPin), isr, FALLING);
Serial.begin(9600); // 시리얼 전송 속도 설정
analogWrite(5, 128); // 5번 PWM 단자에 듀티비 50%인 신호 출력
}
void loop() {
if(sec == 60){ // 60초 되면 1초동안 스피커 울림
tone(spkPin, 500);
delay(1000);
noTone(spkPin);
noInterrupts(); // 모든 인터럽트 금지
}
if(state == 1){ // 상태가 1이면(1초 지나면)
state = 0; // 상태 0으로 바꾸고
Serial.println(sec); // 현재 시간(초) 출력
}
}
void isr(){
count++; // 인터럽트 발생하면 count값 올림
if(count==980){ // count값이 980이 되면(1초 지나면)
sec++; // sec값 1초 올림
count = 0; // count값 0으로 초기화
state = 1; // 상태 1로 바꿈
}
}
# 실행화면(시리얼 모니터)
'전공 공부 > 아두이노프로그래밍' 카테고리의 다른 글
20KHz의 클럭 소스를 이용하여 인터럽트를 발생. 이를 기반으로 tone() 함수를 설계하고 한 옥타브의 음정을 연주 (0) | 2021.01.22 |
---|---|
MsTimer2 이용하여 지정한 주파수의 음정을 생성하는 myTone(pin, frequency)과 myNoTone() 함수를 제작 (0) | 2021.01.22 |
장애물까지의 거리를 mm단위로 반환하는 함수 (4) | 2021.01.18 |
스피커를 이용한 연주 (0) | 2021.01.18 |
적외선 센서 (0) | 2021.01.18 |