Skip to content

Latest commit

Β 

History

22 Commits

Folders and files

NameName
Last commit message
Last commit date
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 
Β 

Repository files navigation

❀️ ECG Stress Detection with HR / HRV

On-device worker stress classification with Arduino Portenta H7, ECG sensing and Edge Impulse

Arduino Edge Impulse ECG License: MIT

Roni Bandini β€” Buenos Aires, Argentina Project started November 2024 Β· inference sketch January 2025

HR-HRV is an experimental wearable Machine Learning project that classifies worker stress from ECG signals directly on an Arduino Portenta H7.

The signal is acquired with a SparkFun AD8232 Single Lead Heart Rate Monitor and processed using the Edge Impulse HR/HRV Features block.

The resulting physiological features feed a neural-network classifier with two output classes:

stress
working

Inference runs locally on the Portenta H7. The onboard RGB LEDs provide immediate visual feedback.

Experimental project for exploring ECG, HR/HRV feature extraction and Edge Machine Learning. It is not intended as a medical diagnostic device.


✨ Features

  • ❀️ Single-lead ECG acquisition
  • 🧠 On-device stress classification
  • πŸ“ˆ Edge Impulse HR/HRV DSP block
  • ⏱️ 40-second inference window
  • πŸ“Š 50 Hz ECG acquisition
  • πŸ”¬ HR and interbeat-interval feature extraction
  • 🚨 85% stress confidence threshold
  • πŸ”΄ Red LED for detected stress
  • 🟒 Green LED for normal working state
  • πŸ“¦ Compiled Arduino HR library included
  • πŸ”Œ Leads-off electrode detection
  • πŸ§ͺ Alternative Elemyo ECG implementation included

πŸ—οΈ Architecture

flowchart LR
    BODY["❀️ ECG Electrodes"]
    AD["AD8232 ECG Front End"]
    PORTENTA["Arduino Portenta H7"]
    HRV["Edge Impulse<br/>HR / HRV DSP"]
    NN["🧠 Neural Network"]
    CLASS{"Classification"}
    RED["πŸ”΄ Stress"]
    GREEN["🟒 Working"]

    BODY --> AD
    AD -->|"A0"| PORTENTA
    PORTENTA --> HRV
    HRV --> NN
    NN --> CLASS
    CLASS -->|"stress > 85%"| RED
    CLASS -->|"otherwise"| GREEN
Loading

The complete inference pipeline executes on the Portenta H7 without requiring remote inference.


🧠 Arduino Portenta H7

The project uses the Arduino Portenta H7.

Specification Value
MCU STM32H747XI
Main CPU Cortex-M7 @ 480 MHz
Secondary CPU Cortex-M4 @ 240 MHz
Internal Flash 2 MB
Internal RAM 1 MB
External Flash 16 MB
External SDRAM 8 MB
Wireless Wi-Fi + Bluetooth
USB USB-C

Its Cortex-M7 provides enough processing power to run the HR/HRV feature extraction and classifier locally.


❀️ ECG Sensor

The original version uses the:

πŸ‘‰ SparkFun Single Lead Heart Rate Monitor β€” AD8232

The AD8232 amplifies and filters the small electrical signals captured by three ECG electrodes.

The project uses:

OUTPUT β†’ A0
LO-    β†’ D2
LO+    β†’ D3

The LO+ and LO- outputs detect disconnected electrodes.


πŸ”Œ Wiring

AD8232 Portenta H7
OUTPUT A0
LO- D2
LO+ D3
GND GND
3.3 V 3.3 V

Electrode placement used in the original experiment:

Yellow β†’ Left
Red    β†’ Right
Green  β†’ Below red

Complete reference:

πŸ‘‰ Wearable for Monitoring Worker Stress β€” Edge Impulse


πŸ“Š Data Acquisition

Training acquisition sketch:

πŸ‘‰ acquisition.ino

The sketch defines:

#define FREQUENCY_HZ 50

and streams the analog ECG value:

Serial.println(
    analogRead(A0)
);

only while both leads-off inputs indicate a valid electrode connection.

Serial speed:

Serial.begin(115200);

The onboard LEDs also indicate electrode state.


πŸ“‘ Edge Impulse Data Forwarder

After uploading acquisition.ino, run:

edge-impulse-data-forwarder

The expected acquisition frequency is:

50 Hz

The original workflow collected approximately:

10–20 samples per class
120 seconds per sample
10% reserved for testing

Typical classes:

working
stress

Official walkthrough:

πŸ‘‰ ECG HR/HRV Portenta Tutorial


🧠 HR / HRV Processing

The project uses the Edge Impulse HR/HRV Features block.

HR is the number of heartbeats per minute.

