아두이노 강좌 #3 시간 관련 함수 설명, delay() 없이 LED Blink 코드 작성
Lucy Archive
Lucy 2023
2020. 7. 2. 00:52
delay() millis() delayMicroseconds() micros()

delay() delayMicroseconds() millis() micros()

  아두이노에서는 일정 시간 동안 프로그램을 멈추거나, 특정 순간부터 시간을 측정 할 수 있는 [각주:1]함수를 제공합니다. 시간 지연 함수는 delay(), delayMicroseconds() 가 있고, 시간을 측정하는 함수는 micros(), millis() 가 있습니다. 이 함수들을 사용하여 1초마다 온도 센서의 값을 PC로 데이터 송신하거나, 0.5초 이내에 버튼이 두 번 눌리면 더블 클릭 같은 기능을 추가하는 방법 등 다양한 방법으로 프로그램 개발이 가능합니다. 
  본 포스트에서는

아두이노에서 제공하는 시간 함수 사용법과 내장 LED를 사용한 간단한 예시

를 작성하였습니다. 

시간 지연 vs 시간 측정 차이

delay() 와 millis() 함수 느낌 차이delay() 와 millis() 함수 느낌 차이

아두이노에서 시간 지연 함수와 시간 측정 함수로 프로그래밍을 한다는 것은 위와 같은 명령의 차이입니다. 

  ①로 지시 받은 박과장은 하던 것을 멈추고, 아무것도 못하는 상태로 5분을 보내다가 요청 받은 일을 처리합니다. 지시 받은 박대리는 아무것도 못하고 답답한 채로 1분을 보내고 요청받은 일을 하겠지만, 지시하는 입장에서는 일 시키기가 간단하고 아무것도 하지 못하게 했기 때문에, 지시한 일에 대한 결과가 잘 못될 염려가 없습니다.

  하지만, ②로 지시 받은 박과장는, 하던 일을 멈추지 않거나, 5분 동안 잠시 다른 일을 하고 와서 요청 받은 일을 수행 할 수 있습니다. 다른 일을 하는 중에 중간 중간 시계를 보며 5분이 되어가는지 확인을 해야 합니다. 지시하는 입장에서도 5분 동안 아무것도 한 것과 다르게, 다른 일을 할 수 있어 지시한 일에 대해 영향을 주는 변수가 생길 수 있다는 염려가 있을 수 있습니다.

  위의 ①과 같은 방식이 시간 지연, ②와 같은 방식이 시간을 측정 하는 방식으로 업무를 지시 하는 방법입니다. 아두이노 프로그램에도 시간 지연 함수와, 시간 측정 함수가 있습니다.

  • 시간 지연 : delay(), delayMicroseconds()
    • 장점 : 프로그래밍 간단함
    • 단점 : 지연되는 시간 동안 아무 것도 못함
  • 시간 측정 : millis(), micros()
    • 장점 : 특정 기능 동작해야 하는 시점 가지 여러가지 일을 같이 할 수 있음
    • 단점 : 프로그램이 복잡함

시간 함수 정의

delay()

  milliseconds 단위로 프로그램을 멈춥니다. ms 입력되는 변수 타입은 unsigned long(4byte) 으로 0 ~ 4,294,967,295 까지 입력이 가능 합니다. 즉, delay() 함수는 최대 49.7日 까지 지연이 가능합니다.

Syntax : delay(ms)

Parameters

  • ms : 밀리 초 단위의 숫자 (Data type : unsigned long)

Return : 없음

Example

  • delay(1000) : 1s (1000ms) 동안 프로그램 멈춤
  • delay(500) : 0.5s 동안 프로그램 멈춤

delayMicroseconds()

  microseconds 단위로 프로그램을 멈춥니다. us 입력되는 변수 타입은 unsigned int(2Byte) 으로 0 ~ 65,535 까지 입력이 가능합니다. 즉, microseconds() 함수는 최대 65ms 까지 지연이 가능합니다.

Syntax : delayMicroseconds(us)

Parameters

  • us : 마이크로 초 단위의 숫자 (Data type : unsigned int)

Return : 없음

Example

  • delayMicroseconds(50) : 50us 동안 프로그램을 멈춥니다.
  • delayMicroseconds(1000) : 1ms(1000us) 동안 프로그램을 멈춥니다.

millis()

  아두이노 프로그램이 시작된 시간을 기준으로, 현재 시간을 ms 단위로 반환합니다. 약 49.7日 까지 시간 측정이 가능합니다. 49.7日이 지나면 (오버플로우가 발생하여) 0ms 로 초기화 됩니다. 

  millis() 로 반환되는 값을 저장하는 변수는 unsgined long 으로 선언되어야 합니다.

Syntax : time = millis()

Parameters : 없음

