#include "DHT.h"
// =========================================
// กำหนดขาอุปกรณ์
// =========================================
#define DHTPIN 4
#define DHTTYPE DHT22
#define BUZZER_PIN 5
#define MANUAL_LED_PIN 15 // ไฟดวงที่ 8 (กระพริบ)
// ขาปุ่มกดตามที่คุณต่อไว้ใน Wokwi
#define GREEN_BTN_PIN 16 // ปุ่มสีเขียว
#define RED_BTN_PIN 18 // ปุ่มสีแดง
int measurePin = 34; // เซ็นเซอร์ฝุ่น (Potentiometer)
int ledPower = 14;
// โมดูล LED 7 ดวง
int ledBarPins[] = {13, 12, 27, 26, 25, 33, 32};
DHT dht(DHTPIN, DHTTYPE);
// ตัวแปรจับเวลา
unsigned long sensorPrevMillis = 0;
unsigned long blinkPrevMillis = 0;
// ตัวแปรสถานะการทำงาน
bool isBlinking = false;
bool isBuzzerOn = false;
bool blinkState = false;
// ตัวแปรสำหรับเช็คการกดปุ่ม (Debounce)
bool lastGreenState = HIGH;
bool lastRedState = HIGH;
void setup() {
Serial.begin(115200);
dht.begin();
// ตั้งค่าปุ่มกดเป็น INPUT_PULLUP (ไม่ต้องต่อตัวต้านทานเพิ่ม)
pinMode(GREEN_BTN_PIN, INPUT_PULLUP);
pinMode(RED_BTN_PIN, INPUT_PULLUP);
pinMode(BUZZER_PIN, OUTPUT);
pinMode(MANUAL_LED_PIN, OUTPUT);
pinMode(ledPower, OUTPUT);
// ปิดไฟและเสียงเริ่มต้น (ใน Simulator เป็น Active-High: LOW = ดับ)
noTone(BUZZER_PIN);
digitalWrite(MANUAL_LED_PIN, LOW);
for (int i = 0; i < 7; i++) {
pinMode(ledBarPins[i], OUTPUT);
digitalWrite(ledBarPins[i], LOW);
}
Serial.println("Simulator is Ready!");
}
void loop() {
// -----------------------------------------------------------
// 1. ตรวจจับการกดปุ่มสีเขียว (เปิด-ปิด ไฟกระพริบดวงที่ 8)
// -----------------------------------------------------------
bool currentGreenState = digitalRead(GREEN_BTN_PIN);
if (currentGreenState == LOW && lastGreenState == HIGH) { // ตรวจจับตอนกดลงไป
isBlinking = !isBlinking; // สลับสถานะเปิด/ปิด
Serial.println(isBlinking ? "🟢 Green Button: Blink ON" : "🟢 Green Button: Blink OFF");
delay(50); // กันปุ่มเบิ้ล
}
lastGreenState = currentGreenState;
// -----------------------------------------------------------
// 2. ตรวจจับการกดปุ่มสีแดง (เปิด-ปิด เสียง Buzzer)
// -----------------------------------------------------------
bool currentRedState = digitalRead(RED_BTN_PIN);
if (currentRedState == LOW && lastRedState == HIGH) {
isBuzzerOn = !isBuzzerOn; // สลับสถานะเปิด/ปิด
Serial.println(isBuzzerOn ? "🔴 Red Button: Buzzer ON" : "🔴 Red Button: Buzzer OFF");
delay(50); // กันปุ่มเบิ้ล
}
lastRedState = currentRedState;
// -----------------------------------------------------------
// 3. ทำงานตามสถานะปุ่มกด (กระพริบ และ เสียง)
// -----------------------------------------------------------
// จัดการไฟกระพริบ
if (isBlinking) {
if (millis() - blinkPrevMillis > 500) {
blinkPrevMillis = millis();
blinkState = !blinkState;
digitalWrite(MANUAL_LED_PIN, blinkState ? HIGH : LOW);
}
} else {
digitalWrite(MANUAL_LED_PIN, LOW); // ปิดสนิทถ้าไม่ได้กด
}
// จัดการเสียง Buzzer
if (isBuzzerOn) {
tone(BUZZER_PIN, 2000); // ส่งเสียง
} else {
noTone(BUZZER_PIN); // ปิดเสียง
}
// -----------------------------------------------------------
// 4. อ่านค่าเซ็นเซอร์ (อุณหภูมิ และ ฝุ่นแบบจำลอง) ทุกๆ 2 วินาที
// -----------------------------------------------------------
if (millis() - sensorPrevMillis > 2000) {
sensorPrevMillis = millis();
float temp = dht.readTemperature();
// จำลองอ่านค่าจาก Potentiometer มาเข้าสูตรคำนวณฝุ่นเดิม
int voMeasured = analogRead(measurePin);
float calcVoltage = voMeasured * (3.3 / 4095.0);
float dustDensity = 170 * calcVoltage - 0.1;
if (dustDensity < 0) dustDensity = 0.00;
// คำนวณไฟ 7 ดวง
int activeLeds = 0;
if (dustDensity < 20.0) activeLeds = 0;
else if (dustDensity < 40.0) activeLeds = 2;
else if (dustDensity < 60.0) activeLeds = 3;
else if (dustDensity < 80.0) activeLeds = 4;
else if (dustDensity < 100.0) activeLeds = 5;
else if (dustDensity < 120.0) activeLeds = 6;
else activeLeds = 7;
// สั่งเปิด-ปิดไฟ (Simulator = Active-High สั่ง HIGH ให้ติด)
for (int i = 0; i < 7; i++) {
if (i < activeLeds) digitalWrite(ledBarPins[i], HIGH);
else digitalWrite(ledBarPins[i], LOW);
}
Serial.printf("Temp: %.2f C, Dust (Simulated): %.2f ug/m3, LEDs: %d/7\n", temp, dustDensity, activeLeds);
}
}