아!두이노, 라즈베리, 코딩 노가다

지능형 온도 경고 시스템 #6 (아두이노 우노 R4 러닝 키트) 본문

아두이노/센서

지능형 온도 경고 시스템 #6 (아두이노 우노 R4 러닝 키트)

아이스뭐라카노 2026. 10. 2. 10:45
반응형

본 리뷰는 IC뱅크에서 제품을 무상 제공받아 작성된 체험 리뷰 입니다. 스폰서 배너 삽입 및 표시 광고법 문구 포함이 됩니다.

본  포스팅은 제품을 무상 제공받아 작성된 체험단 리뷰입니다.

아두이노 우노 R4러닝 키트  https://vo.la/ITrP1f3

 

아두이노 우노 R4 러닝 키트 : 신제품 > NEW 코딩교육몰

아두이노 기본 실습과 IoT 프로젝트 실습에 효율적인 키트입니다.아두이노 UNO R4 WiFi 메인보드를 사용하고 26개의 전자 모듈을 하나의 PCB에 통합하였습니다. - 130000원 국내 최대 전자부품 전문 쇼

www.icbanq.com

 

 

 

차분하게 전체 코드를 숙지해 보자, 약간 길수도 있지만 이정도 코드를 10분정도에 숙지 할 수 있어야 현업에서 적응 할 것이다.

 

//#include <Wire.h>          // I2C 통신 라이브러리
#include "DHT20.h"         // DHT20 온습도 센서 라이브러리

// 핀 번호 정의
#define LED_RED     11     // 빨간색 LED
#define LED_YELLOW  10     // 노란색 LED
#define LED_GREEN   9      // 초록색 LED
#define BUZ         3      // 부저

/*
 * 아두이노 DC 모터 제어 (L298N 드라이버)
 *
 * 배선
 *   L298N ENA -> D6  (PWM, 속도 제어 / ENA 점퍼 캡은 제거)
 *   L298N IN1 -> D5
 *   L298N IN2 -> D4
 *   L298N OUT1, OUT2 -> DC 모터
 *   L298N 12V -> 모터용 외부 전원(+)
 *   L298N GND -> 외부 전원(-) 및 아두이노 GND (반드시 공통 접지)
 */

const int PIN_ENA = 6;   // PWM
const int PIN_IN1 = 5;
const int PIN_IN2 = 4;

int motorSpeed = 180;    // 0~255
int direction = 0;       // 1=정방향, -1=역방향, 0=정지


DHT20 DHT;                 // DHT20 센서 객체 생성

// 온도 기준값 (필요에 따라 수정 가능)
// 상태 표시 기준이자 팬 제어 기준으로 함께 사용
#define TEMP_NORMAL_MAX   28.0   // 이 온도 미만이면 정상 / 팬 OFF 기준(하한)
#define TEMP_HIGH_MAX     32.0   // 이 온도 미만이면 주의, 이상이면 경보 / 팬 ON 기준(상한)

bool control(double , double, double);
void fancontrol(bool onoff);
void normalState();
void warningState();
void alarmState();
void setMotor(int dir, int speed);

void setup() 
{
  Serial.begin(115200);    // 시리얼 모니터 통신 시작 (속도 115200bps)
  //Wire.begin();            // I2C 통신 시작 (센서 읽기 오류가 계속되면 주석 해제)
  DHT.begin();             // DHT20 센서 초기화

  // LED와 부저 핀을 출력 모드로 설정
  pinMode(LED_RED, OUTPUT);
  pinMode(LED_YELLOW, OUTPUT);
  pinMode(LED_GREEN, OUTPUT);
  pinMode(BUZ, OUTPUT);

  // 모터 드라이버 핀을 출력 모드로 설정
  pinMode(PIN_ENA, OUTPUT);
  pinMode(PIN_IN1, OUTPUT);
  pinMode(PIN_IN2, OUTPUT);
  setMotor(0, 0);          // 시작 시 모터 정지
  Serial.println("=== IntellAigent Temperature Warning System ===");

}

void loop() 
{
      // ⭐핵심: 마지막으로 읽은 시점부터 1초가 지났을 때만 센서를 읽음 (1초에 1번)
      if (millis() - DHT.lastRead() >= 1000) 
      {
          int status = DHT.read();         // 센서 측정 요청 및 결과 읽기

          if (status != DHT20_OK)          // 측정 실패 시 오류 코드 출력 후 이번 회차 건너뜀
          {
            Serial.print("DHT20 read error: ");
            Serial.println(status);
            return;
          }

          float temp = DHT.getTemperature();   // 온도 값 가져오기 (℃)
          float humi = DHT.getHumidity();      // 습도 값 가져오기 (%)

          // 시리얼 모니터에 온도와 습도 출력
          Serial.print("Temp: ");
          Serial.print(temp);
          Serial.print(" °C  |  Humidity: ");
          Serial.print(humi);
          Serial.println(" %");


          // ====== 팬 제어 판단 ======
          // 32℃ 이상이면 ON, 28℃ 이하로 내려가면 OFF, 그 사이에서는 직전 상태 유지
          bool fanonoff = control(TEMP_NORMAL_MAX, TEMP_HIGH_MAX, temp);   // 하한 28, 상한 32

          // ====== 상태 판단 ======
          if (temp < TEMP_NORMAL_MAX) 
          {									// 28℃ 미만
            normalState();					// 정상 상태
          } 
          else if (temp < TEMP_HIGH_MAX) 
          {									// 28℃ 이상 32℃ 미만
            warningState();					// 고온 주의 상태
          } 
          else 
          {									// 32℃ 이상
            alarmState();					// 고온 경보 상태
          }
          fancontrol(fanonoff);				// 팬 작동 또는 정지
      }

      return ;
}

