#include <WiFi.h>
#include <PubSubClient.h>
#include <ArduinoJson.h>
// ตั้งค่า MQTT
const char* mqtt_server = "mqtt-dashboard.com"; // หรือ MQTT broker ที่คุณใช้งานจริง
const int mqtt_port = 1883;
const char* mqtt_user = "Detect"; // ใช้ username ที่คุณตั้งไว้
const char* mqtt_password = "1234"; // ใช้ password ที่คุณตั้งไว้
const char* mqtt_clientId = "clientId-gaGnJtBAzp";
const char* topic_publish_pir = "MQTT_/sensor/PIR"; // Topic ที่ส่งข้อมูลการเคลื่อนไหว
const char* topic_subscribe_buzzer = "MQTT_/Buzzer"; // Topic ที่ควบคุม Buzzer
// ข้อมูลการเชื่อมต่อ WiFi
const char* ssid = "Wokwi-GUEST"; // ชื่อ WiFi ของ Wokwi
const char* password = ""; // ไม่มีรหัสผ่านสำหรับ Wokwi
// การตั้งค่าอุปกรณ์
String device_id = "Sensors";
WiFiClient wifiClient;
PubSubClient mqtt_client(wifiClient);
// ตั้งค่า PIR Sensor และ Buzzer
#define PIR_Pin 2
#define Buzzer_Pin 13
// ตัวแปร
bool motionDetected = false;
bool lastMotionState = false;
// ตัวแปรสำหรับการหน่วงเวลา
unsigned long previousMillis = 0;
const long interval = 1000; // หน่วงเวลา 1 วินาที
void setup() {
Serial.begin(115200);
pinMode(PIR_Pin, INPUT);
pinMode(Buzzer_Pin, OUTPUT);
Serial.println("\n\nWelcome to PIR_Sensor_and_Buzzer\n");
// เริ่มต้นการเชื่อมต่อ Wi-Fi
setup_wifi();
// เชื่อมต่อกับ MQTT broker
mqtt_client.setServer(mqtt_server, mqtt_port);
mqtt_client.setCallback(callback);
mqtt_connect();
}
void loop() {
unsigned long currentMillis = millis();
// ตรวจสอบเวลาหน่วง
if (currentMillis - previousMillis >= interval) {
previousMillis = currentMillis;
// ตรวจสอบ PIR Sensor และส่งสถานะ
motionDetected = digitalRead(PIR_Pin);
sendPIRStatus();
}
// รักษาการเชื่อมต่อ MQTT
if (!mqtt_client.connected()) {
mqtt_connect();
} else {
mqtt_client.loop(); // จัดการการสื่อสาร MQTT
}
}
void setup_wifi() {
Serial.println();
Serial.print("กำลังเชื่อมต่อ WiFi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
Serial.println("\nWiFi เชื่อมต่อแล้ว");
Serial.print("IP address: ");
Serial.println(WiFi.localIP());
}
void mqtt_connect() {
while (!mqtt_client.connected()) {
Serial.println("กำลังพยายามเชื่อมต่อ MQTT...");
if (mqtt_client.connect(mqtt_clientId, mqtt_user, mqtt_password)) {
Serial.println("เชื่อมต่อ MQTT เรียบร้อย");
mqtt_subscribe(topic_subscribe_buzzer); // สมัครรับข้อมูลจาก topic สำหรับควบคุม Buzzer
} else {
Serial.print("ล้มเหลว, rc=");
Serial.print(mqtt_client.state());
Serial.println(" ลองใหม่อีกครั้งใน 5 วินาที");
delay(5000);
}
}
}
void mqtt_publish(const char* topic, const char* data) {
if (mqtt_client.publish(topic, data)) {
Serial.println("ส่งข้อความไปยัง topic \"" + String(topic) + "\" สำเร็จ: " + String(data));
} else {
Serial.println("ไม่สามารถส่งข้อความไปยัง topic \"" + String(topic) + "\" ได้");
}
}
void mqtt_subscribe(const char* topic) {
if (mqtt_client.subscribe(topic)) {
Serial.println("สมัครรับข้อมูลจาก topic \"" + String(topic) + "\" สำเร็จ");
} else {
Serial.println("ไม่สามารถสมัครรับข้อมูลจาก topic \"" + String(topic) + "\" ได้");
}
}
void sendPIRStatus() {
// ส่งสถานะของ PIR Sensor เมื่อสถานะมีการเปลี่ยนแปลง
if (motionDetected != lastMotionState) {
lastMotionState = motionDetected;
// ส่งสถานะ PIR
StaticJsonDocument<200> doc;
doc["device_id"] = device_id;
doc["type"] = "PIR";
doc["motionDetected"] = motionDetected ? "ตรวจพบการเคลื่อนไหว" : "ไม่พบการเคลื่อนไหว";
char jsonBuffer[512];
serializeJson(doc, jsonBuffer);
mqtt_publish(topic_publish_pir, jsonBuffer);
// พิมพ์สถานะ PIR
Serial.println("ส่งสถานะ PIR: " + String(motionDetected ? "ตรวจพบการเคลื่อนไหว" : "ไม่พบการเคลื่อนไหว"));
// ควบคุม Buzzer หากตรวจพบการเคลื่อนไหว
if (motionDetected) {
digitalWrite(Buzzer_Pin, HIGH); // เปิด Buzzer
Serial.println("ตรวจพบการเคลื่อนไหว, เปิด Buzzer");
} else {
digitalWrite(Buzzer_Pin, LOW); // ปิด Buzzer
Serial.println("ไม่พบการเคลื่อนไหว, ปิด Buzzer");
}
}
}
void callback(char* topic, byte* payload, unsigned int length) {
String message = "";
for (unsigned int i = 0; i < length; i++) {
message += (char)payload[i];
}
// สร้าง StaticJsonDocument เพื่อจัดการกับ JSON payload
StaticJsonDocument<200> doc;
DeserializationError error = deserializeJson(doc, message);
// ตรวจสอบว่าการ deserialize สำเร็จหรือไม่
if (error) {
Serial.println("ไม่สามารถแปลง JSON ได้");
return;
}
// ตรวจสอบว่า topic เป็นสำหรับควบคุมบัซเซอร์
if (String(topic) == topic_subscribe_buzzer) {
const char* value = doc["value"]; // ดึงค่า value จาก JSON
// เช็คคำสั่งสำหรับเปิด/ปิดบัซเซอร์
if (String(value) == "1") {
digitalWrite(Buzzer_Pin, HIGH); // เปิดบัซเซอร์
Serial.println("ได้รับคำสั่ง: เปิด Buzzer");
} else if (String(value) == "0") {
digitalWrite(Buzzer_Pin, LOW); // ปิดบัซเซอร์
Serial.println("ได้รับคำสั่ง: ปิด Buzzer");
} else {
// ในกรณีที่ได้รับคำสั่งที่ไม่ถูกต้อง
Serial.println("ได้รับคำสั่งที่ไม่ถูกต้องสำหรับ Buzzer: " + String(value));
}
}
// เพิ่มการจัดการคำสั่งเพิ่มเติมที่นี่
else {
Serial.println("ได้รับข้อความจาก topic ที่ไม่รู้จัก: " + String(topic));
}
}