millis함수 사용하기
아두이노에는 시간과 관련된 함수가 여러 가지가 있습니다.
대표적으로 delay 와 delaymicroseconds가 있습니다. 이 두 함수는 지정된 시간 동안 코드를 멈추는 것입니다.
이 함수들은 어떠한 복잡한 로직 없이 실행을 지연시키기 때문에 간단하게 LED를 점등하고 소등하는 기능을 구현할 수 있지만 가장 큰 단점으로는 그 시간 동안은 아무런 작업도 못한다는 겁니다. 예를 들어 delay가 실행중일 때 버튼을 눌러 다른 기능을 수행시킬 때 버튼 입력코드 자체가 delay로 인해 동작을 못하게 되는 것입니다.
그래서 아두이노를 본격적으로 공부하고 프로젝트를 진행할 때는 웬만해서 delay함수는 사용하지 않는 것이 좋습니다.
그림으로 설명하면 이렇습니다.
스위치가 눌렸는데 그때는 아두이노가 delay 때문에 자고 있는 상태입니다.
그러면 아무 일도 못하기 때문에 스위치가 눌린 걸 감지하지 못하게 됩니다 ㅠㅠ
아두이노에게 쉬는 시간을 주면 안 됩니다!
그래서 저희는 아두이노가 계속 일을 하면서 정해진 시간에 일을 하도록 코드를 작성해야 합니다.
그러기 위해서는 millis()라는 함수를 알아야 합니다. 이 함수는 아두이노가 부팅(전원이 들어간 시점)에서부터 시간을 반환하는 함수입니다. 쉽게 말해서 아두이노가 켜지고 지금까지의 시간을 측정하는 함수입니다.
그럼 이 함수를 사용해서 delay 같은 나쁜 함수를 대신하는 방법을 설명하고 예제를 통해 사용법을 알아보겠습니다.
unsigned long timer_1 = 0;
void setup() {
timer_1 = millis();
}
void loop() {
if(millis() - timer_1 >= 1000){
timer_1 = millis();
//실행코드 작성
}
}
delay(1000)과 동일한 기능을 수행하면서 다른 로직또한 수행할 수 있는 코드입니다.
생각보다 간단하죠 ㅎㅎ
먼저 시간을 비교하기 위한 unsigned long 타입의 변수를 하나 만들어주세요 저는 timer_1이라는 이름으로 만들었습니다.
그리고 setup안에서 timer_1에 현재 아두이노가 실행된 시간을 넣습니다. 그리고 loop문에서 조건문을 하나 만들고 조건식으로 실시간으로 아두이노가 실행되는 시간과 timer_1의 차를 구해서 1000보다 커지게 되면 조건문의 내용을 실행시키는 코드입니다. 그리고 실행문 안에 timer_1 변수에 다시 현재 아두이노가 실행된 시간을 넣습니다. 이 과정을 계속 반복하게 됩니다.
중요한 것은 millis함수가 있는 코드에는 어쩔 수 없는 경우를 제외하고는 delay함수를 사용하면 안 됩니다.
이유는 millis로 시간을 측정하는 로직의 정확도가 떨어지게 되기 때문입니다.
그리고 사실 이 로직은 실행 코드가 많아질수록 정확도가 떨어지게 되는 사실상 불안전한 코드입니다.
비교 연산자를 >= 를 사용한 이유가 정확하지 못하기 때문입니다.
즉 이 코드를 오래 실행하게 된다면 시간적 오차로 인해 실제 시간과 오차가 생기게 될 것입니다.
그래서 이런 오차를 조금이라도 없애기 위한 로직을 제가 생각해 봤습니다.
그리고 이것이 오차를 줄이기 위한 코드입니다.
unsigned long timer_1 = 0;
void setup() {
timer_1 = millis();
}
void loop() {
if(millis() - timer_1 >= 1000){
timer_1 = millis() + (millis() - timer_1 - 1000);
//실행코드 작성
}
}
timer_1 변수에 오차가 발생한 만큼 + 해서 다음 돌아올 때의 오차를 줄이도록 하는 코드입니다.
물론 이 코드 또한 100% 정확하지는 않습니다.
이상으로 millis함수에 대한 설명을 마치겠습니다. 감사합니다.