/*
  데드밴드(히스테리시스) 제어 함수 - 냉각 팬용
  _1st  : 하한값 (이 값 이하로 내려가면 OFF)
  _2st  : 상한값 (이 값 이상이면 ON 시작)
  value : 현재 입력값 (예: 현재 온도)
  반환값 : 출력 상태 (true = ON, false = OFF)

  동작 예 (_1st = 28, _2st = 32)
    온도 상승 중 30℃ → OFF 유지
    32℃ 이상 도달    → ON
    온도 하강 중 30℃ → ON 유지 (직전 상태 기억)
    28℃ 이하         → OFF
*/
bool control(double _1st, double _2st, double value)
{
    bool case1;                  // 현재 값이 상한값 이상인가? (켜기 조건)
    bool case2;                  // 현재 값이 하한값 초과인가? (유지 조건)
    static bool case3 = false;   // ON 조건 (static: 함수가 끝나도 값이 유지됨)
    static bool case4 = false;   // 최종 출력 (static: 직전 출력 상태를 기억함)
     
    case1 = value >= _2st  ? true:false;   // 상한값 이상이면 true
    case2 = value >  _1st  ? true:false;   // 하한값 초과이면 true

    // ON 조건: 상한값 이상으로 올라왔거나, 이미 ON 상태였으면 true
    // (case4에는 아직 "직전" 출력값이 들어 있음 → 자기유지 역할)
    case3 = case1 || case4;

    // 최종 출력: ON 조건을 만족하면서 하한값보다 높을 때만 ON
    // 하한값 이하로 내려가면 case2가 false가 되어 강제로 OFF
    case4 = case2 && case3;
    
    return case4;
}
// ================== 팬작동 함수 ==================
// onoff가 true면 정방향 속도 180으로 회전, false면 브레이크로 정지
void fancontrol(bool onoff)
{
	if(onoff)
	{
		motorSpeed = 180;
		direction = 1;
		setMotor(direction, motorSpeed);
	}
	else
	{
		brake();
	}
}

// 모터 방향(dir)과 속도(speed, 0~255)를 설정
void setMotor(int dir, int speed) 
{
  speed = constrain(speed, 0, 255);   // 속도를 0~255 범위로 제한
  if (dir > 0) 
  {
    digitalWrite(PIN_IN1, HIGH);
    digitalWrite(PIN_IN2, LOW);
  } else if (dir < 0) {
    digitalWrite(PIN_IN1, LOW);
    digitalWrite(PIN_IN2, HIGH);
  } else {
    digitalWrite(PIN_IN1, LOW);
    digitalWrite(PIN_IN2, LOW);
    speed = 0;
  }
  analogWrite(PIN_ENA, speed);
}

void brake()
 {
  // IN1, IN2를 모두 HIGH로 두면 모터 단자가 단락되어 빠르게 멈춤
  digitalWrite(PIN_IN1, HIGH);
  digitalWrite(PIN_IN2, HIGH);
  analogWrite(PIN_ENA, 255);
  direction = 0;
}

// 방향 전환 시 모터와 드라이버 보호를 위해 잠깐 멈춘 뒤 전환 (현재 미사용)
void changeDirection(int newDir) 
{

  if (direction != 0 && direction != newDir) 
  {
    setMotor(0, 0);
    delay(300);
  }
  direction = newDir;
  setMotor(direction, motorSpeed);
}

// ================== 상태별 함수 ==================
// 정상 상태: 초록색 LED 켜짐, 부저 꺼짐
void normalState() 
{
  digitalWrite(LED_GREEN, HIGH);
  digitalWrite(LED_YELLOW, LOW);
  digitalWrite(LED_RED, LOW);
  digitalWrite(BUZ, LOW);
}

// 고온 주의 상태: 노란색 LED 켜짐, 부저가 짧게 한 번 울림
void warningState() 
{
  digitalWrite(LED_GREEN, LOW);
  digitalWrite(LED_YELLOW, HIGH);
  digitalWrite(LED_RED, LOW);

  digitalWrite(BUZ, HIGH);   // 부저 켜기
  delay(100);                // 0.1초 유지
  digitalWrite(BUZ, LOW);    // 부저 끄기
}

// 고온 경보 상태: 빨간색 LED가 깜빡이고, 부저가 경보음을 울림
void alarmState()
{
  digitalWrite(LED_GREEN, LOW);
  digitalWrite(LED_YELLOW, LOW);

  digitalWrite(LED_RED, HIGH);   // 빨간색 LED와 부저 켜기
  digitalWrite(BUZ, HIGH);
  delay(300);                    // 0.3초 유지
  digitalWrite(LED_RED, LOW);    // 빨간색 LED와 부저 끄기
  digitalWrite(BUZ, LOW);
  delay(300);                    // 0.3초 유지

}