An IoT-enabled fire safety solution featuring:
- STM32-based Sensor Nodes for real-time monitoring of fire/environmental parameters
- ESP32 Fire Alarm Control Panel serving as both gateway and cloud interface
- Modular Architecture using C++ Abstract Factory Pattern for flexible sensor management
- Edge-to-Cloud Integration with AWS IoT for remote monitoring and alerts
- STM32 Sensor Node continuously monitor all sensors and communicates with the ESP32 FACP via SPI.
- FACP conducts heartbeat checks - pings the Sensor Node, receiving acknowledgments in normal operation.
- On anomaly, Sensor Node raises an interrupt, prompting the FACP to request detailed sensor readings.
- Cloud reporting: FACP transmits health metrics and emergency events via MQTT (AWS IoT Core).
✅ Modular & Scalable Design
• Abstract Factory Pattern in C++ for dynamic sensor management.
• Plug-and-play expandability: Add more Sensor Nodes to the FACP for larger deployments.
✅ Multi-Sensor Monitoring (Sensor Node STM32) (Notes on Notion)
The sensor node has 3 groups of sensors:
🔥 Fire Detection: Temperature, Smoke, Gas, Flame sensors
💧 Environmental: Humidity, VOC sensors
♨️ Smart Sensing: Ambient Light, Thermal IR sensors
(Supports up to 8 sensors per node with configurable thresholds)
✅ Fire Alarm Control Panel Node (ESP32) (Notes on Notion) (Doxygen Documentation)
• Active Monitoring: Periodically checks sensor node health via SPI.
• Event-Driven Response: Instantly reacts to interrupt-based anomaly alerts from sensor nodes.
• Scalable Architecture: Supports daisy-chaining multiple sensor nodes for large-scale deployments.
✅ Robust Communication Stack
🔹 UART Debugging:
• Serial logs for sensor status, diagnostics, and development.
🔹 Hardware Interrupt Line:
• Low-latency Sensor Node to FACP anomaly alerts (Node → FACP)
🔹 SPI:
• Heartbeat checks (FACP → Node → FACP)
• On-demand sensor data transmission (Node → FACP)
✅ Edge Processing: Anomalies are identified at the sensor node level.
✅ Cloud Integration: Lightweight AWS IoT Core messaging for live sensor status and emergency alerts.
To support scalable deployments and dynamic sensor configuration, we use the Abstract Factory Pattern in C++. This allows the system to flexibly create related groups of sensors without hardcoding specific sensor types into the logic.
🧩 Factory Structure
┌────────────────────┐
│ SensorFactory │ → Abstract base class
└────────────────────┘
▲ ▲ ▲
┌─────────────────┘ │ └─────────────────┐
▼ ▼ ▼
┌─────────────────┐ ┌────────────────────┐ ┌──────────────────┐
FireSensorFactory EnvironSensorFactory SmartSensorFactory
└─────────────────┘ └────────────────────┘ └──────────────────┘
Each concrete factory creates a specific family of sensors:
🔥 FireSensorFactory → Temp, Smoke, Gas, Flame Sensors
🌿 EnvironSensorFactory → Humidity, VOC Sensors
💡 SmartSensorFactory → Ambient Light, Thermal IR Sensors
This SPI communication protocol uses a two-phase approach to allow the slave device sufficient time to process incoming commands and prepare a response:
🔁 Phase 1: Command Transmission
• Master (ESP32) initiates communication by sending a command.
• Slave (STM32) receives the command and replies with dummy bytes.
• The slave parses the command and prepares the appropriate response for the next phase.
📤 Phase 2: Response Retrieval
• Master sends dummy bytes to generate clock cycles for the SPI bus.
• Slave transmits the prepared response over SPI in real time.
✅ Health Status Check – "Are you alive?"
This is a basic handshake to check if the slave is responsive.
| Master | Slave |
| Phase 1 Command Sent: "Are you alive?" | Phase 1 Command received: "Are you alive?" |
| Phase 1 DUMMY received: FF FF FF FF | Phase 1 DUMMY sent: FF FF FF FF |
| | |
| Phase 2 Command Sent: FF FF FF FF | Phase 2 Command received: FF FF FF FF |
| Phase 2 DUMMY received: "I'm alive" | Phase 2 DUMMY sent: "I'm alive" |
📊 Sensor Data Request – Triggered on Anomaly Detection
Upon detecting an anomaly, the master requests the latest sensor readings from the slave.
| Master | Slave |
| Phase 1 Command Sent: "Data Request" | Phase 1 Command received: "Data Request" |
| Phase 1 DUMMY received: FF FF FF FF | Phase 1 DUMMY sent: FF FF FF FF |
| | |
| Phase 2 Command Sent: FF FF FF FF | Phase 2 Command received: FF FF FF FF |
| Phase 2 DUMMY received: "1.1, 2.2,..." | Phase 2 DUMMY sent: "1.1, 2.2, 3.3..." |
[Sensors] → [STM32 Sensor Node] → [SPI] → [ESP32 FACP/Cloud Node] → [MQTT] → [Cloud Dashboard]
𐂷 Sensor Node
⎔ VS Code - Primary code editor for STM32 firmware development
⎔ OpenOCD - Used for flashing and debugging over SWD
⎔ Makefile - Handles compilation, linking, and build automation
🌐 FACP / Cloud Gateway
⎔ ESP-IDF - Official development framework for ESP32 firmware
⎔ VS Code - Development environment with ESP-IDF integration and UART debugging
⎔ AWS Cloud - Powers the IoT backend with services like:
• AWS IoT Core – Secure device connectivity and MQTT messaging
• Amazon Timestream – Time-series database for storing sensor data
| STM32 PIN | Interface | ESP32 Pin |
|---|---|---|
| PA6 | SPI MISO | GPIO19 |
| PA7 | SPI MOSI | GPIO23 |
| PA4 | SPI NSS | GPIO5 |
| PA5 | SPI SCK | GPIO18 |
| PB6 | GPIO Interrupt | GPIO22 |
| GND | GND | GND |
📁 Smart-Fire-Detection-System/
│── 📁 stm32_sensor_node/
│ ├── 📄 main.c (Entry point of the program)
│ ├── 📄 factory.cpp / .h (Abstract Factory pattern implementation)
│ ├── 📄 sensor.cpp / .h (Base sensor classes and interfaces)
│ ├── 📄 wrapper.cpp / .h (Hardware abstraction layer wrappers)
│ ├── 📄 simulate.c / .h (Sensor data simulation)
│ ├── 📄 spi.c / .h (SPI & GPIO Interrupt Communication)
│ ├── 📄 uart.c / .h (UART Communication)
│ ├── 📄 systick.c / .h (Systick Timer)
│ ├── 📄 Makefile (Build system configuration)
│── 📁 esp32_facp_cloud_node/
│ ├── 📄 main.c (Entry point of the program, Tasks)
│ ├── 📄 spi.c / .h (SPI & GPIO Interrupt Communication)
│ ├── 📄 uart.c / .h (UART Communication)
│ ├── 📄 wifi.c / .h (WiFi Connectivity)
│ ├── 📄 cloud.c / .h (MQTT for AWS Connectivity)
│ ├── 📄 CMakeLists.txt (Build system configuration)
│── 📄 README.md (Documentation)
