#include <WiFi.h>
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <ESP32Servo.h>
// การตั้งค่าหน้าจอ LCD
LiquidCrystal_I2C LCD(0x27, 16, 2);
// การตั้งค่า NTP
#define NTP_SERVER "pool.ntp.org"
#define UTC_OFFSET 0
#define UTC_OFFSET_DST 0
// การตั้งค่า Servo
Servo myservo;
// การตั้งค่าปุ่ม
#define BUTTON_PIN 12 // GPIO ที่เชื่อมต่อกับปุ่ม
volatile bool buttonPressed = false; // ตัวแปรตรวจสอบสถานะการกดปุ่ม
unsigned long lastDebounceTime = 0; // เวลาล่าสุดที่กดปุ่ม
const unsigned long debounceDelay = 200; // ระยะเวลาหน่วง (ms) เพื่อลด Bounce
// การตั้งค่า LDR และ Buzzer
#define LDR_PIN 34 // ขาอนาล็อกที่เชื่อมต่อกับ LDR
#define BUZZER_PIN 25 // ขาที่เชื่อมต่อกับ Buzzer
bool isServoBusy = false; // ตัวแปรสถานะเพื่อป้องกันการทำงานซ้ำ
void IRAM_ATTR handleButtonPress() {
// กรองการกดปุ่มซ้ำด้วย Debounce
unsigned long currentTime = millis();
if (currentTime - lastDebounceTime > debounceDelay) {
buttonPressed = true;
lastDebounceTime = currentTime;
}
}
void spinner() {
static int8_t counter = 0;
const char* glyphs = "\xa1\xa5\xdb";
LCD.setCursor(15, 1);
LCD.print(glyphs[counter++]);
if (counter == strlen(glyphs)) {
counter = 0;
}
}
void printLocalTime() {
struct tm timeinfo;
if (!getLocalTime(&timeinfo)) {
LCD.setCursor(0, 1);
LCD.print("Connection Err");
return;
}
LCD.setCursor(8, 0);
LCD.print(&timeinfo, "%H:%M:%S");
LCD.setCursor(0, 1);
LCD.print(&timeinfo, "%d/%m/%Y %Z");
}
void setup() {
// เริ่มต้น Serial
Serial.begin(115200);
// ตั้งค่าหน้าจอ LCD
LCD.init();
LCD.backlight();
LCD.setCursor(0, 0);
LCD.print("Connecting to ");
LCD.setCursor(0, 1);
LCD.print("WiFi ");
// เชื่อมต่อ WiFi
WiFi.begin("Wokwi-GUEST", "", 6);
while (WiFi.status() != WL_CONNECTED) {
delay(250);
spinner();
}
Serial.println("");
Serial.println("WiFi connected");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Online");
LCD.setCursor(0, 1);
LCD.print("Updating time...");
// ตั้งค่าเวลา NTP
configTime(UTC_OFFSET, UTC_OFFSET_DST, NTP_SERVER);
// ตั้งค่า Servo
myservo.attach(13); // กำหนดขาควบคุม Servo (D13)
// ตั้งค่าปุ่ม
pinMode(BUTTON_PIN, INPUT_PULLUP); // เปิดใช้งาน Pull-up Resistor
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), handleButtonPress, FALLING); // ตรวจจับการกดปุ่ม
// ตั้งค่า Buzzer
pinMode(BUZZER_PIN, OUTPUT);
// ตั้งค่า LDR
pinMode(LDR_PIN, INPUT);
}
void loop() {
// อัปเดตเวลาและแสดงผลบนหน้าจอ
printLocalTime();
// ตรวจสอบการกดปุ่ม
if (buttonPressed && !isServoBusy) {
buttonPressed = false; // รีเซ็ตสถานะปุ่ม
isServoBusy = true; // ล็อกสถานะเพื่อป้องกันการทำงานซ้ำ
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Servo Moving...");
// หมุน Servo
myservo.write(0); // หมุน Servo ไปที่ 0 องศา
delay(250); // รอ 0.25 วินาที
myservo.write(180); // หมุน Servo ไปที่ 180 องศา
delay(250); // รอ 0.25 วินาที
myservo.write(0); // หมุน Servo กลับไปที่ 0 องศา
delay(250); // รอ 0.25 วินาที
// ส่งเสียง Buzzer
digitalWrite(BUZZER_PIN, HIGH);
delay(1000); // Buzzer ทำงาน 1 วินาที
digitalWrite(BUZZER_PIN, LOW);
// แสดงข้อความ Thank You
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Thank You!");
delay(1000); // แสดงข้อความ "Thank You" เป็นเวลา 1 วินาที
// กลับไปแสดงข้อความเดิม
LCD.clear();
LCD.setCursor(0, 0);
LCD.print("Online");
LCD.setCursor(0, 1);
LCD.print("Updating time...");
isServoBusy = false; // ปลดล็อกสถานะเมื่อกระบวนการเสร็จสิ้น
}
delay(50); // ลดการประมวลผลที่ไม่จำเป็น
}