HRV describes variations between consecutive beats β€” the interbeat interval / RR interval.

ECG waveform
     ↓
R peaks
     ↓
Interbeat intervals
     ↓
HR / HRV features
     ↓
Machine Learning

The Edge Impulse block can produce features including:

Time domain

HR Mean
HR Slope
IBI Slope
RMSSD
RMSSD Slope
AVNN
SDNN
Range NN
MAD NN
pNN50

Frequency domain

VLF Energy
LF Energy
HF Energy
Total Energy
Relative VLF / LF / HF
LF/HF Ratio
Peak VLF / LF / HF

The configuration used by this project is intentionally compact:

Signal: ECG
Filter preset: 1
Window: 40 seconds
HRV feature group: none

The HR-derived features are then passed to the classifier.


🧠 Edge Impulse Model

Public project:

πŸ‘‰ Heart Rate Analysis β€” Edge Impulse Project #558080

Current impulse:

Parameter Value
Input ECG
Frequency 50 Hz
Window 40,000 ms
Window stride 40,000 ms
Classes stress, working
Input features to NN 20
Validation accuracy 89.3%
Test accuracy 94.4%

Current reported Portenta H7 performance for the float32 model:

Metric Value
Latency 11 ms
Peak RAM 17.7 KB
Flash 14 KB

🧠 Neural Network

The custom Keras architecture is compact:

20 input features
        ↓
Dense 20 / ReLU
        ↓
Dense 10 / ReLU
        ↓
2-class Softmax

Training configuration used for the published model:

Training cycles: 40
Learning rate:   0.005
Batch size:      30
Auto weighting:  Disabled

The resulting validation accuracy was:

89.3%

πŸ”¬ Training Pipeline

flowchart LR
    ECG["❀️ ECG @ 50 Hz"]
    HRV["HR / HRV Block"]
    FEATURES["20 Features"]
    NN["Dense Neural Network"]
    STRESS["stress"]
    WORK["working"]

    ECG --> HRV
    HRV --> FEATURES
    FEATURES --> NN
    NN --> STRESS
    NN --> WORK
Loading

πŸ“¦ Deployment

The repository contains the compiled Arduino library:

πŸ‘‰ heart-rate-analysis-hr-library-portenta-compiled.zip

The original Edge Impulse deployment procedure is:

  1. Export the model as an Arduino library.
  2. Unzip it locally.
  3. Download: edgeimpulse/example-hr-lib-arm
  4. Copy those support files into the deployment folder.
  5. Zip the complete folder again.
  6. Install it through:
Arduino IDE
β†’ Sketch
β†’ Include Library
β†’ Add .ZIP Library

The resulting library exposes:

#include <arduino-hrv.h>

Current Edge Impulse documentation notes that HR/HRV block evaluation is available broadly, while hardware deployment requires Enterprise enablement.


❀️ Inference Firmware

Main application:

πŸ‘‰ ecg2.ino

The model expects:

float features[2000];

corresponding to:

40 seconds Γ— 50 Hz = 2000 ECG samples

The sketch continuously fills this buffer from:

analogRead(A0);

and passes it to:

run_classifier(
    &features_signal,
    &result,
    false
);

🎯 Stress Threshold

The current source uses:

float threesold = 0.85;

A stress event is detected when:

result.classification[ix].value > threesold

and:

result.classification[ix].label == "stress"

Therefore:

stress confidence > 85%
          ↓
       STRESS

πŸ”΄ 🟒 LED Feedback

The Portenta onboard LEDs are used as the local interface.

Stress

digitalWrite(LEDR, LOW);
digitalWrite(LEDG, HIGH);

Result:

πŸ”΄ Red ON
🟒 Green OFF

Normal state

digitalWrite(LEDG, LOW);
digitalWrite(LEDR, HIGH);

Result:

🟒 Green ON
πŸ”΄ Red OFF

No external screen is required.


πŸ”„ Runtime Flow

flowchart TD
    ECG["❀️ Read ECG"]
    LEADS{"Electrodes connected?"}
    BUFFER["Store in 2000-sample buffer"]
    HRV["HR / HRV Processing"]
    ML["🧠 Classification"]
    SCORE{"stress > 0.85?"}
    RED["πŸ”΄ Red LED"]
    GREEN["🟒 Green LED"]

    ECG --> LEADS
    LEADS -->|"Yes"| BUFFER
    LEADS -->|"No"| ECG
    BUFFER --> HRV
    HRV --> ML
    ML --> SCORE
    SCORE -->|"Yes"| RED
    SCORE -->|"No"| GREEN
    RED --> ECG
    GREEN --> ECG
Loading

πŸ› οΈ Hardware

