아두이노

📟 아두이노 메가2560 시계 & 센서 통합 프로젝트 (LCD, EEPROM, 초음파, SY-LD213)

모빌리티키즈 2025. 6. 21. 11:46
728x90
반응형

📟 아두이노 메가2560 시계 & 센서 통합 프로젝트 (LCD, EEPROM, 초음파, SY-LD213)

안녕하세요, 오늘은 아두이노 메가2560을 기반으로 다양한 센서를 통합하고, 실시간 디지털 시계와 센서 데이터를 LCD에 출력하는 프로젝트를 소개합니다. 이 프로젝트는 아래와 같은 하드웨어와 소프트웨어 요구사항을 충실히 반영한 통합 설계입니다.

전자산업기사 예제 문제를 풀어봐요.

📋 프로젝트 개요

항목설명
보드 Arduino Mega 2560
센서 LM35 온도 센서, CDS 조도 센서, HC-SR04 초음파
디스플레이 16x2 I2C LCD
입력 장치 텍트 스위치 3개 (SW1, SW2, SW3)
부가기능 EEPROM 저장/불러오기, 시리얼 플로터 출력

🔧 회로 연결 요약

  • LM35 → A0 (10kΩ 직렬 저항)
  • CDS → A1 (풀다운 10kΩ 연결)
  • 초음파센서 HC-SR04 → TRIG(5), ECHO(6)
  • SY-LD213 주파수 입력 → PWM_IN 핀 (미사용 시 내부 타이머 사용)
  • SW1 / SW2 / SW3 → 2, 3, 4번 핀 (풀업 10kΩ)

회로도 1과제.pdf
0.05MB
ele01.zip
0.09MB

🖼️ LCD 화면 구성

▶️ 초기화면(1) : 깜빡이기 (0.5초 간격 5회)

 
Digital Sensor
Number:     A001

▶️ 초기화면(2) : 모드 안내

 
Mode Button
Push Mode SW1!

🔁 모드 전환 방식

  • SW1 / SW2 누를 때마다 모드 전환
  • SW2로 모드 선택
  • SW3으로 EEPROM 저장/복원
  • 초음파 센서로 15cm 이내 감지 시 초기화면 자동 복귀

⏰ Clock Mode: 디지털 시계 구현

  • 시작 시간: 11시 59분 50초
  • 10ms 간격으로 시간 증가 (micros() 기반)
  • AM/PM 자동 판단 표시
  • LCD 출력 예시:
 
[Digital Clock]  
[AM] 11:59:52:60

🌡️ Sensor Mode: 센서 데이터 출력

  • LCD에 현재 시각 + CDS + 온도 표시
  • 시리얼 플로터에 실시간 CDS 출력
  • 출력 예시:
 
[AM] 11:59:53:12
CDS: 0514 T:23.15

💾 SW3: EEPROM 저장 / 불러오기

  • SW3 짧게 누르면 현재 시간 + 센서 값 저장
  • 전원 OFF → ON 후 SW3 누르면 저장값 불러오기
  • EEPROM 출력 예시:
 
[AM] 11:59:53:12
CDS: 0514 T:23.15

📁 전체 소스코드

아래 버튼을 클릭해 전체 .ino 파일을 복사하거나 다운로드하세요:

#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <EEPROM.h>

#define SW1 2
#define SW2 3
#define SW3 4
#define TRIG 5
#define ECHO 6
#define LM35 A0
#define CDS A1

LiquidCrystal_I2C lcd(0x27, 16, 2);

int mode = 1;
bool modeSelected = false;
bool showEEPROM = false;

int hour = 11, minute = 59, second = 50, hundredths = 0;
unsigned long lastMicros = 0;

void setup() {
  pinMode(SW1, INPUT_PULLUP);
  pinMode(SW2, INPUT_PULLUP);
  pinMode(SW3, INPUT_PULLUP);
  pinMode(TRIG, OUTPUT);
  pinMode(ECHO, INPUT);
  lcd.begin(16, 2);
  lcd.clear();
  Serial.begin(9600);
  showInitScreen();
}

void loop() {
  updateClock();

  if (getDistance() <= 15) {
    modeSelected = false;
    showInitScreen();
  }

  if (digitalRead(SW3) == LOW) {
    delay(300);
    if (showEEPROM) loadFromEEPROM();
    else saveToEEPROM();
    showEEPROM = !showEEPROM;
  }

  if (!modeSelected) {
    showModeMenu();
    if (digitalRead(SW1) == LOW || digitalRead(SW2) == LOW) {
      delay(250);
      mode = (mode == 1) ? 2 : 1;
    }
    if (digitalRead(SW2) == LOW) {
      delay(300);
      modeSelected = true;
    }
  } else {
    if (mode == 1) showClockMode();
    else showSensorMode();
  }
}

