?>

Hard Copy World

HCW

Arduino beginner

Home > Learning >

Arduino beginner

아두이노 기초 강좌 13 – 시간에 따른 작업 관리 millis()

페이지 정보

작성자 하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물 작성일14-11-03 18:09 조회17,796회 댓글3건

본문

아두이노 기초 강좌는 아두이노를 처음 접하시는 전자분야 비 전공자를 위한 강좌입니다. 이해를 위해서는 간단한 프로그래밍 지식이 필요할 수 있습니다. 프로그래밍이 처음이라면 [아두이노 프로그래밍 기초] 강좌를 먼저 읽으시길 권해 드립니다.

===============================================================

 

1. 아두이노의 시간 함수 millis()

 

앞선 강좌 12에서 delay 함수와 주의점에 대해서 살펴봤습니다. 버튼 입력처럼 빠르게 입력 상태를 체크해야 하는 경우 delay는 독이 될 수도 있다고 했죠.

그런데 앞선 강좌 12의 버튼 예제를 실행해보면 PC의 Serial monitor에 굉장히 빠르게 버튼의 상태가 표시됩니다. 아래처럼요.

000000011111100000...

보기도 불편하고 필요없이 PC로 너무 자주 데이터를 보내는 것 같습니다. 버튼의 상태 체크는 빠르게 계속 하면서 PC로 데이터를 보내는 것은 긴 간격(1초 정도?)으로 조절할 필요를 느끼실 겁니다.

그래서 필요한 것이 시간 함수 millis() 입니다.

unsigned long currentMillis millis();

위와 같이 사용하면 millis() 함수가 현재시간(아두이노가 시작된 후부터 경과된 시간)을 밀리초 단위로(1/1000 초) 리턴해줍니다. 이걸 loop() 반복문을 돌때마다 체크하면 경과된 시간이 얼마인지를 알 수 있습니다.

이제 강좌 12에서 사용한 소스를 수정해 보겠습니다. 사용자 입력을 놓치지 않도록 버튼은 빠르게 계속 체크하면서, 1초에 한 번씩 PC로 버튼 상태를 전송하도록 하겠습니다.

 

2. 수정된 소스 예제

 

수정된 소스부터 보시죠.

// digital pin 2 has a pushbutton attached to it. Give it a name:
int pushButton = 2;

void setup() {
  // initialize serial communication at 9600 bits per second:
  Serial.begin(9600);
  // make the pushbutton's pin an input:
  pinMode(pushButton, INPUT);
}

int isClicked = LOW;
unsigned long prev_time = 0;

void loop() {
  // read the input pin:
  int buttonState = digitalRead(pushButton);
  if(buttonState == HIGH) {
    isClicked = HIGH;
  }
  
  unsigned long current_time = millis();
  
  // if 1 second has passed after last check
  if(current_time - prev_time > 1000) {
    // print out the state of the button:
    Serial.println(isClicked);
    isClicked = LOW;
    prev_time = current_time;
  }
  
  delay(1);        // delay in between reads for stability
}

 

수정된 부분 위주로 살펴 보겠습니다.

int isClicked = LOW:
unsigned long prev_time = 0;

 PC로 메시지를 보내기 전 1초 동안 클릭이 있었는지 저장하기 위해 isClicked 변수를 전역으로 만들었습니다. prev_time 변수는 PC로 메시지를 보내면 현재 시간을 저장해 두는 용도로 씁니다. 다음번 1초 경과를 체크할 때 이 값을 가지고 계속 비교합니다.

알고 갑시다!! 시간을 저장하는 prev_time 값은 unsigned long 형태입니다. 시간은 무조건 양수의 값을 사용하기 때문에 음수의 값을 사용하지 않고, 대신 저장할 숫자의 크기를 늘린겁니다. unsigned 구문이 의미하는 것이 이것입니다. 아두이노에서는 long 이 4byte 이고 [-2,147,483,648 ~ 2,147,483,647] 사이의 정수를 표현합니다. unsigned long은 음수를 버리는 대신 양수의 표현 범위가 2배로 늘어납니다. unsigned long으로 시간을 표현할 때 아두이노 실행 후 약 50일이 지나면 최대값에 도달하는데, 최대값이 되면 다시 0부터 계산하게 됩니다.

 

이제 loop 반복문 안을 살펴보겠습니다.

  // read the input pin:
  int buttonState = digitalRead(pushButton);
  if(buttonState == HIGH) {
    isClicked = HIGH;
  }

 

사용자가 버튼을 누를 경우 buttonState 값은 HIGH 가 됩니다. HIGH 일 때 isClicked 값도 HIGH 로 기록해주면 1초 동안 한번이라도 사용자 입력이 감지되면 클릭이 된걸로 간주합니다. 1초 뒤 PC로 데이터를 보내고 나면 isClicked 값을 LOW로 초기화 해줘야 합니다. 다음 1초 동안의 사용자 입력 여부를 기록해야 하니까요.

  unsigned long current_time = millis();

 

current_time 에 현재 시간을 기록해 둡니다. 이걸 미리 기억해둔 prev_time 과 비교해서 1초(=1000 ms)가 지났는지 확인할겁니다. 

  // if 1 second has passed after last check
  if(current_time - prev_time > 1000) {
    // print out the state of the button:
    Serial.println(isClicked);
    isClicked = LOW;
    prev_time = current_time;
  }

현재 시간에서 prev_time(지난번에 처리한 시간) 을 뺀 값이 1000 보다 크면 1초가 지난겁니다. 따라서 이때는 PC로 버튼 상태를 전송해주고, 다음번 체크를 위해 isClicked를 LOW로 초기화하고 prev_time 을 현재 시간인 current_time으로 교체합니다.

 

이 코드를 실행해보면 PC로 약 1초 마다 버튼 클릭여부가 전송될겁니다.

시간 함수 millis() 를 이용한 위와 같은 형태의 루틴은 사용할 일이 많습니다. 아두이노 뿐 아니라 다른 프로그래밍 언어나 플랫폼에서도 동일하니 기억해 둘 만한 코드입니다.

 

 

===============================================================

이 문서는 작성자의 동의없이 개인적인 목적 외의 상업적인 목적으로 활용되어서는 안됩니다.

이 문서의 일부 혹은 전체를 수정, 삭제, 재배포 하여서는 안됩니다.

작성자 : GodsTale (godstale@hotmail.com)  


하드카피 쪽지보내기 메일보내기 자기소개 아이디로 검색 전체게시물

모든 전통이 한 때는 오해를 면치 못했다. 마찬가지로 모든 아이디어는 한 때는 비웃음을 면치 못했다. -홀브룩 잭슨 ::::: 느닷없이 떠오르는 생각이 가장 귀중한 것이며, 보관해야할 가치가 있는 것이다. -베이컨 ::::: 미리 숙고하면 힘든 일도 그저 실행에 옮기는 순간 쉬워진다. - 로버트 M. 피어식

추천 0
  • 페이스북으로 보내기
  • 트위터로 보내기
  • 구글플러스로 보내기

댓글목록