#define BLYNK_PRINT Serial
#define BLYNK_TEMPLATE_ID "TMPL6ZhZufyqA"
#define BLYNK_TEMPLATE_NAME "wator"
#define BLYNK_AUTH_TOKEN "yo_irz_3silctp6m7xXt6lY-KfxBA1uC"
#include <Wire.h>
#include <LiquidCrystal_I2C.h>
#include <WiFi.h>
#include <WiFiClient.h>
#include <HTTPClient.h>
#include <BlynkSimpleEsp32.h>
// WiFi Credentials
char ssid[] = "Wokwi-GUEST";
char pass[] = "";
// LINE Notify Access Token
String lineToken = "83jNlCXVFod5ZNB7S21X7wmUrKTLp1k2YmRlD3KVtua"; // Replace with your LINE Notify Access Token
// Ultrasonic Sensor Pins
#define TRIG_PIN 15
#define ECHO_PIN 4
#define BUZZER_PIN 5
// Variables
long echo;
float distance;
float distancecm;
int highwar = 404;
int currentLevel = -1; // Keeps track of current alert level (-1 = undefined)
int notifyCount[3] = {0}; // Array to track LINE Notify count for each level
// Time tracking
long previousLCDMillis = 0; // สำหรับการแสดงผลบน LCD
long previousAPIMillis = 0; // สำหรับการส่งข้อมูลไปยัง API
const long lcdInterval = 10000; // แสดงผลบน LCD ทุก 2 วินาที
const long apiInterval = 10000; // ส่งข้อมูล API ทุก 15 วินาที
// ตัวแปรสำหรับส่งสถานะบอร์ด
long previousStatusMillis = 0; // เก็บเวลาการส่งสถานะครั้งล่าสุด
const long statusInterval = 15000; // ส่งสถานะทุก 15 วินาที
// ตัวแปรสำหรับชื่อบอร์ด
const String boardName = "ESP32-Board-1"; // กำหนดชื่อบอร์ด
// LCD Configuration (I2C)
LiquidCrystal_I2C lcd(0x27, 16, 2); // I2C Address: 0x27, 16 columns, 2 rows
void setup() {
Serial.begin(9600);
// Set up I2C pins manually for ESP32
Wire.begin(22, 21); // SDA = D22, SCL = D21
// Initialize pins
pinMode(TRIG_PIN, OUTPUT);
pinMode(ECHO_PIN, INPUT);
pinMode(BUZZER_PIN, OUTPUT);
// Initialize LCD
lcd.init();
lcd.backlight();
lcd.setCursor(0, 0);
lcd.print("Initializing...");
// Connect to WiFi
connectToWiFi();
// Connect to Blynk
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Connecting Blynk");
Blynk.begin(BLYNK_AUTH_TOKEN, ssid, pass);
lcd.setCursor(0, 1);
lcd.print("Blynk Connected!");
delay(2000);
lcd.clear();
}
void loop() {
// ตรวจสอบการเชื่อมต่อ WiFi
if (WiFi.status() != WL_CONNECTED) {
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("WiFi Disconnected!");
delay(3000); // รอ 3 วินาทีแล้วลองเชื่อมต่อใหม่
connectToWiFi();
} else {
Blynk.run();
readSensor();
updateLCD(); // อัปเดตการแสดงผลบน LCD ทุก 2 วินาที
sendPeriodicAPI(); // ส่งข้อมูลไปยัง API ทุก 15 วินาที
sendBoardStatus(); // ส่งสถานะบอร์ดทุก 15 วินาที
}
}
void connectToWiFi() {
lcd.setCursor(0, 1);
lcd.print("Connecting WiFi");
WiFi.begin(ssid, pass);
int dotCount = 0;
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
lcd.setCursor(15 - dotCount, 1); // Add dots as connecting
lcd.print(".");
dotCount++;
if (dotCount > 15) {
lcd.setCursor(0, 1);
lcd.print("Connecting WiFi");
dotCount = 0;
}
}
lcd.setCursor(0, 1);
lcd.print("WiFi Connected! ");
Serial.println("\nWiFi Connected!");
delay(2000);
}
void readSensor() {
// Trigger ultrasonic sensor
digitalWrite(TRIG_PIN, LOW);
delayMicroseconds(2);
digitalWrite(TRIG_PIN, HIGH);
delayMicroseconds(10);
digitalWrite(TRIG_PIN, LOW);
// Read echo time and calculate distance
echo = pulseIn(ECHO_PIN, HIGH);
distancecm = (echo / 2.0) / 29.1; // Convert to cm
distance = max(0.0f, highwar - distancecm); // ใช้ 0.0f เพื่อให้เป็น float
// ตรวจสอบระดับความปลอดภัย
int newLevel;
if (distance > 150) {
newLevel = 0; // Level 0: Danger
} else if (distance <= 150 && distance >= 100) {
newLevel = 1; // Level 1: Caution
} else {
newLevel = 2; // Level 2: Safe Distance
}
// หากระดับเปลี่ยน ให้แจ้งเตือน
if (newLevel != currentLevel) {
currentLevel = newLevel;
switch (currentLevel) {
case 0: // Danger
sendLineNotify("สถานะอันตราย: ระยะห่างคือ " + String(distance) + " ซม. ระดับน้ำสูงเกินไป");
digitalWrite(BUZZER_PIN, HIGH); // เปิดเสียงแจ้งเตือน
resetNotifyCount();
break;
case 1: // Caution
if (notifyCount[1] == 0) {
sendLineNotify("สถานะเตือน: ระยะห่างคือ " + String(distance) + " ซม.");
notifyCount[1]++;
}
digitalWrite(BUZZER_PIN, LOW);
break;
case 2: // Safe Distance
if (notifyCount[2] == 0) {
sendLineNotify("สถานะปลอดภัย: ระยะห่างคือ " + String(distance) + " ซม.");
notifyCount[2]++;
}
digitalWrite(BUZZER_PIN, LOW);
break;
}
}
// ส่งข้อมูลไปยัง Blynk
Blynk.virtualWrite(V0, distance);
// Debugging
Serial.print("Distance: ");
Serial.print(distance);
Serial.println(" cm");
}
void updateLCD() {
if (millis() - previousLCDMillis >= lcdInterval) {
previousLCDMillis = millis();
lcd.clear();
lcd.setCursor(0, 0);
lcd.print("Distance:");
lcd.print(distance);
lcd.print(" cm");
lcd.setCursor(0, 1);
switch (currentLevel) {
case 0:
lcd.print("Danger! Too Close");
break;
case 1:
lcd.print("Caution!");
break;
case 2:
lcd.print("Safe Distance");
break;
}
}
}
void sendPeriodicAPI() {
if (millis() - previousAPIMillis >= apiInterval) {
previousAPIMillis = millis();
sendToAPI(distance, currentLevel);
}
}
void sendToAPI(float distance, int newLevel) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String apiUrl = "https://sandbox.thaikoon.co.th/APITKS/sensor/esp32wokwi.php";
http.begin(apiUrl);
http.addHeader("Content-Type", "application/json");
// Prepare JSON payload
String payload = "{\"distance\": " + String(distance) + ", \"level\": " + String(newLevel) + "}";
Serial.println("Sending to API: " + payload);
// http.setTimeout(5000); // 5 seconds timeout
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("Response: " + response);
} else {
Serial.println("Error sending to API.");
}
http.end();
} else {
Serial.println("WiFi not connected. Cannot send to API.");
}
}
void resetNotifyCount() {
for (int i = 0; i < 3; i++) {
notifyCount[i] = 0;
}
Serial.println("Notification counts reset.");
}
void sendLineNotify(String message) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
http.begin("https://notify-api.line.me/api/notify");
http.addHeader("Content-Type", "application/x-www-form-urlencoded");
http.addHeader("Authorization", "Bearer " + lineToken);
String payload = "message=" + message;
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
Serial.println("LINE Notify Sent!");
} else {
Serial.println("Error sending LINE Notify.");
}
http.end();
} else {
Serial.println("WiFi not connected. Cannot send LINE Notify.");
}
}
void sendBoardStatus() {
if (millis() - previousStatusMillis >= statusInterval) {
previousStatusMillis = millis();
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String apiUrl = "https://sandbox.thaikoon.co.th/APITKS/sensor/esp32wokwistatus.php";
http.begin(apiUrl);
http.addHeader("Content-Type", "application/json");
// JSON payload
String payload = "{\"status\": \"online\", \"board_name\": \"" + boardName + "\"}";
Serial.println("Sending Board Status: " + payload);
int httpResponseCode = http.POST(payload);
if (httpResponseCode > 0) {
String response = http.getString();
Serial.println("Board Status Response: " + response);
} else {
Serial.println("Error sending board status.");
}
http.end();
} else {
Serial.println("WiFi not connected. Cannot send board status.");
}
}
}