-
Notifications
You must be signed in to change notification settings - Fork 4
G15: Human stress support system
| Name | GitHub |
|---|---|
| Ismaiel Sabet | IsmaielSemo |
| Islam Abdeen | Islamauc |
| Shaza Ali | ShazaAli |
Initial Proposal Presentation: https://docs.google.com/presentation/d/15qIhvaUgoBuKYNqpRnmv-6q4hrBTbnAHyQtF4mhVkXQ/edit
Progress Presentation: https://docs.google.com/presentation/d/1iJ_KwXfODH8SZaMu5e3o40hrdalOv2xpgm2F6IHnFfA/edit?slide=id.g3d63db8e731_0_15#slide=id.g3d63db8e731_0_15
Final Presentation: https://docs.google.com/presentation/d/1yA2vummIRzYLGS2uCpnEJDrOUXCZSGapRp8SkPjGbIw/edit?slide=id.g3e36e8cf39b_0_13#slide=id.g3e36e8cf39b_0_13
Stress is one of the most pervasive health challenges in academic and professional environments, yet it remains entirely invisible to the surrounding system. Most people only recognize they are stressed after the fact that performance has already degraded or focus has slipped.
The system uses the sensor MAX30102 (a photoplethysmography sensor) to capture pulse waveforms from the fingertip or wrist. These signals are then processed on the STM32L432KC (an embedded microcontroller) to extract Heart rate variablity features that are correlated with stress. The system was built to demonstrate a low-power, low-cost embedded health-monitoring pipeline that bridges biosignal acquisition, real-time DSP, behavioral feedback, and wireless communication, all running on a single microcontroller with BLE event logging to a smartphone terminal.
- Acquire a clean PPG signal using the MAX30102 sensor
- Interface the sensor with STM32L432KC via I2C
- Apply DSP signal processing to detect pulse peaks and compute inter-beat intervals
- Implement system control logic: if stressed → enable Breathing Mode; else → Monitor
- Drive a breathing guide LED (PB3) and buzzer with a dimming/pulsing pattern and musical tone when stress is detected
- Transmit event logs wirelessly via BLE Bluetooth Module over UART (PA2) to a smartphone terminal
- Power the full system from a regulated 3.7V LiPo battery with onboard LDO regulation to 3.3V
- Implement adaptive thresholding for stress detection to personalize sensitivity per user
- Add historical HRV trending and session summaries over BLE
- Develop a dedicated mobile app (beyond a serial terminal) for data visualization
- Implement low-power sleep modes between ADC samples to extend battery life
- Add SD card or flash logging for offline session data storage
Original Version:

Progress Presentation Version:

Final Version:

