· last year · Feb 12, 2025, 03:41 AM
1#define BLYNK_TEMPLATE_ID "TMPL60PHVGDEq"
2#define BLYNK_TEMPLATE_NAME "TANAWA"
3#define BLYNK_AUTH_TOKEN "PtI4d8oCiM5gFwMRiOW69Hs6Nzof8caC"
4
5#define BLYNK_PRINT Serial
6#include <BlynkSimpleEsp32.h>
7#include <HTTPClient.h>
8#include <Arduino.h>
9#include <WiFi.h>
10#include "time.h"
11#include <ESP32Servo.h>
12#include <WebServer.h>
13
14WebServer server(80); // Create an HTTP server on port 80
15
16char auth[] = BLYNK_AUTH_TOKEN;
17BlynkTimer timer;
18
19// Wi-Fi credentials
20const char* ssid = "AOBY_2.4";
21const char* password = ""; // password hidden for data privacy purposes
22const char* ntpServer = "time.google.com"; // Using Google NTP server
23
24const long gmtOffset_sec = 3600 * 8; // Philippines Time (UTC +8)
25const int daylightOffset_sec = 0; // No DST in the Philippines
26
27// Pin definitions
28const int trigPin = 5;
29const int echoPin = 18;
30const int ledPin = 19;
31const int buzzerPin = 21;
32const int servoPin = 23;
33
34// Constants for sound speed and distance conversion
35#define SOUND_SPEED 0.034
36#define CM_TO_INCH 0.393701
37
38long duration;
39float distanceCm;
40float distanceInch;
41String receivedText;
42
43// Global variables for task synchronization
44QueueHandle_t alarmQueue;
45
46Servo servo1;
47
48String time_info;
49int alarm_info;
50bool is_servo_fixed_control;
51
52// Global flag to ensure only one capture request is sent per detection event.
53volatile bool captureTriggered = false;
54
55#define SWITCH_VPIN V2 // Use V2 for the switch in the Blynk app
56#define CAPTURE_VPIN V3
57
58// Blynk function to handle the switch state
59BLYNK_WRITE(SWITCH_VPIN) {
60 int switchState = param.asInt();
61 if (switchState == 1) {
62 is_servo_fixed_control = true;
63 servo1.write(0); // Move to 90° when switch is ON
64 Serial.println("Servo moved to 0°");
65 } else {
66 is_servo_fixed_control = false;
67 servo1.write(90); // Move to 0° when switch is OFF
68 Serial.println("Servo moved to 90°");
69 }
70}
71
72BLYNK_WRITE(CAPTURE_VPIN) {
73 int captureState = param.asInt();
74 if (captureState == 1) {
75 bool alarmSignal = true;
76 xQueueSend(alarmQueue, &alarmSignal, portMAX_DELAY);
77 }
78}
79
80void sendCaptureRequest() {
81 HTTPClient http;
82 Serial.println("Sending capture request to Flask server...");
83
84 http.begin("http://192.168.254.112/capture"); // ESP32 CAM code capture // CHANGE IP
85 http.addHeader("Content-Type", "application/json"); // Set JSON header
86 int httpResponseCode = http.GET(); // Send empty JSON body for POST request
87
88 if (httpResponseCode > 0) {
89 Serial.print("Capture Request Sent Successfully, Response code: ");
90 Serial.println(httpResponseCode);
91 } else {
92 Serial.print("Capture Request Failed: ");
93 Serial.println(http.errorToString(httpResponseCode).c_str());
94 }
95
96 http.end();
97}
98
99
100void sendSensor() {
101 struct tm timeinfo;
102 if (!getLocalTime(&timeinfo)) {
103 Serial.println("Failed to obtain time");
104 return;
105 }
106 char formattedTime[20];
107 strftime(formattedTime, sizeof(formattedTime), "%Y%m%d_%H%M%S", &timeinfo);
108 time_info = String(formattedTime);
109 xQueueReceive(alarmQueue, &alarm_info, portMAX_DELAY);
110 Blynk.virtualWrite(V0, time_info);
111 Blynk.virtualWrite(V1, receivedText);
112 // Blynk.virtualWrite(V1, alarm_info);
113}
114
115void sendplateNumber() {
116 Blynk.virtualWrite(V1, receivedText);
117
118}
119
120void printLocalTime() {
121 struct tm timeinfo;
122 if (!getLocalTime(&timeinfo)) {
123 Serial.println("Failed to obtain time");
124 return;
125 }
126 char formattedTime[20];
127 strftime(formattedTime, sizeof(formattedTime), "%Y%m%d_%H%M%S", &timeinfo);
128 Serial.print(formattedTime);
129}
130
131// Task to control the servo motor
132void controlServoTask(void *pvParameters) {
133 while (true) {
134 bool alarm = false;
135 if (xQueueReceive(alarmQueue, &alarm, portMAX_DELAY)) {
136 if (!is_servo_fixed_control) {
137 vTaskDelay(pdMS_TO_TICKS(2000));
138 if (alarm && receivedText == "LMM 8923") {
139 servo1.write(0);
140 } else {
141 servo1.write(90);
142 }
143 }
144 }
145 vTaskDelay(pdMS_TO_TICKS(100));
146 }
147}
148
149// Task to measure distance using the ultrasonic sensor
150void measureDistanceTask(void *pvParameters) {
151 unsigned long objectDetectedTime = 0;
152 while (true) {
153 // Trigger the ultrasonic pulse
154 digitalWrite(trigPin, LOW);
155 delayMicroseconds(2);
156 digitalWrite(trigPin, HIGH);
157 delayMicroseconds(10);
158 digitalWrite(trigPin, LOW);
159
160 // Measure pulse duration on echo pin
161 duration = pulseIn(echoPin, HIGH);
162 if (duration > 0 && duration < 30000) {
163 distanceCm = duration * SOUND_SPEED / 2;
164 distanceInch = distanceCm * CM_TO_INCH;
165
166 // If an object is detected within 6 inches:
167 if (distanceInch < 6) {
168 if (objectDetectedTime == 0) {
169 objectDetectedTime = millis();
170 } else if (millis() - objectDetectedTime >= 3000) {
171 bool alarmSignal = true;
172 xQueueSend(alarmQueue, &alarmSignal, portMAX_DELAY);
173 }
174 } else {
175 objectDetectedTime = 0;
176 bool alarmSignal = false;
177 xQueueSend(alarmQueue, &alarmSignal, portMAX_DELAY);
178 }
179 }
180 vTaskDelay(pdMS_TO_TICKS(100));
181 }
182}
183
184void alarmTask(void *pvParameters) {
185 bool lastAlarm = false; // Keep track of the previous alarm state
186
187 while (true) {
188 bool alarm = false;
189 // Wait to receive the latest alarm state from the queue.
190 if (xQueueReceive(alarmQueue, &alarm, portMAX_DELAY)) {
191 // Only trigger when alarm goes from false to true.
192 if (alarm && !lastAlarm) {
193 lastAlarm = true; // Update state
194
195 Serial.print("Date/Time: ");
196 printLocalTime();
197 Serial.println(" - VEHICLE DETECTED!");
198
199 // Reset receivedText when a new vehicle is detected
200 receivedText = "";
201 Serial.println("🔄 Reset receivedText for new detection.");
202
203 // Trigger alarm pattern (LED & buzzer)
204 for (int i = 0; i < 3; i++) {
205 digitalWrite(ledPin, HIGH);
206 digitalWrite(buzzerPin, HIGH);
207 vTaskDelay(pdMS_TO_TICKS(100));
208 digitalWrite(ledPin, LOW);
209 digitalWrite(buzzerPin, LOW);
210 vTaskDelay(pdMS_TO_TICKS(100));
211 }
212
213 // Send the capture request only once per detection event.
214 if (!captureTriggered) {
215 sendCaptureRequest();
216 captureTriggered = true;
217 }
218 }
219 // When the alarm goes from true to false, reset the flag.
220 else if (!alarm && lastAlarm) {
221 lastAlarm = false;
222 captureTriggered = false;
223 }
224 }
225 vTaskDelay(pdMS_TO_TICKS(100));
226 }
227}
228
229// Function to handle received text from Flask
230void handleTextReception() {
231 if (server.hasArg("text")) {
232 receivedText = server.arg("text");
233 Serial.print("📌 Extracted Text Received: ");
234 Serial.println(receivedText);
235 sendSensor();
236 }
237 server.send(200, "text/plain", "Text received");
238}
239
240void setup() {
241 Serial.begin(115200);
242
243 // Initialize pins for sensor, LED, buzzer.
244 pinMode(trigPin, OUTPUT);
245 pinMode(echoPin, INPUT);
246 pinMode(ledPin, OUTPUT);
247 pinMode(buzzerPin, OUTPUT);
248
249 // Attach servo.
250 servo1.attach(servoPin);
251
252 // Connect to Wi-Fi.
253 Serial.print("Connecting to ");
254 Serial.println(ssid);
255 WiFi.begin(ssid, password);
256 while (WiFi.status() != WL_CONNECTED) {
257 delay(500);
258 Serial.print(".");
259 }
260 Serial.println("\nWiFi connected.");
261 Serial.print("WiFi Signal Strength: ");
262 Serial.println(WiFi.RSSI());
263
264 // Initialize time synchronization.
265 configTime(gmtOffset_sec, daylightOffset_sec, ntpServer);
266 struct tm timeinfo;
267 int attempts = 0;
268 while (!getLocalTime(&timeinfo) && attempts < 5) {
269 Serial.println("Failed to obtain time, retrying...");
270 delay(2000);
271 attempts++;
272 }
273 if (attempts == 5) {
274 Serial.println("Failed to obtain time after multiple attempts.");
275 } else {
276 Serial.println("Time successfully synchronized!");
277 printLocalTime();
278 Serial.println();
279 }
280
281 // Create a queue to synchronize alarm signals.
282 alarmQueue = xQueueCreate(5, sizeof(bool));
283
284 // Start Blynk.
285 Blynk.begin(auth, ssid, password);
286 timer.setInterval(10000L, sendplateNumber);
287
288 server.on("/receive_text", HTTP_GET, handleTextReception);
289 server.begin();
290 Serial.println("🔹 HTTP Server Started on ESP32");
291
292 // Create FreeRTOS tasks.
293 xTaskCreate(measureDistanceTask, "Measure Distance", 4096, NULL, 2, NULL);
294 xTaskCreate(alarmTask, "Alarm", 4096, NULL, 1, NULL);
295 xTaskCreate(controlServoTask, "Servo", 4096, NULL, 1, NULL);
296}
297
298void loop() {
299 // Let Blynk and its timer run.
300 Blynk.run();
301 timer.run();
302 server.handleClient();
303
304 if (alarm_info == 1) {
305 Blynk.logEvent("vehicle_detected", "Vehicle Detected! It wants to enter.");
306 }
307}