아두이노를 이용해 LCD 화면과 버튼을 활용하여 모드를 변경하고, 특정 조건에서 초기 화면으로 돌아가는 기능을 구현해보겠습니다. 🤖✨
오늘은 전자산업기사 1번 공개 문제를 풀어 보도록 하겠습니다.
1. 프로젝트 개요
이 프로젝트에서는 아두이노 메가(Arduino Mega)와 I2C 방식의 LCD, 버튼(SW1, SW2, SW3)을 사용하여 모드를 선택하는 시스템을 만듭니다. 기능은 다음과 같습니다.
🔹 LCD에 기본 메시지(init_LCD()) 표시 🔹 LCD 백라이트를 5번 깜박인 후 모드 선택 화면(mode_LCD())으로 이동 🔹 SW1 버튼을 클릭할 때마다 모드1(mode1_LCD())과 모드2(mode2_LCD())가 번갈아 표시 🔹 SW1 버튼을 3초 이상 누르면 초기 화면으로 복귀
2. 사용 부품
✅ 아두이노 메가 (Arduino Mega) ✅ LiquidCrystal_I2C LCD (16x2) ✅ 푸시 버튼 3개 (SW1, SW2, SW3) ✅ 저항 (각 버튼에 10kΩ 풀다운 저항 사용) ✅ 점퍼 와이어
3. 회로 연결
버튼 연결
- SW1 → 아두이노 23번 핀
- SW2 → 아두이노 24번 핀
- SW3 → 아두이노 25번 핀
- 각 버튼의 GND는 아두이노 GND와 연결
LCD 연결
- SDA → 아두이노 20번 핀
- SCL → 아두이노 21번 핀
- VCC → 5V
- GND → GND
4. 아두이노 코드 구현
아두이노 코드에서 주요 기능을 확인해보겠습니다!
1) LCD 초기 화면 (init_LCD())
LCD에 기본 메시지를 표시합니다.
void init_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Digital Pulse");
lcd.setCursor(0, 1);
lcd.print("Number: A001");
}
2) 모드 선택 화면 (mode_LCD())
모드를 변경할 준비 화면을 출력합니다.
void mode_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Mode Button");
lcd.setCursor(0, 1);
lcd.print("Push Mode Sw1! ");
}
3) 두 개의 모드 (mode1_LCD(), mode2_LCD())
SW1 버튼을 누르면 Pulse Mode와 Sensor Mode를 번갈아 선택합니다.
void mode1_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1.Pulse Mode ");
lcd.setCursor(0, 1);
lcd.print(" Push Select! ");
}
void mode2_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("2.Sensor Mode ");
lcd.setCursor(0, 1);
lcd.print(" Push Select! ");
}
4) 버튼 클릭 시 모드 변경 및 3초 유지 시 초기 화면 복귀
SW1 버튼을 한 번 클릭하면 모드가 변경되며, 3초 이상 누르면 초기 화면으로 돌아갑니다.
void loop() {
// 백라이트를 5번 깜박이기
for (int i = 0; i < 5; i++) {
lcd.noBacklight();
delay(500);
lcd.backlight();
delay(500);
}
mode_LCD();
while (true) {
if (digitalRead(SW1) == HIGH) { // SW1 버튼이 눌렸을 때
delay(50); // 디바운싱 방지
int pressTime = 0;
while (digitalRead(SW1) == HIGH) {
delay(100);
pressTime += 100;
if (pressTime >= 3000) { // 3초 이상 눌린 경우
init_LCD();
return;
}
}
// 버튼 한 번 눌렸을 때 Mode 변경
mode = (mode == 1) ? 2 : 1;
// 선택한 모드 출력
if (mode == 1) {
mode1_LCD();
} else {
mode2_LCD();
}
}
}
}
- 버튼 핀 연결:
- SW1은 디지털 핀 2에, SW2는 디지털 핀 3에 연결됩니다.
- 풀다운 저항을 사용하는 것이 권장됩니다.
- 모드 전환:
- SW1을 눌러 Pulse Mode와 Sensor Mode를 전환할 수 있습니다.
- SW2를 눌러 각 모드에서 추가 동작(주파수 표시 또는 센서 데이터 표시)을 실행합니다.
- 주파수 및 센서 데이터:
- 주파수(xxx Hz)와 센서 데이터를 읽는 로직은 실제 연결된 하드웨어에 맞게 추가해야 합니다.
- 디바운싱: 버튼 입력의 신뢰성을 높이기 위해 딜레이를 추가했습니다.
-
- 온도 센서 (LM35):
- analogRead 값을 통해 온도를 계산하며, 소수점 이하 두 자리까지 표시합니다.
- CDS 센서:
- analogRead 값을 기반으로 2.5V를 기준으로 NIG 또는 DAY를 표시합니다.
- 초음파 센서:
- 초음파 센서를 이용하여 거리를 측정하고, 1cm 당 1열씩 감지를 표시하는 기능을 구현했습니다.
- SW3 버튼:
- SW3 버튼이 눌렸을 때 초기 모드로 돌아갑니다.
- 온도 센서 (LM35):
필요에 따라 값을 조정하거나 하드웨어에 맞게 수정하세요.
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD 객체 초기화 (I2C 주소 설정)
LiquidCrystal_I2C lcd(0x27, 16, 2);
int mode = 1; // 기본 모드는 1 (Pulse Mode)
const int SW1 = 2; // SW1 버튼 핀
const int SW2 = 3; // SW2 버튼 핀
void setup() {
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
lcd.init(); // LCD 초기화
lcd.backlight();
init_LCD(); // 초기 화면 표시
}
void loop() {
// 백라이트 깜박임 (5번 반복)
for (int i = 0; i < 5; i++) {
lcd.noBacklight();
delay(500);
lcd.backlight();
delay(500);
}
mode_LCD();
while (true) {
if (digitalRead(SW1) == HIGH) { // SW1 버튼이 눌렸을 때
delay(50); // 디바운싱 방지
int pressTime = 0;
while (digitalRead(SW1) == HIGH) {
delay(100);
pressTime += 100;
if (pressTime >= 3000) { // 3초 이상 눌렸을 때
init_LCD();
return;
}
}
// 모드 변경
mode = (mode == 1) ? 2 : 1;
// 변경된 모드 표시
if (mode == 1) {
mode1_LCD();
} else {
mode2_LCD();
}
}
if (digitalRead(SW2) == HIGH) { // SW2 버튼이 눌렸을 때
delay(50); // 디바운싱 방지
if (mode == 1) {
displayPulseMode(); // Pulse Mode 화면 표시
} else if (mode == 2) {
displaySensorMode(); // Sensor Mode 화면 표시
}
}
}
}
void init_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("초기화 중...");
delay(2000);
lcd.clear();
}
void mode_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("모드를 선택하세요");
lcd.setCursor(0, 1);
lcd.print("SW1을 눌러주세요");
}
void mode1_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("1. Pulse Mode");
lcd.setCursor(0, 1);
lcd.print("선택: SW2 클릭!");
}
void mode2_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("2. Sensor Mode");
lcd.setCursor(0, 1);
lcd.print("선택: SW2 클릭!");
}
void displayPulseMode() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("[Pulse Mode]");
lcd.setCursor(0, 1);
lcd.print("Freq: xxx Hz"); // 실제 주파수 값을 여기에 추가
}
void displaySensorMode() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("[Sensor Mode]");
lcd.setCursor(0, 1);
lcd.print("센서 데이터"); // 실제 센서 데이터를 여기에 추가
}
이 코드에서는 온도, CDS 상태, 초음파 거리 감지, 그리고 버튼을 눌러 초기 모드로 되돌아가는 기능을 포함합니다:
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
// LCD 객체 초기화 (I2C 주소 설정)
LiquidCrystal_I2C lcd(0x27, 16, 2);
int mode = 2; // 기본 모드는 Sensor Mode
const int SW1 = 2; // SW1 버튼 핀
const int SW2 = 3; // SW2 버튼 핀
const int SW3 = 4; // SW3 버튼 핀
const int CDS_PIN = A0; // CDS 센서 핀
const int TEMP_PIN = A1; // 온도 센서 핀 (LM35)
const int ULTRASONIC_TRIGGER = 5; // 초음파 센서 트리거 핀
const int ULTRASONIC_ECHO = 6; // 초음파 센서 에코 핀
void setup() {
pinMode(SW1, INPUT);
pinMode(SW2, INPUT);
pinMode(SW3, INPUT);
pinMode(CDS_PIN, INPUT);
pinMode(TEMP_PIN, INPUT);
pinMode(ULTRASONIC_TRIGGER, OUTPUT);
pinMode(ULTRASONIC_ECHO, INPUT);
lcd.init(); // LCD 초기화
lcd.backlight();
init_LCD(); // 초기 화면 표시
}
void loop() {
// SW3 버튼이 눌렸을 경우 초기화로 되돌아감
if (digitalRead(SW3) == HIGH) {
delay(50); // 디바운싱 방지
init_LCD();
return;
}
if (mode == 2) {
sensorMode_LCD(); // Sensor Mode 기능 실행
}
}
void init_LCD() {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("초기화 중...");
delay(2000);
lcd.clear();
}
void sensorMode_LCD() {
// 온도 센서 값을 읽고 표시
float temperature = analogRead(TEMP_PIN) * (5.0 / 1023.0) * 100.0; // LM35 온도 계산
lcd.setCursor(0, 0);
lcd.print("T: ");
lcd.print(temperature, 2); // 소수점 2자리로 표시
lcd.print("C");
// CDS 센서 상태 표시
int cdsValue = analogRead(CDS_PIN) * (5.0 / 1023.0);
lcd.setCursor(0, 1);
lcd.print("CDS: ");
if (cdsValue < 2.5) {
lcd.print("NIG"); // 손으로 가렸을 경우
} else {
lcd.print("DAY"); // 손으로 가리지 않았을 경우
}
delay(2000); // 화면 유지
// 초음파 센서 거리 측정
lcd.clear();
digitalWrite(ULTRASONIC_TRIGGER, LOW);
delayMicroseconds(2);
digitalWrite(ULTRASONIC_TRIGGER, HIGH);
delayMicroseconds(10);
digitalWrite(ULTRASONIC_TRIGGER, LOW);
long duration = pulseIn(ULTRASONIC_ECHO, HIGH);
int distance = duration * 0.034 / 2; // cm로 변환
lcd.setCursor(0, 0);
lcd.print("Ultrasonic:");
lcd.setCursor(0, 1);
lcd.print("Dist: ");
lcd.print(distance);
lcd.print("cm");
delay(2000); // 화면 유지
}
5. 결론
이제 버튼을 눌러 모드를 선택하고, 3초 이상 누르면 초기 화면으로 돌아가는 기능이 정상적으로 동작할 것입니다. 🚀
이 프로젝트를 바탕으로 추가적인 기능을 구현할 수도 있어요! 🔸 모드 추가 → 새로운 기능을 가진 Mode3을 추가 🔸 센서 연동 → 온도 센서, 초음파 센서 등과 결합하여 데이터를 LCD에 표시 🔸 소리 출력 → 특정 모드에서 부저를 울리거나 알람 기능 적용
💡 아두이노를 활용한 다양한 프로젝트를 직접 만들어보면서 창의력을 발휘해보세요! 궁금한 점이나 추가할 기능이 있다면 언제든지 댓글로 알려주세요! 😊🔥