void showInitScreen() {
  for (int i = 0; i < 5; i++) {
    lcd.clear();
    lcd.setCursor(0, 0);
    lcd.print("Digital Sensor");
    lcd.setCursor(0, 1);
    lcd.print("Number:     A001");
    delay(500);
    lcd.clear();
    delay(500);
  }
  lcd.setCursor(0, 0);
  lcd.print("Mode Button");
  lcd.setCursor(0, 1);
  lcd.print("Push Mode SW1!");
}

void showModeMenu() {
  lcd.setCursor(0, 0);
  if (mode == 1) lcd.print("1. Clock Mode   ");
  else lcd.print("2. Sensor Mode  ");
  lcd.setCursor(0, 1);
  lcd.print("Push Select!    ");
}

void showClockMode() {
  lcd.setCursor(0, 0);
  lcd.print("[Digital Clock] ");
  lcd.setCursor(0, 1);
  lcd.print(getClockString());
}

void showSensorMode() {
  int cds = analogRead(CDS);
  float temp = analogRead(LM35) * 0.488;

  Serial.println(cds);

  lcd.setCursor(0, 0);
  lcd.print(getClockString());
  lcd.setCursor(0, 1);
  lcd.print("CDS:");
  if (cds < 1000) lcd.print("0");
  if (cds < 100) lcd.print("0");
  if (cds < 10) lcd.print("0");
  lcd.print(cds);
  lcd.print(" T:");
  lcd.print(temp, 2);
}

void updateClock() {
  if (micros() - lastMicros >= 10000) {
    lastMicros = micros();
    hundredths++;
    if (hundredths >= 100) {
      hundredths = 0;
      second++;
      if (second >= 60) {
        second = 0;
        minute++;
        if (minute >= 60) {
          minute = 0;
          hour = (hour + 1) % 24;
        }
      }
    }
  }
}

String getClockString() {
  char ap[] = "AM";
  int h = hour;
  if (h >= 12) strcpy(ap, "PM");
  if (h == 0) h = 12;
  else if (h > 12) h -= 12;

  char buf[17];
  sprintf(buf, "[%s] %02d:%02d:%02d:%02d", ap, h, minute, second, hundredths);
  return String(buf);
}

void saveToEEPROM() {
  EEPROM.update(0, hour);
  EEPROM.update(1, minute);
  EEPROM.update(2, second);

  int cds = analogRead(CDS);
  float temp = analogRead(LM35) * 0.488;

  EEPROM.put(10, cds);
  EEPROM.put(20, temp);
}

void loadFromEEPROM() {
  hour = EEPROM.read(0);
  minute = EEPROM.read(1);
  second = EEPROM.read(2);

  int cds;
  float temp;
  EEPROM.get(10, cds);
  EEPROM.get(20, temp);

  lcd.clear();
  lcd.setCursor(0, 0);
  lcd.print(getClockString());
  lcd.setCursor(0, 1);
  lcd.print("CDS:");
  if (cds < 1000) lcd.print("0");
  if (cds < 100) lcd.print("0");
  if (cds < 10) lcd.print("0");
  lcd.print(cds);
  lcd.print(" T:");
  lcd.print(temp, 2);
}

int getDistance() {
  digitalWrite(TRIG, LOW);
  delayMicroseconds(2);
  digitalWrite(TRIG, HIGH);
  delayMicroseconds(10);
  digitalWrite(TRIG, LOW);

  long duration = pulseIn(ECHO, HIGH);
  int distance = duration / 58;
  return distance;
}

✅ 결론 및 느낀 점

  • 시계와 센서가 병렬 동작하면서도 각기 모드별로 독립적으로 작동해야 해서, 설계 구조를 깔끔히 나누는 것이 중요했습니다.
  • 센서들의 직관적인 LCD 시각화는 사용성 향상에 큰 도움이 되었어요.
  • 특히 EEPROM을 이용해 재부팅 후에도 상태 유지를 가능케 한 점이 만족스럽습니다.

궁금한 점이나 회로도 첨부가 필요하시면 댓글이나 메시지로 남겨주세요! 이상으로 Arduino Mega2560 통합 프로젝트 포스팅을 마칩니다 😊

> 이 글이 도움이 되셨다면 ❤️ 공감 또는 공유 부탁드립니다!

728x90
반응형