Component Quantity
Arduino Portenta H7 1
SparkFun AD8232 ECG Sensor 1
ECG electrode cable 1
Disposable electrode pads 3
Female-female jumper wires 5
USB-C cable 1

Machine Learning platform:

πŸ‘‰ Edge Impulse


πŸš€ Installation

1. Install Arduino IDE

πŸ‘‰ Arduino IDE

2. Install Portenta Support

From Boards Manager install:

Arduino Mbed OS Portenta Boards

Select:

Arduino Portenta H7 (M7 core)

Hardware documentation:

πŸ‘‰ Arduino Portenta H7


3. Clone the Repository

git clone https://github.com/ronibandini/hr-hrv.git
cd hr-hrv

Repository:

πŸ‘‰ github.com/ronibandini/hr-hrv


4. Install the Model

Add:

πŸ‘‰ heart-rate-analysis-hr-library-portenta-compiled.zip

through:

Sketch
β†’ Include Library
β†’ Add .ZIP Library

5. Upload

For data collection:

πŸ‘‰ acquisition.ino

For stress inference:

πŸ‘‰ ecg2.ino

Serial Monitor:

115200 baud

Startup:

Stress detection started
Roni Bandini, Jan 2025

πŸ§ͺ Elemyo Version

The repository also contains a later adaptation for an Elemyo MYO-series EMG/ECG module:

πŸ“‚ elemyo/

Files:

The acquisition version uses:

#define CSpin 7
#define sensorInPin A1

and applies notch filters around:

50 Hz
100 Hz

through the Elemyo library before forwarding ECG samples.

The adaptation was added in May 2025.


πŸ“ Repository Structure

hr-hrv/
β”‚
β”œβ”€β”€ acquisition.ino
β”œβ”€β”€ ecg2.ino
β”œβ”€β”€ heart-rate-analysis-hr-library-portenta-compiled.zip
β”‚
β”œβ”€β”€ elemyo/
β”‚   β”œβ”€β”€ acquisition3.ino
β”‚   β”œβ”€β”€ ecg3.ino
β”‚   └── readme.txt
β”‚
β”œβ”€β”€ README.md
└── LICENSE

🌐 External References

🧠 Edge Impulse Expert Network

Complete official tutorial for this project:

πŸ‘‰ Wearable for Monitoring Worker Stress using HR/HRV DSP Block β€” Arduino Portenta


🧠 Public Edge Impulse Project

Dataset, impulse, HR/HRV processing block, classifier and model testing:

πŸ‘‰ Heart Rate Analysis β€” Project #558080


❀️ Edge Impulse HR / HRV Documentation

Full list of HR and HRV time-domain and frequency-domain features:

πŸ‘‰ HR/HRV Features Block

Technical background:

πŸ‘‰ Getting the Pulse: Technical Insights Into Edge Impulse's HR and HRV Blocks


♾️ Arduino

Official Portenta H7 documentation:

πŸ‘‰ Arduino Portenta H7


❀️ SparkFun

AD8232 ECG sensor hookup, electrode placement and example waveforms:

πŸ‘‰ AD8232 Heart Rate Monitor Hookup Guide


🧩 Edge Impulse HR Library

Support library required by the original HR/HRV Arduino deployment workflow:

πŸ‘‰ edgeimpulse/example-hr-lib-arm


πŸ”— Related GitHub Projects

🧍 BTFall

TinyML worker fall detection with Arduino Nano 33 BLE Sense, Edge Impulse, BLE and Raspberry Pi.

πŸ‘‰ github.com/ronibandini/BTFall

πŸ’ͺ Rotator Cuff Recovery

TinyML shoulder-movement recognition using accelerometer data and Edge Impulse.

πŸ‘‰ github.com/ronibandini/rotatorCuffRecovery

❀️ Heart & Respiration Monitor

Contactless heart-rate and respiration monitoring with mmWave radar, UNIHIKER and ESP32-C6.

πŸ‘‰ github.com/ronibandini/heartRespirationMonitor

🏍️ TinyML Tire Care

Motion-pattern classification using XIAO nRF52840 Sense and Edge Impulse.

πŸ‘‰ github.com/ronibandini/XIAOnRF52840TireCare


πŸ“• Contracultura Maker

Contracultura Maker is a book by Roni Bandini about maker culture, experimental electronics, AI, physical computing and technological autonomy.

πŸ“‚ Contracultura Maker β€” GitHub repository

πŸ“• Download Contracultura Maker PDF


πŸ“¬ Contact

Roni Bandini Maker Β· AI Developer Β· Writer Buenos Aires, Argentina


Built with ❀️ + ECG + HR/HRV + Edge Machine Learning.

Releases

Packages

Contributors

Languages