Thinking Different




 

하드웨어는 지난 시간까지 다 구성하였습니다. 이제 남은건 소스코드를 작성하여 정상적으로 작동하도록 코드 작성을 진행해 보도록 하겠습니다.

 

이번 시간에는 아두이노 초기화 부분과 온 습도 값을 읽어서 처리하는 코드를 작성하도록 하겠습니다.

 

아두이노의 경우 setup() 함수와 loop() 함수로 이루어지며, setup()의 경우 최초 아두이노 구동시 1번 구동되고 loop() 함수가 반복적으로 구동되는 코드로 이루어져 있습니다.

 

우리는 setup() 함수에 초기화 부분을 설정하고 나머지 구동되는 코드를 loop() 함수로 작성하면 되겠습니다.

 

 

 

아두이노에서 사용되는 포트를 define 하고 setup() 함수에서 초기화하여 사용할 수 있도록 코드를 구성하고, DHT11 온습도 센서와 NTC 온도센서를 사용할 수 있도록 함수와 코드를 구성해 보도록 하겠습니다.

 

아래는 코드 전문입니다. 

(모든 소스코드는 분할 코딩 되어 있습니다)

 

 

Incubator_Main.ino

#include <avr/wdt.h> // 와치독
#include <DHT.h>  // DHT11 사용시 필요한 헤더파일

// 아두이노 핀 설정
#define BUTTON_SETUP    2   // 설정
#define BUTTON_UP       3   // ↑
#define BUTTON_DOWN     4   // ↓
#define BUTTON_SAVE     5   // SAVE
#define BUTTON_RESET    6   // RESET
#define HUMIDITIER      7   // 가습기
#define HUMIDITY_SENSOR 8   // 습도 센서
#define LIGHT           9  // 전등   (220v 릴레이)
#define EGG_MOVER       10  // 전란기 (220v 릴레이)
#define FAN             11  // Fan
#define NTC_PIN         A7  // NTC 온도 센서

extern float NTC;       // 온도
extern float humidity;  // 습도

unsigned long beforeTime;  // 이전시간
unsigned long nowTime = 0; // 현재타이머시간

int day, hour, min, sec;

DHT dht(HUMIDITY_SENSOR, DHT11); // DHT11 객체 생성


void setup()
{
  pinMode(FAN, OUTPUT);         // 팬
  pinMode(LIGHT, OUTPUT);       // 전구
  pinMode(EGG_MOVER, OUTPUT);   // 전란기
  pinMode(HUMIDITIER, OUTPUT);  // 가습기 ON OFF

  // 버튼 (풀업 저항 사용)
  pinMode(BUTTON_SETUP, INPUT_PULLUP);     // 설정 버튼
  pinMode(BUTTON_UP, INPUT_PULLUP);        // ↑
  pinMode(BUTTON_DOWN, INPUT_PULLUP);      // ↓
  pinMode(BUTTON_SAVE, INPUT_PULLUP);      // MODE (SAVE로 사용)
  pinMode(BUTTON_RESET, INPUT_PULLUP);     // RESET

  dht.begin();               // DHT11 객체 초기화
  beforeTime = millis();     // 이전 시간 설정
  
  wdt_enable(WDTO_4S); // 와치독 타이머 설정 (시스템 다운시 자동 재부팅 시작)
}

void loop() 
{
  // 이전 시간보다 1초가 지났다면
  if(millis()-beforeTime>=1000)
  {
    // 시간 카운트(초)
    nowTime++;
    beforeTime = millis();

    // 온도 습도 읽기
    GetTempHumi();

    // 와치독 리셋
    wdt_reset();
  }
}

 

 

 

_readHumidity.ino

#define R1 10000      // 저항의크기(10k옴 = 10000옴)

float NTC = .0f;      // 온도
float humidity = .0f; // 습도

// 온도 습도 읽기
void GetTempHumi()
{
  // 습도 읽기
  humidity = dht.readHumidity();

  //NTC서미스터 온도 구하기
  float voltage_value = analogRead(NTC_PIN);
  float voltage = (5.0 * voltage_value) / 1023.0;

  float R2 = (5.0 * R1) / voltage - R1;
  NTC = 1.0 / ((1.0/(273.15 + 25.0)) + (log(R2/R1)/3435.0)) - 273.15;
}

 

 

 

_time.ino

#define MIN 60
#define HOUR (60*60)
#define DAY (60*60*24)

// 초 -> 시분초
void GetSecToTimeDay()
{
  // 초 -> 일시분초
  sec = nowTime%MIN;
  min = (nowTime/MIN)%MIN;
  hour = ((nowTime/HOUR)%HOUR)%24;
  day = (nowTime/DAY)%DAY;
}

// 시분초 -> 초
void GetTimeDayToSec()
{
  // 시분초 -> 초
  nowTime = (long)day * DAY;
  nowTime += (long)hour * HOUR;
  nowTime += (long)min * MIN;
  nowTime += sec;
}



(1) 내부 풀업 저항

우리는 버튼 회로를 구성할 때 따로 10k 의 저항을 구성하지 않았습니다. 내부 풀업 저항을 사용하기 위해서 였습니다.

pinMode 함수내에서 INPUT_PULLUP 옵션을 설정하는 것으로 내부 풀업 저항을 사용하는 것을 설정할 수 있습니다.

 

(2) millis 와 delay

아두이노의 loop() 함수 내에서는 delay() 라는 함수를 사용하지 않고 코딩하는것이 가장 좋습니다.

delay는 강제적으로 모든 동작을 대기상태로 넣어버리게 되어 내장된 카운터의 시간과 실행되는 코드의 시간 간격이 조금씩 틀어지게 되고 추후에는 치명적으로 문제가 발생할 수 있는 요지가 있습니다.

 

이를 방지하기 위해서 millis() 함수를 이용해서 시간값을 측정하여 1초마다 카운트 시켜서 실행되는 코드를 작성하여 구동할 수 있도록 작성하였습니다.

 

(3) 와치독 설정

예상치 못한 아두이노 시스템의 물리적인 오류나 기타 버그 등으로 인해 코드가 실행되지 않을 경우 설정된 와치독 타이머 시간(4S) 을 기다리다가 wdt_reset() 함수가 실행되지 않으면 강제적으로 reset 시켜줍니다. 이는 물리적 reset 버튼을 누른 것과 같습니다.

 

(4) 습도 및 NTC 온도

부화기 및 육추기의 경우 온도가 민감한 부분이므로 DHT11 센서의 경우 온도 편차가 심하여 정밀한 NTC 써미스터 온도센서를 사용하여 온도를 구성하였습니다. 여기서는 10k옴 짜리를 연결한 센서를 구성하였으며 +- 0.5도 내외의 아주 정밀한 온도값을 나타내 주었습니다.

 

 

 

소스코드의 경우 양이 너무 많아서 탭을 생성하여 코드를 분할 코딩하였습니다. 추후 최종 업로드시 소스코드를 첨부하도록 하겠습니다.