MAX30102 is a PPG sensor with high level of integration used for applications involving heart rate and blood oxygen measurements. The operation principle of MAX30102 sensor is based on illumination of biological tissue using red and infrared light sources and detecting light absorption or reflection from the blood vessels. The optical signal generated in such way changes periodically depending on the heart activity.
The I2C module of the STM32L432KC microcontroller fetches the PPG signal samples from the MAX30102 sensor at the appropriate frequency (usually 100 to 200 Hz, to reliably extract HRV).
The processing flow of PPG data in this software component is done in a systematic manner; starting from bandpass filtering for extracting the pulse wave, followed by peak detection for identifying every heart beat, inter-beat interval calculation, and HRV feature analysis.
Acting as the system's central state machine, this module interprets the stress classification output and routes behavior accordingly:
- If Stressed → activates Breathing Guide mode (LED dimming pattern via PB3 and buzzer sound)
- Else → remains in passive Monitor mode It also packages event data and dispatches them over UART (PA2) to the BLE module.
A BLE peripheral module receives UART event logs from the STM32 on PA2 and broadcasts them wirelessly to a paired smartphone. This allows clinicians, researchers, or the user themselves to observe real-time stress events and mode transitions.
A PWM-driven LED connected to PB3 produces a smooth dimming/brightening pattern that guides the user through a regulated breathing cycle (e.g., 4s inhale / 4s exhale). This serves as the primary real-time intervention when stress is detected. Right now, this LED is the 1.3" OLED
A PWM-driven buzzer connected to PB3 produces a musical tone that rises up when the user is breathing in, and falls down when the user breaths out.
A generic BLE serial terminal app on the smartphone displays event logs streamed from the system, including stress detection events, mode transitions, and session metadata — providing human-readable visibility into system state.
• MCP73831: A charge controller IC that handles one cell Lithium Polymer batteries using a 5V input from USB connections. The battery is charged safely with temperature control and overcharge prevention features, thus enabling convenient charging from any available USB port.
• 3.7V LiPo Cell: Provides the energy for the circuit. A small-sized 500-1000 mAh LiPo battery provides many hours of usage time, depending on the overall power consumption of the system.
• MCP1700 Voltage Regulator: Converts the LiPo battery voltage (between 3.0V to 4.2V) to 3.3V DC power. This DC power rail supplies all devices in the system, from microcontrollers, sensors, Bluetooth module, and indicator LEDs. Voltage regulation is essential to ensure accurate measurements using ADC and I2C communication between devices.
Circuit diagrams, pinout tables, and breadboard layouts.
| Component Name | Part Number | Qty | Cost (EGP) | Datasheet |
|---|---|---|---|---|
| Li-Po Battery 3.7V 500mAh (30405mm) | 503040 | 1 | 135.00 | View PDF |
| Lithium Battery Charger Module (Micro USB) | TP4056 | 1 | 17.50 | View PDF |
Order Totals:
- Subtotal: 697.50 EGP
- Card Fee (2%): 13.95 EGP
- Total: 711.45 EGP (Supplier: Micro Ohm Store)
Calculations ensuring your power supply can handle the peak current draw of all components combined.
The software for our system is built on a real-time, preemptive multitasking architecture utilizing FreeRTOS. This design decouples time-critical sensor acquisition and signal processing from computationally expensive algorithmic analysis and slower user interface updates.
The firmware follows a modular, four-tier embedded architecture to separate hardware-specific interactions from high-level application logic:
- Application Layer: Contains the core FreeRTOS threads (Task_FIFO, Task_HRV, Task_Display), the non-blocking audio/UI state machines, and the primary application logic.
-
Middleware/Library Layer:
- FreeRTOS: Manages task scheduling, prioritization, and execution.
- u8g2: Handles graphical rendering and buffer management for the OLED display.
- DSP & HRV Modules: Custom libraries (hrv.h, display.h) handling the mathematical computation of R-R intervals and stress indexing.
- Hardware Abstraction Layer (HAL): Utilizes the STM32 HAL to manage peripheral interfaces (I2C, UART, TIM, DMA) without exposing raw register manipulation to the upper layers.
- Hardware Layer: The physical STM32 microcontroller interacting directly with the MAX30102 sensor, SSD1306 OLED, PWM buzzer, and external BLE module.
The application leverages three primary RTOS threads, prioritized based on their strict timing requirements:
-
Data Acquisition Thread (Task_FIFO)
- Priority: Above Normal
- Role: Acts as the time-critical producer in the system. It continuously polls the MAX30102 via I2C for raw photoplethysmography (PPG) data.
- Execution: Processes incoming signals through a digital filter (process_ppg_signal), dynamically recalculates peak-detection envelopes, and logs precise microsecond timestamps (via TIM2) when a systolic peak (heartbeat) is detected.
- Ancillary Duties: Manages the non-blocking state machine for audio feedback (Music_Update) to ensure tone generation does not interrupt I2C reads.
-
Biometric Analysis Thread (Task_HRV)
- Priority: Normal
- Role: Handles the heavy mathematical computation decoupled from the fast sensor loop.
- Execution: Wakes periodically to evaluate the buffer of R-R intervals collected by the FIFO task. It calculates time-domain Heart Rate Variability (HRV) metrics such as SDNN and RMSSD, translating them into a normalized stress_index (0-100 scale).
- Telemetry: Formats the computed biometric data and transmits it over UART (to a BLE module) within a protected critical section.
-
User Interface Thread (Task_Display)
- Priority: Below Normal
- Role: Manages the OLED screen updates and user feedback.
- Execution: Operates as a state machine monitoring global system flags (finger_detected, hrv.valid, hrv.stress_index). Depending on the state, it renders a live scrolling waveform, displays static status messages ("PLACE FINGER", "ANALYZING..."), or triggers a guided breathing exercise animation if high stress is detected.



