volatile로 공유하기
Coddy Arduino 여정의 delay 없이 타이밍 제어하기 섹션에 포함된 레슨. 18개 중 14번째.
ISR은 빠르게 한 가지 작업을 해야 하므로, 보통 스케치의 나머지 부분에서 읽을 변수를 설정합니다. 두 곳에서 모두 사용하는 변수는 volatile로 선언해야 합니다:
volatile bool started = false;
void onPress() {
started = true;
}시간을 절약하기 위해 컴파일러(C++ 코드를 칩의 명령어로 변환하는 프로그램)는 메모리를 읽는 대신 프로세서 내부에 변수의 복사본을 보관할 수 있습니다. 컴파일러는 인터럽트가 변수를 바꿀 수 있다는 것을 모르므로 스케치가 오래된 복사본을 계속 사용할 수도 있습니다. volatile을 사용하면 매번 변수를 새로 읽습니다.
이 스케치는 setup()에서 while 루프를 사용해 기다립니다: while (condition) { }은 조건이 참인 동안 중괄호 안의 내용을 반복하며, 여기서 조건은 !started입니다. Inputs 섹션에서처럼 !는 부정을 뜻합니다. 즉, started가 false인 동안 루프가 반복됩니다. volatile이 없으면 버튼을 누른 뒤에도 영원히 기다릴 수 있습니다.
챌린지
쉬움이 스케치는 버튼을 누를 때까지 기다린 다음 LED를 깜박여야 합니다. 지금은 영원히 기다립니다. 다음과 같이 수정하세요:
onPress()에서started를true로 설정하세요started를volatile로 선언하세요
Run을 누르고, 버튼을 누른 다음 Check를 누르세요. 보드가 멈춘 상태로 있는 것을 확인하려면 volatile 없이 한 번 시도해 보세요.
직접 해보기
const int ledPin = 13;
const int buttonPin = 2;
bool started = false; // 인터럽트에서 설정하고 스케치에서 읽음
unsigned long previousMillis = 0;
int ledState = LOW;
void onPress() {
// 여기서 started를 true로 설정
}
void setup() {
pinMode(ledPin, OUTPUT);
pinMode(buttonPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
// 버튼이 눌릴 때까지 여기서 대기
while (!started) {
}
}
void loop() {
// 250 ms마다 깜빡임
unsigned long now = millis();
if (now - previousMillis >= 250) {
previousMillis = now;
if (ledState == LOW) {
ledState = HIGH;
} else {
ledState = LOW;
}
digitalWrite(ledPin, ledState);
}
}
이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.
delay 없이 타이밍 제어하기의 모든 레슨
직접 연습해 보세요: Arduino 플레이그라운드