[아두이노] delay() 함수 대신 millis() 함수 사용하기

delay() 함수 사용하지 않고 LED 깜박거리게 하기

가끔 동시에 두가지 이상의 기능을 동작시켜야 하는 경우가 있습니다. 예를 들어 LED를 깜박이는 동안 버튼의 상태를 읽어오는 경우가 있습니다. 이런 경우 LED를 주기적으로 깜박이게 하는데 delay() 함수를 사용하기엔 제약사항이 있습니다. delay() 함수가 실행되는 동안에 프로그램의 수행이 일시적으로 멈추기 때문입니다. 따라서 delay() 함수가 실행되고 있을 때 버튼이 눌리면 아두이노는 이 버튼이 눌린 이벤트를 놓치게 됩니다.


이러한 동시성 문제를 해결하기 위해, delay() 함수 없이 LED를 깜박이게 해 보겠습니다. LED를 켬과 동시에 시간을 기록합니다. loop() 함수 실행될 때마다 깜박이는 주기가 지났는지 확인합니다. LED를 켠 뒤로 깜박이는 주기가 지났다면 LED를 끕니다. LED를 끈 뒤로 깜박임 주기가 지났다면 다시 LED를 켭니다. LED를 켜고 끄는 코드 전후로 다른 기능을 수행하는 코드가 있다면, LED ON-OFF와 무관하게 동작시킬 수 있습니다.


우선 필요한 하드웨어는 아래와 같습니다.

- 아두이노 우노

- LED

- 220Ω 저항

회로도는 아래와 같습니다.

코드는 아래와 같습니다.

// LED가 연결된 핀번호
const int ledPin = LED_BUILTIN; // 보드에 내장된 LED 핀 번호 = 13번

// LED 상태를 저장할 변수
int ledState = LOW; // 초기 LED 상태는 OFF

// unsigned long 변수 형식 이용하여 시간값 저장
unsigned long previousMillis = 0; // LED 상태를 변경한 시각을 저장

// 깜박임 주기는 1초:
const long interval = 1000; // ms 단위

void setup() {
  // LED 출력핀 지정
  pinMode(ledPin, OUTPUT);
}

void loop() {
  // 현재 시간을 저장
  // millis() 함수는 아두이노가 실행된 이후 경과시간을 반환합니다.
  // millis() 함수는 50일 정도가 지나면 overflow가 되는점 유의해야 합니다.
  unsigned long currentMillis = millis(); 
  
  // 깜박임 주기가 지났는지 확인
  if (currentMillis - previousMillis >= interval) {
    // 마지막 LED 상태 변경시간을 저장
    previousMillis = currentMillis;

    // LED 상태를 토글(toggle)
    if (ledState == LOW) {
      ledState = HIGH;
    } else {
      ledState = LOW;
    }

    // LED 상태를 출력
    digitalWrite(ledPin, ledState);
  }
}



끝.

댓글

이 블로그의 인기 게시물

[전기 기초] 전력공식 P=VI 유도

전력(kW) 계산하기 (직류, 교류 단상, 교류 삼상)

[PLC] PLC 아날로그 입출력 기본

제너 다이오드에 저항을 연결하는 이유

공압 속도 제어: 미터인 vs 미터아웃

회로 차단기 용량 선정하는 방법

NPN, PNP 트랜지스터 차이점

[아두이노] 가변저항(Potential Divider)과 전압분배(Voltage Divider)

[python] 파이썬 pyplot 2차원 그래프 샘플 코드

[PLC] 래더 다이어그램과 PLC