Returns

  • 프로그램이 시작되고 현재 시간을 ms 단위로 반환 합니다.
  • 약 49.7日 이 경과한 경우 0으로 초기화 됩니다.
  • Data Type : unsgined long

micros()

  아두이노 프로그램이 시작된 시간을 기준으로, 현재 시간을 us 단위로 반환합니다. 약 70분 정도까지 측정이 가능합니다. 약 70분이 지나면 (오버플로우가 발생하여) 0 으로 초기화 됩니다. 

  micros() 로 반환되는 값을 저장하는 변수는 unsigned long 으로 선언되어야 합니다.

Syntax : time = micros()

Parameters : 없음

Returns

  • 프로그램 시작되고 현재 시간을 us 단위로 반환
  • 약 70분 경과한 경우 0으로 초기화
  • Data Type : unsigned long

시간 함수로 LED 깜빡이기

delay() 함수와 delayMicroseconds() 는 사용 법이 비슷하고, millis() 와 micros() 함수는 사용법이 비슷하므로, delay() 함수와 millis() 함수를 사용하여 500ms 마다 Arduino Uno LED가 깜빡이는 코드를 작성하고 비교해 보겠습니다.

delay() 함수로 LED Blinking

1
2
3
4
5
6
7
8
9
10
void setup(){
    pinMode(13OUTPUT); // 13번핀 출력 설정
}
 
void loop(){
    // 13번핀 현재 전압의 반전된 값으로 출력
    // HIGH 일경우 LOW로, LOW일 경우 HIGH 로 반전 출력
    digitalWrite(13!(digitalRead(13))); 
    delay(500);
}
cs

millis() 함수로 LED Blinking

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
unsigned long past = 0// 과거 시간 저장 변수
int flag = 0// 과거 기준 시간 보다 500ms 이상 지날 경우를 판단하는 flag
 
void setup(){
    pinMode(13OUTPUT);
}
 
void loop(){
    unsigned long now = millis(); // 현재 시간을 저장
    
    // 현재 시간이 과거 시간보다 500ms 지났을 때
    // 과거 시간에 현재 시간을 저장
    // 500ms 시간이 지낫음을 알려 주는 flag 를 1로 활성화
    if(now - past >= 500){ 
        past = now;
        flag = 1;
    }
 
    // flag 가 1인 경우 
    // LED를 현재 상태 반전으로 출력
    // flag 를 0으로 초기화
    if(flag == 1){
        digitalWrite(13!(digitalRead(13)));
        flag = 0;
    }
 
}
 
cs

결과 비교 하기

  위의 두 가지 코드 동작은 동일합니다. 큰 차이가 있다면, millis() 로 사용한 코드는 복잡하지만, 추가 다른 기능을 넣어도 LED 가 500ms 마다 깜빡이는 기능은 그대로 유지 할 수 있습니다. 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
unsigned long past = 0// 과거 시간 저장 변수
int flag = 0// 과거 기준 시간 보다 500ms 이상 지날 경우를 판단하는 flag
 
void setup(){
    pinMode(13OUTPUT);
}
 
void loop(){
    unsigned long now = millis(); // 현재 시간을 저장
    
    // 현재 시간이 과거 시간보다 500ms 지났을 때
    // 과거 시간에 현재 시간을 저장
    // 500ms 시간이 지낫음을 알려 주는 flag 를 1로 활성화
    if(now - past >= 500){ 
        past = now;
        flag = 1;
    }
 
    // flag 가 1인 경우 
    // LED를 현재 상태 반전으로 출력
    // flag 를 0으로 초기화
    if(flag == 1){
        digitalWrite(13!(digitalRead(13)));
        flag = 0;
    }
 
    /* ex) 추가 기능 1 - 센서 입력 받아서 제어 */
 
    /* ex) 추가 기능 2 - PC와 시리얼 통신 */
 
    /* ex) 추가 기능 3 - 모터 동작 하기/
}
cs

마무리

  본 포스트에서 아두이노에서 제공되는 시간 함수에 대해 알아보았습니다.   

  delay() 함수는 프로그램을 중지시키는 방식으로, 복잡한 프로그래밍을 작성시 지양해야 할 함수입니다. 특정한 시간마다 이벤트를 발생시키면서 다른 기능들을 함께 수행하고자 할 때는 시간을 측정하는 millis() 함수를 대신하여 사용 할 수 있습니다. 이외에도 멀티테스킹 같은 효과를 만들어 주는 방식은 Timer, Interrupt 등의 방식으로 구현 할 수 있으며, 추후 포스트에서 자세히 다루도록 하겠습니다.

  끝까지 읽어 주셔서 감사합니다.^^

관련포스트

👉 아두이노 전체글 목록 보기

👉 아두이노 디지털 입출력 관련글 목록 보기

👉 아두이노 타이머 관련글 목록 보기


  1. Arduino Reference : https://www.arduino.cc/reference/en/#functions [본문으로]