아두이노 코딩-42: millis() 명령에 의한 LED ON OFF 코딩

in #kr8 years ago

noname01.png

Delay() 명령을 사용하는 아두이노 코딩에 의한 LED ON OFF 코드를 Millis() 명령을 사용해 리모델링 해보자.

noname02.png

일정 시간 간격으로 껌뻑이는 바로 위의 아두이노 LED ON OFF 코드를 살펴보자.
loop() 내에서 디지털 핀 번호 3번의 LED를 ON 시키고 5000 msec 즉 5초 동안 delay() 명령을 수행한다. 이 delay() 명령도 일종의 명령이므로 아두이노 칩 내부적으로는 시간(time) 카운팅을 열심히 하고 있다고 보면 될 것이다.

5초에 걸쳐 delay() 명령을 수행하고 난 바로 다음 LED를 OFF 시킨 후 다시 5초 동안 delay() 명령을 수행하며 한 사이클이 끝남과 동시에 전원 스위치를 내릴 때까지 loop()문을 무한 반복하게 된다.

이 loop()문의 코드를 시간적으로 분석해 본다면 digitalWrite() 명령 수행은 불과 수십 μsec 이면 충분할 것이다. 그렇다면 이 한심스러운 아두이노 코드는 주어진 모든 시간을 어디에 사용하는 것일까? 쉽게 말하면 99.9999% 내부에서 시간 죽이기 카운팅을 하고 있는 셈이다.

무선 와이파이 기능을 바탕으로 하는 사물 인터넷 코드에서도 LED ON OFF 부터 출발점으로 삼는 것이 사실이다. LED 라고 하는 것은 물론 작은 LED 조명 그 자체일 수도 있지만 한편으로는 로봇이나 청소기 또는 자율운전 차량과 같은 사물인터넷에서라면 적어도 큰 전력 소모가 일어나는 시스템을 의미하게 되며 이러한 시스템 제어를 위한 ON OFF 문제로 귀착된다.

noname03.png

따라서 하나의 쥐방울만한 LED 이든지 또는 사물인터넷 시스템을 원격에서 무선 와이파이에 의해 끄고 켜기 위해서는 ON 과 OFF 사이에 사물에서 센싱한 데이터를 처리하고 난 후 판단에 따라 ON 이나 OFF 명령을 실행하게 되는 것이다.

즉 아두이노 코드 실행을 시간적으로 분석해 보면 사물로부터의 데이터 센싱 및 연산 처리에 거의 대부분의 시간을 소모하고 시스템 ON OFF 판단 후 아주 짧은 시간을 할애하여 ON OFF 작업을 실행하게 되는 것이다.

앞으로 포스팅하게 될 아두이노 무선와이 코딩 사례 경험에 비추어 보면 온습도 데이터를 그래프로 처리해 주는 ThingSpeak의 경우 데이터 1회 전송 최소 시간을 15초 이상으로 요구하고 있으며 아울러 전 세계를 상대로 기상 데이터를 제공하는 openweathermap 의 경우는 1회 기상 데이타 요구 최소 시간을 15분 단위로 규정하고 있다. 실제로 데이터 하나를 보내고 받는데 필요한 시간은 대체로 수초면 충분하므로 도대체 남는 시간에 아두이노는 무엇을 하고 놀아야 하는지 문제가 되는 것이다.

즉 앞으로 사물인터넷 코딩을 하겠다고 생각한다면 적어도 0.1초 또는 1초 이상 되는 단순 delay() 명령 사용을 가급적 배제하도록 코딩이 이루어져야 하며 여기서는 millis() 명령을 사용하는 아주 간단한 코딩 기법을 사용하여 LED ON OFF를 다시 코딩해 보기로 한다.

아래의 예제 코드는 아두이노의 붙박이 LED를 사용하여 간단히 실험해 볼 수 있는 예제 코드이다.

noname04.png

코드 전반부를 살펴보자. ledPin = 13 은 디지털 핀 13 번에 LED를 설치하여 ON OFF 한다는 설정이다. 하지만 13번 핀은 아두이노 우노 붙박이(Built-in LED) 이므로 별도로 LED를 설치하지 않아도 된다.

현재 코드 시작점에서의 LED 상태 즉 ledStat를 OFF 상태로 꺼져있는 LOW 로 설정해둔다.

long 변수 interval은 ON 이나 OFF 지속 시간 간격 1000msec 즉 1초로 설정해 둔다. long 변수 previousMillis 는 시작 초기 값을 0 으로 설정한다.

delay() 명령을 millis() 명령을 사용하여 대체하여 코딩하기로 하자. millis() 명령의 의미는 전원이 연결되어 업로딩된 아두이노 코드 실행 시작점으로부터의 경과 시간을 뜻하며 단위는 msec 이다.

millis() 명령의 한계 최대치는 아두이노 홈페이지 Reference 설명에 의하면 50일까지의 시간 측정이 가능하다고 하며 정수 중에서 가장 큰 수를 다룰 수 있는 unsigned long 정수형태의 변수로 받아서 설정한다.

noname05.png

일단 loop() 루틴이 실행 시작하는 현재까지의 경과 시간을 읽어서 currentMillis 로 둔다.
만약 currentMillis 와 previousMillis 와의 차이가 1000 msec 이상이라면 LED ON 또는 OFF 를 실행하기 위한 if 제어문을 실행하도록 한다.

if 문에서 우선 currentMillis 를 previousMillis 로 저장한 후에 내부의 if 문에서 ledState 가 만약 LOW 라면 ledState를 HIGH로 설정하며 그렇지 않은 경우는 LOW 로 설정한다. 따라서 처음 시작에서는 LOW에서 출발하여 HIGH로 변경되게 된다. 내부 if 문에서 ledState 가 설정되고 나면 digitalWrite() 명령을 실행한다.

현재의 코드에서는 데이터 센싱 및 처리 코드가 없는 상태이나 실제 사물인터넷 코딩에서는 온습도 측정이라든지 센싱 및 처리 과정 또는 사용자 서비스를 위한 루틴들이 반드시 있게 마련이다.

아래의 예제 코드를 컴파일 업로딩하여 delay() 명령이 없이 millis() 명령만을 사용한 코딩도 동일한 효과를 줄 수 있다는 점을 다음 동영상을 통해서 확인하자.

//Millis_LED_ON_OFF_01
int ledPin = 13;
int ledState = LOW;
long interval = 1000;
long previousMillis = 0;
void setup() {
// put your setup code here, to run once:
Serial.begin(9600);
pinMode(ledPin,OUTPUT);
}
void loop() {
unsigned long currentMillis = millis();
if( currentMillis - previousMillis > interval ) {
previousMillis = currentMillis;
if( ledState == LOW ) {
ledState = HIGH;
}
else {
ledState = LOW;
}
digitalWrite(ledPin,ledState);
}
}// 프로그램 끝

Sort:  

짱짱맨 호출에 출동했습니다!!

@therealwolf 's created platform smartsteem scammed my post this morning (mothersday) that was supposed to be for an Abused Childrens Charity. Dude literally stole from abused children that don't have mothers ... on mothersday.

https://steemit.com/steemit/@prometheusrisen/beware-of-smartsteem-scam

Coin Marketplace

STEEM 0.04
TRX 0.33
JST 0.094
BTC 62600.26
ETH 1750.35
USDT 1.00
SBD 0.39