/*
* ระบบควบคุมอุตสาหกรรมด้วยเซ็นเซอร์หลายตัว
* ESP32 Multi-Sensor Industrial Control System
*
* อุปกรณ์ที่ใช้:
* - ESP32 DevKit
* - Relay Module 3 Channel
* - LED 2 สี (แดง, เขียว)
* - DC Motor (ควบคุมผ่าน Relay 3)
* - Servo Motor
* - OLED Display 0.96" I2C
* - Ultrasonic Sensor HC-SR04
* - Flying-fish MQ-2 Gas Sensor
* - DHT11 Temperature & Humidity Sensor
*
* การทำงาน:
* 1. Ultrasonic: ระยะ 40-60 cm → Servo หมุน 90° + Relay1 ON
* 2. Flying-fish: ตรวจจับแก๊ส → LED แดง ON + Relay2 ON
* ไม่ตรวจจับ → LED เขียว ON
* 3. DHT11: วัดความชื้น → DC Motor ON (Relay3)
*/
#include <ESP32Servo.h>
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
#include <DHT.h>
// ========== กำหนดค่า OLED ==========
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define OLED_RESET -1
#define SCREEN_ADDRESS 0x3C
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
// ========== กำหนดขา Ultrasonic Sensor (HC-SR04) ==========
#define TRIG_PIN 5 // Trigger Pin
#define ECHO_PIN 18 // Echo Pin
// ========== กำหนดขา Flying-fish Gas Sensor (MQ-2) ==========
#define GAS_SENSOR_PIN 34 // Analog Input (ADC)
#define GAS_DIGITAL_PIN 35 // Digital Output (ถ้ามี)
// ========== กำหนดขา DHT11 ==========
#define DHT_PIN 4 // Data Pin DHT11
#define DHTTYPE DHT11 // ประเภทเซ็นเซอร์
DHT dht(DHT_PIN, DHTTYPE);
// ========== กำหนดขา Relay (3 Channel) ==========
#define RELAY1_PIN 19 // Relay 1 (สำหรับ Ultrasonic)
#define RELAY2_PIN 21 // Relay 2 (สำหรับ Gas Sensor)
#define RELAY3_PIN 22 // Relay 3 (สำหรับ DC Motor)
// ========== กำหนดขา LED ==========
#define LED_RED 25 // LED แดง (ตรวจจับแก๊ส)
#define LED_GREEN 26 // LED เขียว (ไม่ตรวจจับแก๊ส)
// ========== กำหนดขา Servo Motor ==========
#define SERVO_PIN 23 // PWM Pin สำหรับ Servo
Servo myServo;
// ========== เกณฑ์และค่าคงที่ ==========
// Ultrasonic
const float DISTANCE_MIN = 40.0; // ระยะขั้นต่ำ (cm)
const float DISTANCE_MAX = 60.0; // ระยะสูงสุด (cm)
// Gas Sensor
const int GAS_THRESHOLD = 1500; // เกณฑ์ตรวจจับแก๊ส (0-4095)
// DHT11
const float HUMIDITY_THRESHOLD = 60.0; // เกณฑ์ความชื้น (%)
// Servo
const int SERVO_OFF = 0; // มุมปิด (0 องศา)
const int SERVO_ON = 90; // มุมเปิด (90 องศา)
// ========== ตัวแปรเก็บค่าเซ็นเซอร์ ==========
float distance = 0; // ระยะทางจาก Ultrasonic (cm)
int gasValue = 0; // ค่าแก๊สจาก Flying-fish
float temperature = 0; // อุณหภูมิจาก DHT11 (°C)
float humidity = 0; // ความชื้นจาก DHT11 (%)
// ========== สถานะการทำงาน ==========
bool ultrasonicActive = false; // Ultrasonic ทำงาน
bool gasDetected = false; // ตรวจจับแก๊ส
bool motorActive = false; // DC Motor ทำงาน
// ========== ตัวแปรเวลา ==========
unsigned long lastDisplayUpdate = 0;
unsigned long lastSensorRead = 0;
const unsigned long DISPLAY_UPDATE = 500; // อัพเดทหน้าจอทุก 500ms
const unsigned long SENSOR_READ_INTERVAL = 200; // อ่านเซ็นเซอร์ทุก 200ms
// ========== ฟังก์ชัน Setup ==========
void setup() {
// เริ่มต้น Serial
Serial.begin(115200);
Serial.println("\n========================================");
Serial.println(" ESP32 Multi-Sensor Control System");
Serial.println("========================================\n");
delay(1000);
// เริ่มต้น I2C และ OLED
Wire.begin();
if(!display.begin(SSD1306_SWITCHCAPVCC, SCREEN_ADDRESS)) {
Serial.println(F("ไม่พบ OLED Display"));
for(;;);
}
// แสดงหน้าจอเริ่มต้น
displayBootScreen();
// ตั้งค่า Ultrasonic
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
// ตั้งค่า Gas Sensor
pinMode(GAS_SENSOR_PIN, INPUT);
pinMode(GAS_DIGITAL_PIN, INPUT);
// ตั้งค่า DHT11
dht.begin();
// ตั้งค่า Relay (Active HIGH)
pinMode(RELAY1_PIN, OUTPUT);
pinMode(RELAY2_PIN, OUTPUT);
pinMode(RELAY3_PIN, OUTPUT);
digitalWrite(RELAY1_PIN, LOW);
digitalWrite(RELAY2_PIN, LOW);
digitalWrite(RELAY3_PIN, LOW);
// ตั้งค่า LED
pinMode(LED_RED, OUTPUT);
pinMode(LED_GREEN, OUTPUT);
digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, HIGH); // เริ่มต้นเป็นสีเขียว
// ตั้งค่า Servo
myServo.attach(SERVO_PIN);
myServo.write(SERVO_OFF);
Serial.println("ระบบเริ่มต้นสำเร็จ");
Serial.println("กำลังตรวจสอบเซ็นเซอร์...\n");
delay(2000);
}
// ========== ฟังก์ชัน Loop หลัก ==========
void loop() {
// อ่านค่าจากเซ็นเซอร์ทั้งหมด
if (millis() - lastSensorRead >= SENSOR_READ_INTERVAL) {
readAllSensors();
processLogic();
lastSensorRead = millis();
}
// อัพเดทหน้าจอ OLED
if (millis() - lastDisplayUpdate >= DISPLAY_UPDATE) {
updateDisplay();
lastDisplayUpdate = millis();
}
delay(50);
}
// ========== อ่านค่าเซ็นเซอร์ทั้งหมด ==========
void readAllSensors() {
// 1. อ่านค่า Ultrasonic Sensor
distance = readUltrasonic();
// 2. อ่านค่า Gas Sensor (Flying-fish)
gasValue = analogRead(GAS_SENSOR_PIN);
// 3. อ่านค่า DHT11
humidity = dht.readHumidity();
temperature = dht.readTemperature();
// ตรวจสอบข้อผิดพลาด DHT11
if (isnan(humidity) || isnan(temperature)) {
Serial.println("ไม่สามารถอ่านค่า DHT11");
humidity = 0;
temperature = 0;
}
}
// ========== อ่านค่า Ultrasonic Sensor ==========
float readUltrasonic() {
// ส่งสัญญาณ Trigger
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// รับสัญญาณ Echo
long duration = pulseIn(ECHO_PIN, HIGH, 30000); // Timeout 30ms
// คำนวณระยะทาง (cm)
float dist = duration * 0.034 / 2.0;
// กรองค่าที่ผิดปกติ
if (dist == 0 || dist > 400) {
dist = 999; // ค่าผิดปกติ
}
return dist;
}
// ========== ประมวลผลและควบคุม ==========
void processLogic() {
// ========== 1. ควบคุมด้วย Ultrasonic Sensor ==========
// เงื่อนไข: ระยะ 40-60 cm → Servo 90° + Relay1 ON
if (distance >= DISTANCE_MIN && distance <= DISTANCE_MAX) {
if (!ultrasonicActive) {
ultrasonicActive = true;
myServo.write(SERVO_ON);
digitalWrite(RELAY1_PIN, HIGH);
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println("📏 ULTRASONIC ACTIVATED");
Serial.print(" ระยะ: ");
Serial.print(distance);
Serial.println(" cm");
Serial.println(" ✓ Servo → 90°");
Serial.println(" ✓ Relay 1 → ON");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
}
} else {
if (ultrasonicActive) {
ultrasonicActive = false;
myServo.write(SERVO_OFF);
digitalWrite(RELAY1_PIN, LOW);
Serial.println("ULTRASONIC DEACTIVATED");
Serial.println(" Servo → 0°");
Serial.println(" Relay 1 → OFF\n");
}
}
// ========== 2. ควบคุมด้วย Flying-fish Gas Sensor ==========
// เงื่อนไข: ตรวจจับแก๊ส → LED แดง + Relay2 ON
// ไม่ตรวจจับ → LED เขียว
if (gasValue > GAS_THRESHOLD) {
if (!gasDetected) {
gasDetected = true;
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_GREEN, LOW);
digitalWrite(RELAY2_PIN, HIGH);
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println(" GAS DETECTED!");
Serial.print(" ค่าแก๊ส: ");
Serial.println(gasValue);
Serial.println(" LED แดง → ON");
Serial.println(" Relay 2 → ON");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
}
} else {
if (gasDetected) {
gasDetected = false;
digitalWrite(LED_RED, LOW);
digitalWrite(LED_GREEN, HIGH);
digitalWrite(RELAY2_PIN, LOW);
Serial.println("GAS CLEAR");
Serial.println(" LED เขียว → ON");
Serial.println(" Relay 2 → OFF\n");
}
}
// ========== 3. ควบคุมด้วย DHT11 ==========
// เงื่อนไข: ความชื้น >= 60% → DC Motor ON (Relay3)
if (humidity >= HUMIDITY_THRESHOLD) {
if (!motorActive) {
motorActive = true;
digitalWrite(RELAY3_PIN, HIGH);
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━");
Serial.println("💧 HIGH HUMIDITY");
Serial.print(" ความชื้น: ");
Serial.print(humidity);
Serial.println(" %");
Serial.print(" อุณหภูมิ: ");
Serial.print(temperature);
Serial.println(" °C");
Serial.println(" DC Motor → ON");
Serial.println(" Relay 3 → ON");
Serial.println("━━━━━━━━━━━━━━━━━━━━━━━━━━━━\n");
}
} else {
if (motorActive) {
motorActive = false;
digitalWrite(RELAY3_PIN, LOW);
Serial.println("NORMAL HUMIDITY");
Serial.println(" DC Motor → OFF");
Serial.println(" Relay 3 → OFF\n");
}
}
}
// ========== แสดงหน้าจอเริ่มต้น ==========
void displayBootScreen() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
display.setCursor(10, 5);
display.println(F("ESP32 CONTROL"));
display.setCursor(25, 18);
display.println(F("SYSTEM"));
display.drawRect(0, 30, 128, 2, SSD1306_WHITE);
display.setCursor(5, 40);
display.println(F("Multi-Sensor"));
display.setCursor(5, 52);
display.println(F("Initializing..."));
display.display();
delay(2000);
}
// ========== อัพเดทหน้าจอ OLED ==========
void updateDisplay() {
display.clearDisplay();
display.setTextSize(1);
display.setTextColor(SSD1306_WHITE);
// หัวข้อ
display.setCursor(0, 0);
display.println(F("=SENSOR MONITOR="));
// แสดงค่า Ultrasonic
display.setCursor(0, 12);
display.print(F("Dist:"));
if (distance < 400) {
display.print(distance, 1);
display.print(F("cm"));
} else {
display.print(F("---"));
}
// สถานะ Ultrasonic
display.setCursor(70, 12);
if (ultrasonicActive) {
display.print(F("[ACTIVE]"));
} else {
display.print(F("[OFF]"));
}
// แสดงค่า Gas
display.setCursor(0, 24);
display.print(F("Gas:"));
display.print(gasValue);
// สถานะ Gas
display.setCursor(70, 24);
if (gasDetected) {
display.print(F("[ALERT]"));
} else {
display.print(F("[SAFE]"));
}
// แสดงค่า DHT11
display.setCursor(0, 36);
display.print(F("Temp:"));
display.print(temperature, 1);
display.print(F("C"));
display.setCursor(0, 48);
display.print(F("Humi:"));
display.print(humidity, 1);
display.print(F("%"));
// สถานะ Motor
display.setCursor(70, 48);
if (motorActive) {
display.print(F("[MOTOR]"));
} else {
display.print(F("[IDLE]"));
}
// แถบสถานะด้านล่าง
display.drawRect(0, 56, 128, 8, SSD1306_WHITE);
// Relay Status Indicators
if (ultrasonicActive) {
display.fillRect(2, 58, 10, 4, SSD1306_WHITE);
}
display.setCursor(14, 58);
display.print(F("R1"));
if (gasDetected) {
display.fillRect(32, 58, 10, 4, SSD1306_WHITE);
}
display.setCursor(44, 58);
display.print(F("R2"));
if (motorActive) {
display.fillRect(62, 58, 10, 4, SSD1306_WHITE);
}
display.setCursor(74, 58);
display.print(F("R3"));
// Servo Position
display.setCursor(92, 58);
display.print(F("S:"));
display.print(ultrasonicActive ? 90 : 0);
display.display();
}
// ========== สรุปข้อมูลในหน้าจอ Serial ==========
void printSystemStatus() {
Serial.println("\n════════════════════════════════════");
Serial.println(" SYSTEM STATUS REPORT ");
Serial.println("════════════════════════════════════");
Serial.print("Ultrasonic: ");
Serial.print(distance, 1);
Serial.print(" cm ");
Serial.println(ultrasonicActive ? "[ACTIVE]" : "[OFF] ");
Serial.print("Gas Sensor: ");
Serial.print(gasValue);
Serial.print(" ");
Serial.println(gasDetected ? "[ALERT] " : "[SAFE] ");
Serial.print("Temperature: ");
Serial.print(temperature, 1);
Serial.println(" °C ");
Serial.print("Humidity: ");
Serial.print(humidity, 1);
Serial.println(" % ");
Serial.print("DC Motor: ");
Serial.println(motorActive ? "ON " : "OFF ");
Serial.println("════════════════════════════════════");
Serial.print(" Relay1: ");
Serial.print(ultrasonicActive ? "ON " : "OFF ");
Serial.print("│ Relay2: ");
Serial.print(gasDetected ? "ON " : "OFF ");
Serial.print("│ Relay3: ");
Serial.println(motorActive ? "ON " : "OFF ");
Serial.println("════════════════════════════════════\n");
}