Menu
CoddyTech

루프가 놓치는 버튼 누름

Coddy Arduino 여정의 delay 없이 타이밍 제어하기 섹션에 포함된 레슨. 18개 중 12번째.

스케치는 느린 작업이나 긴 delay()를 실행하느라 바쁠 때가 있습니다. 작업 사이에만 버튼을 읽는 루프는 그 사이에 시작되고 끝나는 누름을 놓칩니다.

인터럽트가 이를 해결합니다. 핀이 바뀌면 보드는 하던 일을 멈추고, 사용자가 선택한 함수를 실행한 다음 다시 작업을 이어 갑니다. 칩은 delay() 중에도 핀을 직접 감시합니다.

void onPress() {
  digitalWrite(ledPin, HIGH);
}

void setup() {
  pinMode(buttonPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(buttonPin), onPress, FALLING);
}

attachInterrupt()는 세 가지를 받습니다. 핀의 인터럽트(digitalPinToInterrupt(buttonPin)가 이를 찾습니다), 실행할 함수, 그리고 실행 시점입니다. FALLING은 핀이 HIGH에서 LOW로 바뀌는 순간입니다. 풀업을 사용하는 경우 버튼을 누르는 순간입니다.

이 함수를 인터럽트 서비스 루틴(ISR)이라고 합니다. 짧게 유지하세요. delay()와 Serial은 사용하지 마세요.

challenge icon

챌린지

쉬움

이 알람은 2초마다 한 번만 버튼을 확인하므로, 빠르게 누르면 감지하지 못합니다. 버튼을 누르면 LED가 즉시 켜지도록 하세요:

  • LED를 켜는 ISR onPress()를 작성하세요
  • setup()에서 FALLING을 사용해 버튼 핀에 연결하세요

loop()에는 느린 작업을 그대로 두세요. 알람처럼 버튼을 누른 뒤에도 LED는 켜진 상태로 유지됩니다. Run을 누르고, 버튼을 탭한 다음, Check를 누르세요.

직접 해보기

const int ledPin = 13;
const int buttonPin = 2;

void setup() {
  pinMode(ledPin, OUTPUT);
  pinMode(buttonPin, INPUT_PULLUP);
  Serial.begin(9600);
  // 여기서 인터럽트를 연결하세요
}

void loop() {
  // 느린 작업: 그대로 두세요
  Serial.println("working");
  delay(2000);

  // 이 코드는 2초에 한 번만 버튼 상태를 확인하므로,
  // 짧게 누르면 감지하지 못합니다
  if (digitalRead(buttonPin) == LOW) {
    digitalWrite(ledPin, HIGH);
  }
}
quiz icon실력 점검

이 레슨에는 짧은 퀴즈가 포함되어 있습니다. 레슨을 시작해 문제를 풀고 진행 상황을 기록하세요.

delay 없이 타이밍 제어하기의 모든 레슨

직접 연습해 보세요: Arduino 플레이그라운드