// กำหนดขา LED
const int led1 = 23; // LED หลอดที่ 1
const int led2 = 22; // LED หลอดที่ 2
// กำหนดขาสำหรับสวิตช์
const int switchPin1 = 15; // สวิตช์สำหรับ LED1 (GPIO15 หรือ D15)
const int switchPin2 = 4; // สวิตช์สำหรับ LED2 (GPIO4)
// ตัวแปรสำหรับสถานะของ LED แต่ละหลอด
bool led1State = false; // สถานะของ LED1
bool led2State = false; // สถานะของ LED2
// ตัวแปรสำหรับสถานะ "ก่อนหน้า" ของสวิตช์แต่ละตัว
int lastSwitchState1 = HIGH; // สถานะก่อนหน้าของ Switch 1
int lastSwitchState2 = HIGH; // สถานะก่อนหน้าของ Switch 2
// ค่าหน่วงเวลา Debounce แบบง่าย (ใช้ delay())
const int debounceDelay = 50; // 50 มิลลิวินาที (ปรับได้)
// ค่าหน่วงเวลาเพิ่มเติมหลังการ Toggle เพื่อป้องกันการกดซ้ำเมื่อกดค้าง
const int postToggleDelay = 300; // 300 มิลลิวินาที (ปรับได้)
void setup() {
// กำหนดขา LED เป็น OUTPUT
pinMode(led1, OUTPUT);
pinMode(led2, OUTPUT);
// กำหนดขา Switch เป็น INPUT_PULLUP
pinMode(switchPin1, INPUT_PULLUP);
pinMode(switchPin2, INPUT_PULLUP);
// เริ่มต้น Serial Communication เพื่อดีบัก
Serial.begin(115200);
Serial.println("System Initializing for 2 LEDs with 2 switches...");
// ตั้งค่าเริ่มต้นให้ LED ทั้งสองดับ
digitalWrite(led1, LOW);
digitalWrite(led2, LOW);
Serial.println("Setup Complete. Waiting for button presses...");
}
void loop() {
// เรียกใช้ฟังก์ชัน checkSwitch สำหรับสวิตช์ตัวที่ 1 (ควบคุม LED1)
checkSwitch(switchPin1, led1, &led1State, &lastSwitchState1);
// เรียกใช้ฟังก์ชัน checkSwitch สำหรับสวิตช์ตัวที่ 2 (ควบคุม LED2)
checkSwitch(switchPin2, led2, &led2State, &lastSwitchState2);
// ไม่มี delay() ตรงนี้ใน loop() โดยตรงแล้ว เพราะมี delay() ภายใน checkSwitch อยู่แล้ว
// หากเพิ่ม delay() ตรงนี้ จะทำให้การตอบสนองของสวิตช์ทั้งคู่ช้าลงไปอีก
}
// ฟังก์ชันนี้ถูกปรับให้เหมาะสมกับการไม่ใช้ millis() และจัดการได้หลายสวิตช์
// switchPin: ขาที่ต่อกับสวิตช์
// ledPin: ขาที่ต่อกับ LED ที่ต้องการควบคุม
// ledState: ตัวชี้ไปยังตัวแปรสถานะของ LED (เพื่อเปลี่ยนแปลงค่าได้)
// lastSwitchState: ตัวชี้ไปยังตัวแปรสถานะ "ก่อนหน้า" ของสวิตช์สำหรับสวิตช์นี้
void checkSwitch(int switchPin, int ledPin, bool *ledState, int *lastSwitchState) {
// อ่านสถานะปัจจุบันของสวิตช์
int currentReading = digitalRead(switchPin);
// Debugging: พิมพ์สถานะดิบที่อ่านได้ลง Serial Monitor
Serial.print("Raw Pin ");
Serial.print(switchPin);
Serial.print(": ");
Serial.println(currentReading == HIGH ? "HIGH" : "LOW");
// ตรวจจับ "จังหวะที่กดสวิตช์ลงไป" (Falling Edge)
// คือ เมื่อสวิตช์ถูก "กด" (currentReading เป็น LOW) และ "เพิ่ง" ถูกกดลงไป (lastSwitchState เป็น HIGH)
if (currentReading == LOW && *lastSwitchState == HIGH) {
// ** นี่คือการทำ Debounce แบบง่ายโดยใช้ delay() **
delay(debounceDelay);
// หลังจากหน่วงเวลา ให้ตรวจสอบสถานะสวิตช์อีกครั้ง
// เพื่อยืนยันว่ายังคงถูกกดอยู่ (ไม่ใช่การกระดอนชั่วคราว)
if (digitalRead(switchPin) == LOW) {
// สลับสถานะของ LED
*ledState = !(*ledState);
// เขียนสถานะใหม่ไปยัง LED
digitalWrite(ledPin, *ledState ? HIGH : LOW);
// พิมพ์ข้อความยืนยันการทำงานลง Serial Monitor
Serial.print("--- Switch on Pin ");
Serial.print(switchPin);
Serial.print(" PRESSED and TOGGLED! LED ");
Serial.print(ledPin);
Serial.println(*ledState ? " ON" : " OFF");
// **สำคัญมาก: หน่วงเวลาเพิ่มเติมหลังจาก Toggle เพื่อป้องกันการตรวจจับการกดซ้ำ**
delay(postToggleDelay);
}
}
// บันทึกสถานะปัจจุบันที่อ่านได้ เพื่อใช้ในการเปรียบเทียบในรอบถัดไป
*lastSwitchState = currentReading;
}