The accuracy of this biometric monitoring system relies on real-time Digital Signal Processing (DSP), adaptive threshold algorithms, and statistical analysis of heart rhythms. Below is a detailed breakdown of the mathematical and algorithmic logic implemented within the firmware.
The raw data emitted by the MAX30102 integrated photodiode contains a massive DC offset generated by constant light reflection off bone, muscle, and steady tissue, superimposed with a small AC component representing arterial pulse waves.
The raw IR value (i_v) is first parsed through process_ppg_signal(), which eliminates low-frequency baseline drift (DC tracking) and high-frequency ambient noise using a digital bandpass structure.
In the physical world, an influx of oxygenated blood during cardiac systole absorbs more infrared light, causing a sharp drop in the raw photodiode output voltage. To align this with standard medical visualization, the filtered output is inverted:
class="language-c">flt = -flt;
This converts negative-going absorption drops into standard positive-going systolic peaks, facilitating traditional peak-detection processing.
The amplitude of a user's PPG waveform varies dynamically based on finger pressure, skin perfusion, peripheral vascular resistance, and sweat layer changes. A fixed detection threshold would result in severe under-sensing or over-sensing. To combat this, the system calculates an adaptive threshold using a decaying envelope.
The system constantly tracks global extremes (ppg_max and ppg_min) from the inverted filtered data stream.
To ensure that a single massive motion artifact or cough does not permanently lock the threshold limits out of range, an automatic exponential decay contraction executes every 100 samples. The boundaries are compressed towards the waveform centre line (
This mathematical leak ensures the envelope naturally adapts back to nominal physiological levels within roughly one second of a transient noise burst.
The detection threshold is fixed at a 70% slicing level relative to the dynamic peak-to-peak amplitude range, optimised to clear baseline dicrotic notches while catching true beats:
Isolating the precise millisecond of a heartbeat is done via multi-stage verification to filter out false signals caused by small movements.
The algorithm tracks the current sample (flt), the previous sample (ppg_prev), and the sample before that (ppg_prev2). A potential peak is identified when the local slope switches from positive to negative:
The potential peak must prove it is a major cardiac event by surpassing both:
- The dynamic 70% threshold boundary
- A minimum baseline peak-to-peak amplitude window:
$Range > 200$ units
When a peak clears the amplitude rules, the time gap (
| Condition | Classification | Action |
|---|---|---|
|
|
High-frequency noise, muscle twitch, or double-count | Discarded |
|
|
Lost signal or finger lifted | Anchor reset — re-locks on next real pulse |
| Valid cardiac event | Accepted — timestamp logged |
Compilers, IDEs, and toolchains used (e.g., Keil, PlatformIO, STM32CubeIDE).
For the MAX30102, we tried to just read heart rate data from it and pass it to TeraTerm to be displayed. For the OLED, we first tried to just display any graph on it before then trying to pass the MAX30102 data to it.
The MAX30102 and OLED were both tested individually and in cooperation, with the heart data being read by the sensor and displayed on the OLED as a graph. This is highlighted in the demo video above.
Phase 1:
-
The physical connection between the sensor and the circuit board. For now, we had to press on the sensor to ensure this connection is stable, but sometimes this works other times not. A sustainable solution is needed. We are considering soldering the pins to ensure this connection. This will be done in consultation with the CSCE workshop.
-
Validating the heart rate with real, official measurement of the heart rate to ensure proper functionality.
-
Overcoming the unavailability of the CC1101 RF modules by transitioning from a wireless watch-based display to an integrated OLED interface
Our progress presentation video: https://drive.google.com/file/d/1ApTdS9diCfHVNc1OeKTF8sYErBYlYOBw/view?usp=drive_link Final presentation video: https://drive.google.com/file/d/1waWHkF-M01dHLum32-Ylnsn3v-d4LmJX/view
Data showing how well the project met its initial objectives (e.g., "Response time was measured at 12ms, well within our 50ms goal").
| Team Member | Responsibilities |
|---|---|
| Ismaiel Sabet | Hardware setup: MAX30102 wiring, electrode interfacing, ADC configuration on PA0, power supply regulation, PCB/breadboard layout |
| Shaza Ali | Firmware & DSP: ECG signal processing algorithm (DCP, R-peak detection, HRV stress classification), System Control Logic state machine, PWM LED breathing pattern (PB3) |
| Islam Abdeen | Wireless & Integration: BLE UART communication (PA2), smartphone terminal setup, system integration testing, documentation and demo preparation |
Note: All members are jointly responsible for system-level debugging, final integration testing, and project presentation.
| Milestone | Planned Date |
|---|---|
| M1 — component procurement | Week 1 |
| M2 — Hardware assembly: MAX30102 + STM32 wiring | Week 2 |
| M3 — DSP module implmentation | Week 2 |
| M4 — Stress classification logic tested | Week 3 |
| M5 — LED breathing pattern implemented (PB3 PWM) | Week 3 |
| M6 — BLE UART event logging to smartphone terminal | Week 4 |
| M7 — Full system integration & end-to-end test | Week 4 |
| M8 — Final demo & documentation submission | Week 5 |
https://github.com/Islamauc/Human_stress_control
The MAX30102 FIFO reading and register map: https://github.com/sparkfun/SparkFun_MAX3010x_Sensor_Library
The DC removal high-pass IIR filter (x - xprev + yprev * 0.995) is a standard single-pole high-pass used in many PPG implementations: https://github.com/aromring/MAX30102_by_RF
Peak detection, and HRV calculation targeting STM32, the RMSSD and SDNN calculations: https://github.com/pscholl/etherhrv
3-point peak detector logic (prev2 < prev && prev > current) is described in: https://github.com/blakeMilner/real_time_HRV