This project implements a real-time embedded predictive maintenance system on STM32 microcontrollers using Zephyr RTOS.
It simulates industrial machines equipped with multiple sensors, logs sensor data in real time, and performs on-device anomaly detection to identify abnormal operating conditions. The system is designed to be modular, scalable, and suitable for resource-constrained embedded environments.
- This README provides a high-level overview of the project's goals, architecture, and core features.
- Detailed development notes, design decisions, and implementation reasoning are documented in Notion Workspace
- Feature-specific explanations and deep technical breakdowns are linked directly within the relevant sections below.
- Complete API and module documentation is automatically generated using Doxygen Documentaion.
- The generated documentation is hosted on GitHub Pages
- Zephyr RTOS-Based Embedded Architecture
- Built on Zephyr RTOS running on STM32 microcontrollers
- Leverages Zephyr's kernel primitives for threading, synchronization, and timing
- Designed for deterministic execution and portability across supported boards
- Zephyr RTOS in STM32 Setup Guide: STM32 + Zephyr + VSCode
Zephyr RTOS·STM32·Embedded Systems·Real-Time Operating Systems
- Object-Oriented Machine & Sensor Modeling
- Uses Object-Oriented Design to model Machines and Sensors, enabling polymorphic access to different sensor types
- Implements the Factory Method Pattern to dynamically create sensors at runtime based on type identifiers
- Combines C++ core logic with C-compatible wrapper APIs, allowing seamless integration with Zephyr's C-based ecosystem
C / C++·OOP·Design Patterns·Factory Method·C/C++ Interoperability
- Multithreaded Data Pipeline
- Multiple worker threads perform independent tasks including sensor updates, data collection, and anomaly detection
- Threads emit structured log events to a shared message queue
- A dedicated logger thread serializes and prints all output, preventing race conditions on the terminal
Multithreading·Producer–Consumer Pattern·Message Queues·Thread Synchronization
- On-Device Anomaly Detection
- Sensor readings are continuously compared against defined normal operating ranges
- Statistical detection logic identifies deviations indicating abnormal behavior
- Anomaly handling is event-driven, minimizing unnecessary CPU usage
Anomaly Detection·Edge Computing·Predictive Maintenance·Statistical Analysis
- Doxygen Documentation
- Fully documented using Doxygen with clear function, module, and data structure description.
- Generate browsable HTML documentation published via GitHub Pages from the
docs/directory.
Documentation·Maintainability·Code Quality
[📡 Sensors] → [🧵 Threads] → [💾 Buffer] → [🤖 Detection] → [📊 Logging]
↓ ↓ ↓ ↓ ↓
Simulated Data Pipeline Circular Statistical Centralized
Values (5 Threads) Buffer Analysis Output
The system uses 5 concurrent threads with different priorities to implement a staged data processing pipeline:
- Thread 1:
sensor_data_writerPriority = 3
- Generates simulated sensor values within realistic operating ranges
- Writes values into sensor objects via the Factory Pattern interface
- Emits log events describing written values
- Thread 2:
data_collectorPriority = 4
- Reads sensor data from sensor objects
- Writes collected data into a circular buffer for time-series analysis
- Emits log events to verify data flow correctness
- Thread 3:
anomaly_detectorPriority = 5
- Consumes data from the circular buffer
- Performs statistical anomaly detection (range checking, threshold comparison)
- Emits log events describing detection results (normal/anomaly)
- Signal
anomaly_handlervia semaphore when an anomaly is detected
- Thread 4:
anomaly_handlerPriority = 6
- Sleeps until signaled by
anomaly_detector - When activated:
- Dumps circular buffer contents to terminal
- Logs anomaly details with timestamp
- Emits alert messages
- Thread 5:
system_loggerPriority = 7.
- Sole owner of terminal output — prevents race conditions
- Consumes structured log messages from a thread-safe queue
- Prints logs in a serialized manner with thread identification tags
- Example Output:
[Thread 1] Machine 1 - Temp: 75.3°C, Pressure: 120psi, Vibration: 1.2mm/s [Thread 2] Added to buffer: 75.3 [Thread 3] Running inference... MSE: 0.023 ✅ Normal [Thread 3] ANOMALY DETECTED! MSE: 0.087 ⚠️ [Thread 4] ⚠️⚠️⚠️ ANOMALY ALERT ⚠️⚠️⚠️ [Thread 4] Buffer dump: [72.1, 73.5, 74.8, 78.2, 85.4, 90.1, 95.7]
| Mechanism | Purpose | Protected Resource |
|---|---|---|
| Mutex | Protect sensor object access | Thread 1 (write) vs Thread 2 (read) |
| Mutex | Protect circular buffer | Thread 2 (write) vs Threads 3/4 (read) |
| Semaphore | Signal anomaly detection | Thread 3 → Thread 4 |
| Message Queue | Centralized logging | All threads → Thread 5 |
Each industrial machine is equipped with specific sensors for predictive maintenance:
- Air Compressor (
AIR_COMPRESSOR)
- Temperature:
60-100°C• Pressure:72-145 psi• Vibration:0.5-2.0 mm/s - Monitors overheating, pressure fluctuations, and mechanical wear
- Steam Boiler (
STEAM_BOILER)
- Temperature:
150-250°C• Pressure:87-360 psi - Tracks thermal efficiency and safety thresholds
- Electric Motor (
ELECTRIC_MOTOR)
- Temperature:
60-105°C - Winding insulation safety range
├── 📁 edge_pm/ # Edge PM Zephyr Application
│ ├── 📁 src/ # Core application source files
│ │ ├── 📄 main.c # Zephyr application entry point & initialization
│ │ ├── 📁 core/ # Core utilities and algorithms
│ │ │ ├── 📄 circular_buffer.c # Ring buffer for time-series sensor data
│ │ │ └── 📄 detection.c # Anomaly detection logic
│ │ ├── 📁 machines/ # Machine and device logic
│ │ │ ├── 📄 sensor.cpp # Sensor class implementations (C++)
│ │ │ └── 📄 wrapper.cpp # C wrapper API for sensor objects
│ │ ├── 📁 threads/ # Zephyr threads
│ │ │ ├── 📄 thread_anomaly_detect.c # Anomaly detection thread
│ │ │ ├── 📄 thread_anomaly_handle.c # Thread to handle anomaly events
│ │ │ ├── 📄 thread_sensor_read.c # Sensor read thread
│ │ │ ├── 📄 thread_sensor_write.c # Sensor write thread
│ │ │ └── 📄 thread_system_logger.c # Centralized logging thread
│ │ └── 📁 utils/ # Utility modules
│ │ └── 📄 demo.cpp # Demo/C++ interop examples
│ │
│ ├── 📁 include/ # Public headers
│ │ ├── 📁 core/ # Core headers
│ │ ├── 📁 machines/ # Machine headers
│ │ ├── 📁 threads/ # Thread headers
│ │ └── 📁 utils/ # Utility headers
│ │
│ ├── 📄 CMakeLists.txt # Build configuration
│ ├── 📄 prj.conf # Zephyr kernel and module configuration
│ ├── 📄 Doxyfile # Doxygen documentation configuration
│ └── 📄 README.md # Project overview and documentation