====== 타이머 만들기 ======
앞서 만든 기초 소스에 타이머를 추가해 보겠습니다. 타이머는 자동화 현장에서 매우 자주 사용됩니다.
===== On Timer ======
일정 시간 신호가 들어왔을때, 비로소 출력을 하는 가장 기본적인 타이머입니다.
2개의 타이머 관련 배열이 필요합니다.
#define timerMaxLimit 20
uint8_t Tstat[timerMaxLimit]; // Timer status
uint32_t Tvalue[timerMaxLimit]; // Timer Current Value
이 예에서는 총 20개의 타이머만 사용하였습니다. 위 20이라는 숫자를 바꾸면 타이머 갯수를 조정할 수 있습니다.
* Tstat배열 : 타이머의 상태를 저장합니다. 1이면 On, 0이면 Off라는 뜻입니다.
* Tvalue배열 : 타이머의 증가 감소 값을 저장하는 배열입니다.
OnTimer가 어떻게 동작하는지 보겠습니다.
{{ :modularfaduino:timerprogram:ontimer1.png?nolink |}}
입력(Input)이 들어오면 지정한 시간(Time)이 경과된 뒤 비로소 출력(Tstat)가 켜집니다.
#include "CFMEGA.h"
CFNET cfnet;
uint8_t X[128]; // Input Coil
uint8_t Y[128]; // Output Coil
void distribute_value(uint16_t val, uint8_t where) {
for (int i = 0; i < 16; i++) {
X[where++] = val & 0x01;
val >>= 1;
}
}
void input_proc() {
for (int i = 0; i < 8; i++) {
distribute_value(cfnet.digitalRead(i), i * 16);
}
}
uint16_t collect_value(uint8_t where) {
uint16_t tempV = 0;
for (int i = 0; i < 16; i++) {
tempV |= Y[where++] << i;
}
return tempV;
}
void output_proc() {
for (int i = 0; i < 8; i++) {
cfnet.digitalWrite(i, collect_value(i * 16));
}
}
ISR(TIMER5_OVF_vect)
{
TCNT5 = 198; // for 20mS
sei(); // Start Gloval Interrupt
timertn_proc();
input_proc();
logic_proc();
output_proc();
tick_flag = 0;
}
// Timer
uint16_t system_timer=0, tick_flag=0;
#define timerMaxLimit 20
uint8_t Tstat[timerMaxLimit]; // Timer status
uint32_t Tvalue[timerMaxLimit]; // Timer Current Value
void timertn_proc() {
system_timer++;
if (system_timer == 5) {
tick_flag = 1; // Turn On every 100mS
system_timer=0;
}
}
void onTimer(uint8_t inputValue, uint8_t timerIndex, uint16_t timerInitValue)
{
if (tick_flag) {
if (inputValue) {
if (Tvalue[timerIndex] < timerInitValue) {
Tvalue[timerIndex]++;
if (Tvalue[timerIndex] == timerInitValue) {
Tstat[timerIndex] = 1;
}
}
} else {
Tvalue[timerIndex] = 0;
Tstat[timerIndex] = 0;
}
}
}
//
// User Source
//
void setup() {
TCCR5B = 5; // Clock source from system clock/1024
TIMSK5 |= 1; //TOV interrupt set.
sei(); // Start Gloval Interrupt
// Clear Timer array
for (int _i=0; _i < timerMaxLimit; _i++) {
Tstat[_i] = 0;
Tvalue[_i] = 0;
}
}
void loop() {
}
// Run every 20mS
void logic_proc()
{
Y[0] = X[0]; // Main Logic Program
onTimer(X[0],0,8); // 800mS On Timer
Y[1] = Tstat[0]; // Watch Tvalue
}
====== onTimer ======
이 소스에서 맨밑 logic_proc를 보면 onTimer를 사용한 부분이 보입니다.
''void onTimer(입력소스, 타이머 번호, 경과시간) ''
| 입력 소스 : 여기에서는 X[0] 입력을 사용하였습니다. |
| 타이머 번호 : 여기에서는 0번 타이머를 사용하였습니다. |
| 경과시간 : 타이머 값입니다. 여기에서는 8 즉, 0.8S를 뜻합니다. 이 타이머는 0.1초 단위입니다. |
따라서, 위 소스가 실행되면, X[0]이 입력되었을때, 0.8초후에 타이머0이 출력됩니다. 그 결과를 Y[1]에서 보실 수 있습니다.
==== 주의 ====
시간 지연이 필요할때 초보자분들은 delay함수를 사용하는데, 이 경우 delay를 하는 동안 다른 신호를 처리할 수 없기 때문에, 정상적인 흐름이 불가능합니다.
[[modularfaduino:index|Modular FADUINO]]