콘텐츠로 건너뛰기

아두이노 딜레이 구현, delay(), millis() 사용해 보기

    들어가며

    안녕하세요! 오늘은 아두이노에서 시간을 제어하는 두 가지 주요 함수인 delay()millis()에 대해 알아보려고 해요. delay() 함수는 프로그램을 일정 시간 멈추는 데 사용되고, millis() 함수는 아두이노가 켜진 후부터의 경과 시간을 밀리초 단위로 반환하는 함수입니다. 이 두 가지 함수를 통해 딜레이를 구현하고 타이밍을 정밀하게 제어하는 방법을 배워볼 거예요. 이번 프로젝트의 목표는 이 두 함수를 활용하여 내장 LED를 깜빡이게 하는 간단한 예제를 만드는 것입니다.

    delay() 함수

    delay() 함수란?

    delay() 함수는 프로그램 실행을 지정된 시간만큼 멈추게 하는 함수입니다. 함수의 괄호 안에 넣는 숫자는 밀리초(ms) 단위로, 프로그램이 멈추는 시간을 의미합니다. 예를 들어, delay(1000);이라고 하면 프로그램은 1000밀리초, 즉 1초 동안 멈추게 됩니다.

    예제 코드

    void setup() {
      // 내장 LED 핀을 출력 모드로 설정
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    void loop() {
      // LED를 켠다
      digitalWrite(LED_BUILTIN, HIGH);
      // 1초(1000 밀리초) 동안 대기
      delay(1000);
      // LED를 끈다
      digitalWrite(LED_BUILTIN, LOW);
      // 1초(1000 밀리초) 동안 대기
      delay(1000);
    }

    코드 설명

    • pinMode(LED_BUILTIN, OUTPUT);: 내장 LED 핀을 출력 모드로 설정합니다.
    • digitalWrite(LED_BUILTIN, HIGH);: LED를 켭니다.
    • delay(1000);: 1초 동안 대기합니다.
    • digitalWrite(LED_BUILTIN, LOW);: LED를 끕니다.
    • delay(1000);: 1초 동안 대기합니다.

    millis() 함수

    millis() 함수란?

    millis() 함수는 아두이노가 켜진 후부터 경과한 시간을 밀리초 단위로 반환하는 함수입니다. 이 함수를 사용하면 프로그램이 멈추지 않고도 시간을 측정할 수 있어, 보다 정밀한 타이밍 제어가 가능합니다.

    예제 코드

    unsigned long previousMillis = 0;  // 이전 시간 값을 저장할 변수
    const long interval = 1000;        // 간격을 1초(1000 밀리초)로 설정
    
    void setup() {
      // 내장 LED 핀을 출력 모드로 설정
      pinMode(LED_BUILTIN, OUTPUT);
    }
    
    void loop() {
      unsigned long currentMillis = millis();  // 현재 시간 값을 읽어옴
    
      if (currentMillis - previousMillis >= interval) {
        // 간격이 지났다면
        previousMillis = currentMillis;  // 이전 시간 값을 현재 시간으로 업데이트
    
        // LED 상태를 반전시킴
        if (digitalRead(LED_BUILTIN) == LOW) {
          digitalWrite(LED_BUILTIN, HIGH);
        } else {
          digitalWrite(LED_BUILTIN, LOW);
        }
      }
    }

    코드 설명

    • unsigned long previousMillis = 0;: 이전 시간을 저장할 변수를 초기화합니다.
    • const long interval = 1000;: 간격을 1초로 설정합니다.
    • unsigned long currentMillis = millis();: 현재 시간을 읽어옵니다.
    • if (currentMillis - previousMillis >= interval) { ... }: 이전 시간과 현재 시간의 차이가 간격보다 크거나 같으면 LED의 상태를 반전시킵니다.

    코드 실행 결과 확인

    코드를 업로드하고 나면, 내장 LED가 1초 간격으로 깜빡이는 것을 확인할 수 있습니다. delay()millis()를 사용한 두 코드 모두 동일한 결과를 보이지만, millis()를 사용한 코드는 프로그램이 멈추지 않고도 타이밍을 제어할 수 있다는 장점이 있습니다. millis()를 활용한 코드에서는 LED가 점멸 하는 1초 사이에 다른 명령도 수행할 수 있다는 뜻이죠.

    delay()와 millis() 함수 활용하기

    이 두 함수를 응용하면 더욱 다양한 프로젝트를 만들 수 있어요. 예를 들어, 여러 개의 LED를 각각 다른 간격으로 깜빡이게 하거나, 버튼 입력에 따라 LED가 깜빡이는 속도를 조절할 수 있습니다.

    버튼 디바운싱 기능 구현

    버튼을 사용하여 LED를 제어할 때는 버튼의 물리적인 특성 때문에 떨림(Bouncing) 현상이 발생할 수 있습니다. 이 떨림을 제거하기 위해 millis() 함수를 사용하여 디바운싱을 구현할 수 있습니다. (버튼이 따닥!하고 빠르게 연속으로 눌리는건 무시하겠다 이거에요~)

    디바운싱 예제 코드

    const int buttonPin = 2;    // 버튼 핀 번호
    const int ledPin = LED_BUILTIN;  // 내장 LED 핀 번호
    
    int buttonState;             // 현재 버튼 상태
    int lastButtonState = LOW;   // 이전 버튼 상태
    unsigned long lastDebounceTime = 0;  // 마지막 디바운스 시간
    unsigned long debounceDelay = 50;    // 디바운스 지연 시간
    
    void setup() {
      pinMode(buttonPin, INPUT);
      pinMode(ledPin, OUTPUT);
      digitalWrite(ledPin, LOW);
    }
    
    void loop() {
      int reading = digitalRead(buttonPin);
    
      if (reading != lastButtonState) {
        lastDebounceTime = millis();
      }
    
      if ((millis() - lastDebounceTime) > debounceDelay) {
        if (reading != buttonState) {
          buttonState = reading;
          if (buttonState == HIGH) {
            digitalWrite(ledPin, !digitalRead(ledPin));
          }
        }
      }
    
      lastButtonState = reading;
    }

    디바운싱 코드 설명

    • const int buttonPin = 2;: 버튼이 연결된 핀 번호를 설정합니다.
    • int buttonState;: 현재 버튼의 상태를 저장하는 변수입니다.
    • unsigned long lastDebounceTime = 0;: 마지막으로 디바운스를 처리한 시간을 저장합니다.
    • unsigned long debounceDelay = 50;: 디바운스 지연 시간을 50 밀리초로 설정합니다.
    • void setup(): 버튼 핀을 입력 모드로, LED 핀을 출력 모드로 설정합니다.
    • void loop(): 버튼의 상태를 읽고, 버튼이 눌릴 때마다 디바운스를 처리하여 LED의 상태를 반전시킵니다.

    딜레이에 랜덤 첨가하기

    random() 함수를 이용하여 delay()를 랜덤으로 주는 코드를 작성하면 특정 범위 내에서 딜레이를 줄 수 있습니다. 예를 들어, LED를 깜빡이는 간격을 100ms에서 1000ms 사이의 랜덤한 시간으로 설정할 수도 있죠. 다음은 그 예제 코드입니다.

    void setup() {
      pinMode(LED_BUILTIN, OUTPUT);
      randomSeed(analogRead(0)); // 랜덤 시드 초기화
    }
    
    void loop() {
      digitalWrite(LED_BUILTIN, HIGH);
      delay(random(100, 1000)); // 100ms에서 1000ms 사이의 랜덤한 시간 동안 대기
      digitalWrite(LED_BUILTIN, LOW);
      delay(random(100, 1000)); // 100ms에서 1000ms 사이의 랜덤한 시간 동안 대기
    }

    이 코드를 사용하면 LED가 100ms에서 1000ms 사이의 랜덤한 시간 동안 켜지고 꺼지게 됩니다. 랜덤함수를 활용하면 특정 범위 내에서 딜레이를 줄 수 있어, 다양한 패턴을 쉽게 구현할 수 있습니다.

    아두이노 랜덤 구현 알아보기

    함수 사용시 주의점

    • delay() 함수는 프로그램 전체를 멈추기 때문에, 긴 시간 동안 사용하면 다른 작업을 할 수 없게 됩니다. 이를 해결하기 위해서는 millis() 함수를 사용하는 것이 좋습니다.
    • millis() 함수는 프로그램이 멈추지 않으므로 다른 작업을 동시에 수행할 수 있어, 복잡한 프로젝트에서 좀 더 유용하게 사용할 수 있습니다.

    마무리

    이번 프로젝트를 통해 delay()millis() 함수를 사용하는 방법과 그 응용 방법들에 대해 알아보았습니다. 두 함수 모두 타이밍 제어에 유용하지만, 각 함수의 특성을 이해하고 적절히 사용하는 것이 중요해요. 이제 더 복잡한 프로젝트에 도전해 볼 수 있는 지식이 생겼겠는걸요?