This shows you the differences between two versions of the page.
iothings:proiecte:2025sric:esp32-smart-access-monitor [2025/05/29 17:16] robert_george.pancu [Hardware] |
iothings:proiecte:2025sric:esp32-smart-access-monitor [2025/05/29 17:48] (current) robert_george.pancu [Challenges] |
||
---|---|---|---|
Line 34: | Line 34: | ||
====== Software ====== | ====== Software ====== | ||
+ | |||
+ | Technologies Used | ||
+ | |||
+ | * Arduino Framework (ESP32 Core): Used to program the microcontroller. | ||
+ | |||
+ | * HTML/CSS/JavaScript: Used for building a responsive web interface. | ||
+ | |||
+ | * Chart.js: JavaScript library used for rendering the real-time people count chart. | ||
+ | |||
+ | * Embedded Web Server (ESP32): Hosts the HTML page and handles HTTP requests. | ||
+ | |||
=== Code Snippets === | === Code Snippets === | ||
+ | |||
+ | <code cpp> | ||
+ | #include <WiFi.h> | ||
+ | #include <WebServer.h> | ||
+ | |||
+ | #define BUZZER_PIN 4 | ||
+ | #define IR_SENSOR_A 25 | ||
+ | #define IR_SENSOR_B 26 | ||
+ | |||
+ | const char* ssid = ""; | ||
+ | const char* wifiPassword = ""; | ||
+ | const char* correctPassword = ""; | ||
+ | |||
+ | WebServer server(80); | ||
+ | |||
+ | int peopleCount = 0; | ||
+ | unsigned long doorOpenTime = 0; | ||
+ | const unsigned long doorOpenDuration = 10000; | ||
+ | bool doorOpen = false; | ||
+ | |||
+ | enum IRState { | ||
+ | IDLE, | ||
+ | ENTER_STAGE_1, | ||
+ | EXIT_STAGE_1 | ||
+ | }; | ||
+ | |||
+ | IRState state = IDLE; | ||
+ | unsigned long lastTriggerTime = 0; | ||
+ | |||
+ | void buzzerSuccess() { | ||
+ | for (int i = 0; i < 3; i++) { | ||
+ | tone(BUZZER_PIN, 1000); | ||
+ | delay(150); | ||
+ | noTone(BUZZER_PIN); | ||
+ | delay(150); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void buzzerError() { | ||
+ | tone(BUZZER_PIN, 500); | ||
+ | delay(1000); | ||
+ | noTone(BUZZER_PIN); | ||
+ | } | ||
+ | |||
+ | void handleSubmit() { | ||
+ | if (!server.hasArg("pass")) { | ||
+ | server.send(400, "text/plain", "Bad Request"); | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | String enteredPass = server.arg("pass"); | ||
+ | if (enteredPass == correctPassword) { | ||
+ | doorOpen = true; | ||
+ | doorOpenTime = millis(); | ||
+ | buzzerSuccess(); | ||
+ | Serial.println("Door opened for 10 seconds."); | ||
+ | server.send(200, "text/plain", "Access Granted: door open"); | ||
+ | } else { | ||
+ | buzzerError(); | ||
+ | server.send(200, "text/plain", "Access Denied"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void handleCount() { | ||
+ | String json = "{\"count\": " + String(peopleCount) + "}"; | ||
+ | server.send(200, "application/json", json); | ||
+ | } | ||
+ | |||
+ | void handleDoorStatus() { | ||
+ | if (doorOpen) { | ||
+ | server.send(200, "text/plain", "opened"); | ||
+ | } else { | ||
+ | server.send(200, "text/plain", "closed"); | ||
+ | } | ||
+ | } | ||
+ | |||
+ | void setup() { | ||
+ | Serial.begin(115200); | ||
+ | pinMode(BUZZER_PIN, OUTPUT); | ||
+ | pinMode(IR_SENSOR_A, INPUT_PULLUP); | ||
+ | pinMode(IR_SENSOR_B, INPUT_PULLUP); | ||
+ | |||
+ | WiFi.begin(ssid, wifiPassword); | ||
+ | while (WiFi.status() != WL_CONNECTED) { | ||
+ | delay(500); | ||
+ | Serial.print("."); | ||
+ | } | ||
+ | Serial.println("\nConnected to WiFi"); | ||
+ | Serial.println(WiFi.localIP()); | ||
+ | |||
+ | server.on("/", handleRoot); | ||
+ | server.on("/submit", HTTP_POST, handleSubmit); | ||
+ | server.on("/count", handleCount); | ||
+ | server.on("/doorstatus", handleDoorStatus); | ||
+ | server.begin(); | ||
+ | } | ||
+ | |||
+ | void loop() { | ||
+ | server.handleClient(); | ||
+ | |||
+ | unsigned long now = millis(); | ||
+ | int sensorA = digitalRead(IR_SENSOR_A); | ||
+ | int sensorB = digitalRead(IR_SENSOR_B); | ||
+ | |||
+ | if (doorOpen && now - doorOpenTime >= doorOpenDuration) { | ||
+ | doorOpen = false; | ||
+ | Serial.println("Door closed"); | ||
+ | state = IDLE; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | if (!doorOpen) { | ||
+ | state = IDLE; | ||
+ | return; | ||
+ | } | ||
+ | |||
+ | switch (state) { | ||
+ | case IDLE: | ||
+ | if (sensorA == LOW && sensorB == HIGH) { | ||
+ | state = ENTER_STAGE_1; | ||
+ | lastTriggerTime = now; | ||
+ | } else if (sensorB == LOW && sensorA == HIGH) { | ||
+ | state = EXIT_STAGE_1; | ||
+ | lastTriggerTime = now; | ||
+ | } | ||
+ | break; | ||
+ | |||
+ | case ENTER_STAGE_1: | ||
+ | if (sensorB == LOW && now - lastTriggerTime < 2000) { | ||
+ | peopleCount++; | ||
+ | Serial.print("Entered → Total: "); | ||
+ | Serial.println(peopleCount); | ||
+ | state = IDLE; | ||
+ | delay(500); | ||
+ | } else if (now - lastTriggerTime >= 2000) { | ||
+ | state = IDLE; | ||
+ | } | ||
+ | break; | ||
+ | |||
+ | case EXIT_STAGE_1: | ||
+ | if (sensorA == LOW && now - lastTriggerTime < 2000) { | ||
+ | peopleCount = max(0, peopleCount - 1); | ||
+ | Serial.print("Exited → Total: "); | ||
+ | Serial.println(peopleCount); | ||
+ | state = IDLE; | ||
+ | delay(500); | ||
+ | } else if (now - lastTriggerTime >= 2000) { | ||
+ | state = IDLE; | ||
+ | } | ||
+ | break; | ||
+ | } | ||
+ | } | ||
+ | |||
+ | </code> | ||
+ | |||
+ | WEB | ||
+ | |||
+ | {{iothings:proiecte:2025sric:dashboard.png?600 | Web Dashboard}} | ||
+ | |||
====== Challenges ====== | ====== Challenges ====== | ||
+ | Sensor Accuracy and Timing | ||
+ | |||
+ | * Differentiating between entry and exit requires precise detection and timing. | ||
+ | * Simultaneous movement or people hesitating at the doorway can cause incorrect counts. | ||
+ | * Solution: Implemented a state machine with timeouts to improve reliability. | ||
+ | |||
+ | Resource Limitations on ESP32 | ||
+ | |||
+ | * Hosting a full HTML page, JavaScript logic, and handling concurrent client requests pushed the memory limits. | ||
+ | * Optimized the web page content and avoided large libraries to keep the firmware lean. | ||
+ | |||
+ | Security Considerations | ||
+ | * Password is sent in plain text and checked locally, making it vulnerable in open networks. | ||
+ | * Future improvements could include HTTPS support or token-based authentication. | ||
====== References ====== | ====== References ====== | ||
+ | * https://ocw.cs.pub.ro/courses/iothings/laboratoare/2022/lab3 | ||
+ | * https://randomnerdtutorials.com/esp32-web-server-arduino-ide/ | ||
+ | * https://www.w3schools.com/ |