Monday, 2 November 2026

AI Integrated Health Monitoring with Emergency Prediction

AI-Integrated Health Monitoring with Emergency Prediction

Complete IoT + ESP32 + Agentic AI + n8n Automation + Telegram Voice Alerts + Google Sheets + ThingSpeak Dashboard

Build a Multi-Sensor Health Analyzer With ESP32 (Temp + SpO2 + Heart Rate) : 9 Steps (with Pictures) - Instructables
Schematic of ESP32 based digital health monitoring system. | Download Scientific Diagram
HealthyPi v3 - Taking Health Data to the Cloud: How and Why | Crowd Supply

This project is an AI-powered smart healthcare monitoring and emergency alert system that continuously monitors a person's vital health parameters using an ESP32 microcontroller, sends real-time sensor information to the cloud, uses AI to interpret abnormal readings, and automatically sends emergency notifications through Telegram, including voice alerts.

The system also stores patient readings in Google Sheets, displays live health graphs through ThingSpeak, and uses n8n automation to coordinate the entire workflow.

Below is a complete project-documentation blueprint covering the abstract, objectives, hardware, software, block diagrams, circuit connections, working principle, AI agent, automation workflows, source code, dashboard, testing, and future enhancements.

IoT + AI + Agentic Automation ESP32 n8n + Telegram

1. Project overview

Project title:

AI-Integrated Health Monitoring and Emergency Prediction Using ESP32, Agentic AI, n8n Automation, Telegram Voice Alerts, Google Sheets and ThingSpeak.

What does this project do?

The proposed system monitors health parameters using sensors connected to an ESP32.

It can monitor:

  • Heart rate (BPM).

  • Blood oxygen saturation (SpO₂).

  • Body/contact temperature, using a suitable temperature sensor.

  • Optional ECG waveform using an AD8232 module.

  • Optional motion and fall detection using an MPU6050.

The ESP32 sends the collected data to a cloud-based automation system.

The AI agent analyses the readings, determines whether they are within configured monitoring limits, identifies concerning trends, and initiates an alert workflow when necessary.

Main features

Feature

Technology

Health data collection

ESP32

Heart rate

MAX30102

Oxygen saturation

MAX30102

Temperature

DS18B20 or suitable medical-grade sensor

ECG (optional)

AD8232

Wireless connectivity

Wi-Fi

Automation

n8n

AI interpretation

AI API/agent

Emergency notifications

Telegram Bot

Voice notifications

Text-to-speech + Telegram

Data storage

Google Sheets

Cloud monitoring

ThingSpeak

Web interface

HTML, CSS, JavaScript

Historical analysis

Google Sheets / ThingSpeak

2. System architecture

Overall system flow

text
       PATIENT / USER
             |
             v
    HEALTH MONITORING SENSORS
    -------------------------
    MAX30102 - Heart Rate
    MAX30102 - SpO2
    Temperature Sensor
    AD8232 - Optional ECG
    MPU6050 - Optional Motion
             |
             v
          ESP32
    -----------------
    Sensor Processing
    Data Validation
    WiFi Connectivity
             |
             v
        CLOUD SERVER
        ThingSpeak
             |
             v
       n8n AUTOMATION
    ---------------------
    Receive Sensor Data
    Validate Parameters
    Check Emergency Rules
    Analyze Health Trends
             |
             v
         AI AGENT
    ---------------------
    Interpret Readings
    Identify Abnormal Trends
    Generate Explanation
    Recommend Alert Priority
             |
             v
       n8n DECISION ENGINE
          /       \
         /         \
     NORMAL       ABNORMAL
       |              |
       v              v
  Google Sheets   Telegram Alert
  ThingSpeak      Voice Message
  Web Dashboard   Emergency Contact

Important design principle: The AI agent should not be the only emergency detector. Critical alert rules should operate independently in n8n or the ESP32, so that an AI service outage cannot prevent an alert. The prototype is for monitoring and educational use, not medical diagnosis or a replacement for emergency services.

3. Hardware components required

ESP32 WiFi Bluetooth Geliştirme Kartı CP2102 Driver DevKit V1 30 Pin Mikrodenetleyici Fiyatı | Reyonex
MAX30102 Heart Rate Oxygen Pulse Sensor
Binghe Ad8232 Ecg Module Kit Ecg Measuring Pulse Heart Rate | Desertcart INDIA

No.

Component

Quantity

Purpose

1

ESP32 DevKit V1

1

Main controller

2

MAX30102

1

Heart rate and SpO₂

3

DS18B20

1

Contact temperature measurement

4

OLED 0.96-inch I2C

1

Display readings

5

AD8232

Optional

ECG waveform

6

MPU6050

Optional

Motion/fall detection

7

Breadboard

1

Circuit assembly

8

Jumper wires

As required

Connections

9

USB cable

1

Programming and power

10

4.7 kΩ resistor

1

DS18B20 data pull-up

11

Battery and regulated supply

Optional

Portable operation

Recommended initial prototype: ESP32 + MAX30102 + OLED. Add the temperature sensor after confirming the first two sensors work.

The MAX30102 is not a clinical diagnostic instrument. Readings can be affected by movement, sensor placement, skin perfusion, and other factors. Do not use prototype thresholds to make treatment decisions.

4. Circuit diagram and ESP32 connections

Pin connection table

Sensor/module

Pin

ESP32

MAX30102

VIN

3.3V, subject to breakout specifications

MAX30102

GND

GND

MAX30102

SDA

GPIO 21

MAX30102

SCL

GPIO 22

OLED

VCC

3.3V

OLED

GND

GND

OLED

SDA

GPIO 21

OLED

SCL

GPIO 22

DS18B20

VDD

3.3V

DS18B20

GND

GND

DS18B20

DATA

GPIO 4

For the DS18B20, connect a 4.7 kΩ pull-up resistor between DATA and 3.3V.

The OLED and MAX30102 can share the same I²C bus if their addresses do not conflict.

Electrical precautions:

  • Check the voltage requirements of each breakout board.

  • Do not connect a 5V signal directly to an ESP32 GPIO.

  • Use a properly regulated power supply.

  • Do not attach an unisolated prototype ECG circuit to a person while the ESP32 is connected to mains-powered equipment or a computer. Use appropriate medical electrical isolation and safety review for any human-connected ECG implementation.

5. Software requirements and installation

Required software

Software

Purpose

Arduino IDE 2.x

ESP32 programming

ESP32 board package

Microcontroller support

MAX3010x library

Sensor communication

OneWire

Temperature sensor

DallasTemperature

Temperature readings

n8n

Workflow automation

Telegram

Notifications

Google Sheets

Data logging

ThingSpeak

Cloud dashboard

AI API

Health-data interpretation

HTML/CSS/JavaScript

Web dashboard

Arduino IDE installation

  1. Download and install Arduino IDE.

  2. Open Preferences.

  3. Add the Espressif ESP32 board manager URL.

  4. Open Boards Manager.

  5. Search for esp32.

  6. Install the ESP32 board package.

  7. Select ESP32 Dev Module.

  8. Select the correct COM port.

Official installation documentation: ESP32 Arduino installation guide .

Install Arduino libraries

Open Library Manager and install:

  • SparkFun MAX3010x Pulse and Proximity Sensor Library.

  • OneWire.

  • DallasTemperature.

The MAX3010x library provides example code for collecting red and infrared sensor data and calculating heart rate and SpO₂.

6. ESP32 software program

The following is the main prototype firmware. It collects MAX30102 readings using the Maxim calculation algorithm, reads DS18B20 temperature, and sends a JSON data packet to n8n through a webhook.

Before uploading:

  • Use the SparkFun MAX3010x library.

  • Obtain spo2_algorithm.h from the library's Maxim heart-rate/SpO₂ example.

  • Configure your Wi-Fi and webhook URL.

  • The sensor must be correctly positioned and producing valid readings.

cpp

#include <WiFi.h>
#include <HTTPClient.h>
#include <Wire.h>
#include <MAX30105.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include "spo2_algorithm.h"

// -------- WiFi Configuration --------
const char* WIFI_SSID = "YOUR_WIFI";
const char* WIFI_PASSWORD = "YOUR_PASSWORD";

// n8n production webhook
const char* WEBHOOK_URL =
  "https://YOUR_N8N_DOMAIN/webhook/health-data";

// -------- Sensor Configuration --------
#define TEMP_PIN 4

MAX30105 particleSensor;

OneWire oneWire(TEMP_PIN);
DallasTemperature tempSensor(&oneWire);

// Maxim algorithm buffers
#define BUFFER_SIZE 100

uint32_t irBuffer[BUFFER_SIZE];
uint32_t redBuffer[BUFFER_SIZE];

int32_t spo2;
int8_t validSPO2;

int32_t heartRate;
int8_t validHeartRate;

void connectWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASSWORD);

  Serial.print("Connecting to WiFi");

  unsigned long start = millis();

  while (WiFi.status() != WL_CONNECTED &&
         millis() - start < 20000) {
    delay(500);
    Serial.print(".");
  }

  Serial.println();

  if (WiFi.status() == WL_CONNECTED) {
    Serial.println("WiFi connected");
  } else {
    Serial.println("WiFi connection failed");
  }
}

bool initializeSensors() {

  Wire.begin(21, 22);

  if (!particleSensor.begin(Wire, I2C_SPEED_FAST)) {
    Serial.println("MAX30102 not detected");
    return false;
  }

  particleSensor.setup(
    60,     // LED brightness
    4,      // Sample averaging
    2,      // Red + IR
    100,    // Sample rate
    411,    // Pulse width
    4096    // ADC range
  );

  tempSensor.begin();

  return true;
}

bool readHealthData() {

  for (int i = 0; i < BUFFER_SIZE; i++) {

    while (!particleSensor.available()) {
      particleSensor.check();
      delay(1);
    }

    redBuffer[i] = particleSensor.getRed();
    irBuffer[i] = particleSensor.getIR();

    particleSensor.nextSample();
  }

  maxim_heart_rate_and_oxygen_saturation(
    irBuffer,
    BUFFER_SIZE,
    redBuffer,
    &spo2,
    &validSPO2,
    &heartRate,
    &validHeartRate
  );

  return validSPO2 && validHeartRate &&
         spo2 > 0 && heartRate > 0;
}

void sendToN8N(
  float temperature,
  int bpm,
  int oxygen
) {

  if (WiFi.status() != WL_CONNECTED) {
    connectWiFi();
  }

  if (WiFi.status() != WL_CONNECTED) {
    Serial.println("No network. Data not transmitted.");
    return;
  }

  HTTPClient http;

  http.begin(WEBHOOK_URL);
  http.addHeader("Content-Type", "application/json");

  String json = "{";

  json += "\"device_id\":\"ESP32_HEALTH_01\",";
  json += "\"temperature\":" + String(temperature, 2) + ",";
  json += "\"heart_rate\":" + String(bpm) + ",";
  json += "\"spo2\":" + String(oxygen) + ",";
  json += "\"timestamp_ms\":" + String(millis());

  json += "}";

  int response = http.POST(json);

  Serial.print("HTTP response: ");
  Serial.println(response);

  http.end();
}

void setup() {

  Serial.begin(115200);

  connectWiFi();

  if (!initializeSensors()) {
    Serial.println("Sensor initialization failed");
  }

  Serial.println("Health monitoring started");
}

void loop() {

  if (WiFi.status() != WL_CONNECTED) {
    connectWiFi();
  }

  if (readHealthData()) {

    tempSensor.requestTemperatures();

    float temperature =
      tempSensor.getTempCByIndex(0);

    Serial.println("-------------------");

    Serial.print("Heart Rate: ");
    Serial.println(heartRate);

    Serial.print("SpO2: ");
    Serial.println(spo2);

    Serial.print("Temperature: ");
    Serial.println(temperature);

    // Basic sensor validity checks
    bool temperatureValid =
      temperature != DEVICE_DISCONNECTED_C &&
      temperature > -20 && temperature < 80;

    if (temperatureValid) {
      sendToN8N(
        temperature,
        heartRate,
        spo2
      );
    }

  } else {

    Serial.println("Invalid sensor reading");
  }

  delay(15000);
}

Important implementation notes:

  • The algorithm requires a correctly filled sample buffer. The code uses 100 samples per calculation window.

  • The values must pass validity checks before transmission.

  • Add finger-presence detection and signal-quality checks before treating a reading as usable.

  • The sample program is a development starting point, not validated medical monitoring firmware.

  • For a production device, use a non-blocking acquisition loop, a timestamp synchronized with NTP, HTTPS certificate verification, a device authentication token, and a persistent offline queue.

7. n8n automation workflow

n8n acts as the central automation engine.

It receives sensor data from the ESP32, evaluates it, logs it, sends alerts, and coordinates the AI agent.

Official references:

Workflow 1: Receive health sensor data

Create a new workflow.

Add these nodes in sequence:

1. Webhook Node

POST /health-data

2. Code Node

Validate JSON and calculate status

3. Google Sheets Node

Append sensor readings

4. ThingSpeak HTTP Request

Upload readings to cloud fields

5. IF Node

Normal / Warning / Critical / Invalid

Normal

Log and continue monitoring

Alert

AI analysis + Telegram alert

Step 1: Configure the Webhook

In n8n:

  1. Create a workflow.

  2. Add Webhook.

  3. Select HTTP Method: POST.

  4. Set Path: health-data.

  5. Set response mode to respond immediately.

  6. Copy the test webhook URL.

  7. Paste it into the ESP32 firmware.

  8. Click Listen for Test Event.

  9. Upload the firmware and check whether JSON arrives.

After testing, activate/publish the workflow and replace the test URL with the production URL.

n8n has separate test and production webhook URLs.

GitHub
+1

 

Step 2: Add Code Node

This node validates the incoming values and calculates a demonstration alert state.

javascript

const d = $json.body ?? $json;

const hr = Number(d.heart_rate);
const oxygen = Number(d.spo2);
const temp = Number(d.temperature);

const valid =
  Number.isFinite(hr) &&
  Number.isFinite(oxygen) &&
  Number.isFinite(temp) &&
  hr > 0 &&
  hr < 250 &&
  oxygen >= 0 &&
  oxygen <= 100 &&
  temp > -20 &&
  temp < 80;

if (!valid) {
  return [{
    json: {
      ...d,
      status: "INVALID_READING",
      alert: false,
      reason: "Invalid or missing sensor data"
    }
  }];
}

// Illustrative screening rules only.
// Replace with clinician-reviewed limits
// appropriate to the intended population.

const critical =
  hr < 40 ||
  hr > 150 ||
  oxygen < 90 ||
  temp >= 39.0;

const warning =
  hr < 50 ||
  hr > 120 ||
  oxygen < 94 ||
  temp >= 38.0;

let status = "NORMAL";

if (critical) {
  status = "CRITICAL";
} else if (warning) {
  status = "WARNING";
}

return [{
  json: {
    ...d,
    status,
    alert: status !== "NORMAL",
    timestamp: new Date().toISOString()
  }
}];

These thresholds are illustrative software-testing values, not universal clinical thresholds. A real monitoring deployment needs population-specific, clinician-approved thresholds and a defined escalation protocol.

Step 3: Google Sheets integration

Create a Google spreadsheet named:

AI Health Monitoring Database

Create the following columns:

Column

Description

Timestamp

Date and time

Device_ID

ESP32 identifier

Heart_Rate

BPM

SpO2

Oxygen percentage

Temperature

Celsius

Status

Normal/warning/critical

Alert

True/False

AI_Analysis

AI-generated explanation

Alert_Sent

Notification status

In n8n:

  1. Add Google Sheets node.

  2. Authenticate your Google account.

  3. Select the spreadsheet.

  4. Select the sheet.

  5. Choose Append Row.

  6. Map the incoming JSON fields to spreadsheet columns.

Step 4: ThingSpeak cloud integration

Create a ThingSpeak account and a new channel.

Create these fields:

ThingSpeak field

Data

Field 1

Heart rate

Field 2

SpO₂

Field 3

Temperature

Field 4

Alert status

The n8n HTTP Request node sends the data to:

text
https://api.thingspeak.com/update

Use POST with form-urlencoded parameters:

text
api_key=YOUR_WRITE_API_KEY
field1={{ $json.heart_rate }}
field2={{ $json.spo2 }}
field3={{ $json.temperature }}
field4={{ $json.status }}

Use your actual channel write key, and keep it private.

ThingSpeak provides REST APIs for writing and reading channel data.

MATLAB & Simulink

 

8. AI Agent implementation – Agentic IoT

This is the intelligent part of the project.

A conventional IoT system simply collects sensor readings and sends alerts when a threshold is crossed.

An agentic IoT system adds an AI reasoning and action layer. It can:

  1. Receive health readings.

  2. Examine the current values.

  3. Compare them with historical readings.

  4. Identify repeated abnormal readings.

  5. Generate a human-readable explanation.

  6. Assign an alert priority.

  7. Trigger approved automation tools.

  8. Record its analysis and actions.

AI Agent architecture

text
       ESP32 SENSOR DATA
               |
               v
        n8n WEBHOOK
               |
               v
        DATA VALIDATION
               |
               v
        RULE-BASED ENGINE
               |
               v
           AI AGENT
               |
       +-------+-------+
       |       |       |
       v       v       v
    Current History  Trends
    Values   Data    Analysis
       |       |       |
       +-------+-------+
               |
               v
       AI INTERPRETATION
               |
               v
       ALERT CLASSIFICATION
               |
       +-------+-------+
       |               |
       v               v
   NORMAL          ABNORMAL
       |               |
       v               v
  Save Data       Trigger Alerts

AI Agent prompt

In n8n, add an AI Agent node and connect your chosen language model.

Use the following system instructions:

text

You are an AI-assisted IoT health monitoring
analysis agent.

Your job is to analyze sensor readings received
from an ESP32 health monitoring device.

Input parameters:
- Heart rate (BPM)
- SpO2 (%)
- Temperature (Celsius)
- Device ID
- Previous readings, if available
- Rule-based alert status

Responsibilities:

1. Check whether the incoming readings are valid.
2. Explain abnormal readings in simple language.
3. Compare current and historical readings.
4. Identify repeated unusual patterns.
5. Return an alert priority.
6. Recommend that the user seek appropriate
   professional assessment when necessary.
7. Generate a short Telegram notification.

Output valid JSON only:

{
  "priority": "NORMAL",
  "summary": "Reading analysis",
  "observation": "Observed sensor pattern",
  "recommendation": "Appropriate next step",
  "telegram_message": "Notification text"
}

Rules:

- Never diagnose a disease.
- Never claim to predict a heart attack.
- Never recommend medication or treatment.
- Never override a critical rule-based alert.
- Invalid readings must be identified as invalid.
- Sensor failure must not be interpreted as
  evidence that the patient is healthy.
- If a critical rule is triggered, preserve the
  critical alert priority.
- State that sensor readings are not a
  substitute for clinical assessment.

Example AI Agent output

For demonstration purposes:

json
{
  "priority": "WARNING",
  "summary": "An unusual oxygen reading was detected.",
  "observation": "The latest SpO2 reading is 92%.",
  "recommendation": "Check sensor placement and repeat the measurement. Seek prompt medical assessment if the reading remains low or symptoms are present.",
  "telegram_message": "Health monitoring warning: An unusual oxygen reading has been detected. Please check the sensor and take appropriate action."
}

The AI agent provides an explanation. The deterministic emergency rules remain responsible for immediate alert triggering.

9. Telegram emergency notification system

Canali simili, ripubblicazione delle storie e altre 9 funzioni
File:Telegram voice messages.png - Wikimedia Commons
Monitoring and alerting systemd processes running on multiple servers with Prometheus, Node Exporter, and Alert Manager | by adarsh.dhir | Medium

Telegram provides a convenient way to notify a patient, caregiver, or authorized emergency contact.

Step 1: Create a Telegram bot

  1. Open Telegram.

  2. Search for @BotFather.

  3. Start a conversation.

  4. Send /newbot.

  5. Enter a bot name.

  6. Enter a username.

  7. Copy the bot token.

  8. Open your newly created bot.

  9. Press Start.

  10. Obtain your chat ID using the Telegram bot API or an n8n Telegram Trigger.

Never publish your bot token or expose it in the ESP32 firmware.

Step 2: Connect Telegram to n8n

  1. Add Telegram credentials.

  2. Enter the bot token.

  3. Add a Telegram Send Message node.

  4. Select the authorized recipient's chat ID.

  5. Set the message using the AI output.

Example alert:

Health Monitoring Bot

Warning

Health Monitoring Notification

Device: ESP32_HEALTH_01

Heart Rate: 125 BPM

SpO₂: 92%

Temperature: 37.2°C

Status: WARNING

AI observation: An unusual oxygen reading has been detected.

Action: Verify the sensor reading and seek appropriate medical assessment if it remains abnormal.

Illustrative notification, not a real patient reading.

Step 3: Telegram voice alert

This is one of the main features of your project.

The voice notification system converts the alert text into an audio file using a text-to-speech service.

Voice alert architecture:

text
       n8n AI AGENT
             |
             v
      Alert Message
             |
             v
       TTS SERVICE
    Text-to-Speech API
             |
             v
        AUDIO FILE
         MP3/OGG
             |
             v
      TELEGRAM BOT
             |
             v
      CAREGIVER PHONE
             |
             v
       VOICE ALERT

How to implement voice alerts in n8n

Create this additional workflow branch:

  1. IF node – check whether status is WARNING or CRITICAL.

  2. Set node – prepare a short voice message.

  3. HTTP Request – send text to a text-to-speech service.

  4. Receive the generated audio file.

  5. Telegram node – use Send Audio to send an MP3 file, or Send Voice with a compatible voice-note file.

  6. Google Sheets – record the alert delivery attempt.

Example text for the voice generator:

text

Emergency health monitoring notification.

An unusual health reading has been detected.

Please check the patient and verify the sensor
readings.

If the patient has severe symptoms or needs
urgent assistance, contact emergency services
immediately.

For a real emergency workflow, do not wait for AI text generation or audio conversion before sending the initial critical text alert. Send the text alert immediately, then deliver the voice message as an additional notification.

10. Complete n8n workflow – normal and emergency branches

The final workflow should look like this:

text
                  ESP32
                    |
                    v
                 WEBHOOK
                    |
                    v
              VALIDATE DATA
                    |
                    v
             CALCULATE STATUS
                    |
           +--------+--------+
           |                 |
           v                 v
       GOOGLE SHEETS     THINGSPEAK
           |                 |
           +--------+--------+
                    |
                    v
                IF NODE
                    |
            +-------+-------+
            |               |
            v               v
          NORMAL          WARNING/
                            CRITICAL
            |               |
            v               v
       Save Reading       AI AGENT
                            |
                            v
                       ALERT TEXT
                            |
                  +---------+---------+
                  |                   |
                  v                   v
             TELEGRAM TEXT        TTS API
                                      |
                                      v
                                 AUDIO FILE
                                      |
                                      v
                                TELEGRAM AUDIO
                                      |
                                      v
                                GOOGLE SHEETS
                                 ALERT LOG

Recommended additional automation

  • Send a notification if the ESP32 stops reporting.

  • Send an alert if the sensor produces invalid readings repeatedly.

  • Avoid sending duplicate alerts every 15 seconds.

  • Escalate an unacknowledged critical alert to another authorized contact.

  • Provide an acknowledgement mechanism for caregivers.

  • Maintain a separate device-connectivity status.

11. Web-based health monitoring dashboard

The webpage provides a central location to view health readings and their historical trends.

Dashboard features

  • Live heart rate.

  • Live SpO₂.

  • Temperature.

  • Current monitoring status.

  • Heart rate graph.

  • SpO₂ graph.

  • Temperature graph.

  • Latest notification.

  • Device online/offline status.

  • ThingSpeak cloud charts.

Dashboard design

text
+-------------------------------------------+
|      AI HEALTH MONITORING SYSTEM          |
+-------------------------------------------+
| Device: ESP32_HEALTH_01    Status: ONLINE |
+------------------+------------------------+
| Heart Rate       | SpO2                   |
|  78 BPM          | 98%                    |
+------------------+------------------------+
| Temperature      | Health Status          |
|  36.8 C          | NORMAL                 |
+-------------------------------------------+
|                                           |
|       HEART RATE HISTORY GRAPH            |
|                                           |
+-------------------------------------------+
|                                           |
|       SPO2 HISTORY GRAPH                  |
|                                           |
+-------------------------------------------+
|                                           |
|       TEMPERATURE HISTORY GRAPH           |
|                                           |
+-------------------------------------------+
| Latest Alert: No active alert             |
+-------------------------------------------+

Sample HTML webpage

This is a starter dashboard that uses ThingSpeak's embedded charts. Replace the channel ID and field numbers with your own.

HTML
Wrap linesCopy codePreview

<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport"
content="width=device-width, initial-scale=1.0">

<title>AI Health Monitoring</title>

<style>
* {
  box-sizing: border-box;
}

body {
  margin: 0;
  padding: 20px;
  font-family: Arial, sans-serif;
  background: #eef3f8;
  color: #172b4d;
}

header {
  background: #123b65;
  color: white;
  padding: 22px;
  text-align: center;
  border-radius: 12px;
}

.container {
  max-width: 1100px;
  margin: auto;
}

.cards {
  display: grid;
  grid-template-columns:
    repeat(auto-fit, minmax(210px, 1fr));
  gap: 15px;
  margin: 20px 0;
}

.card {
  background: white;
  padding: 22px;
  border-radius: 12px;
  box-shadow: 0 3px 12px #0001;
}

.value {
  font-size: 30px;
  font-weight: bold;
  color: #0878c9;
}

.chart {
  background: white;
  margin: 18px 0;
  padding: 15px;
  border-radius: 12px;
}

iframe {
  width: 100%;
  height: 260px;
  border: none;
}

.status {
  padding: 12px;
  background: #e4f6eb;
  border-radius: 8px;
  color: #14743c;
}

footer {
  text-align: center;
  padding: 20px;
  color: #667;
}
</style>
</head>

<body>

<div class="container">

<header>
<h1>AI Health Monitoring System</h1>
<p>ESP32 | IoT | AI | n8n Automation</p>
</header>

<div class="cards">

<div class="card">
<h3>Heart Rate</h3>
<div class="value" id="hr">-- BPM</div>
</div>

<div class="card">
<h3>SpO2</h3>
<div class="value" id="spo2">-- %</div>
</div>

<div class="card">
<h3>Temperature</h3>
<div class="value" id="temp">-- °C</div>
</div>

<div class="card">
<h3>Monitoring Status</h3>
<div class="status" id="status">
Waiting for data
</div>
</div>

</div>

<div class="chart">
<h3>Heart Rate History</h3>
<iframe
src="https://thingspeak.com/channels/YOUR_CHANNEL_ID/charts/1?bgcolor=%23ffffff&color=%230078c8&dynamic=true&results=30">
</iframe>
</div>

<div class="chart">
<h3>SpO2 History</h3>
<iframe
src="https://thingspeak.com/channels/YOUR_CHANNEL_ID/charts/2?bgcolor=%23ffffff&color=%2300a878&dynamic=true&results=30">
</iframe>
</div>

<div class="chart">
<h3>Temperature History</h3>
<iframe
src="https://thingspeak.com/channels/YOUR_CHANNEL_ID/charts/3?bgcolor=%23ffffff&color=%23e68a00&dynamic=true&results=30">
</iframe>
</div>

<footer>
AI Integrated Health Monitoring and
Emergency Alert System
</footer>

</div>

<script>

// Configure a public channel for this demo.
// Never expose private channel credentials here.

const CHANNEL_ID = "YOUR_CHANNEL_ID";

async function updateDashboard() {

  try {

    const url =
      `https://api.thingspeak.com/channels/${CHANNEL_ID}/feeds/last.json`;

    const response = await fetch(url);

    if (!response.ok) {
      throw new Error("Cloud data unavailable");
    }

    const data = await response.json();

    document.getElementById("hr").textContent =
      (data.field1 ?? "--") + " BPM";

    document.getElementById("spo2").textContent =
      (data.field2 ?? "--") + " %";

    document.getElementById("temp").textContent =
      (data.field3 ?? "--") + " °C";

    document.getElementById("status").textContent =
      "Latest cloud reading received";

  } catch(error) {

    document.getElementById("status").textContent =
      "Data unavailable - check connection";

  }
}

updateDashboard();
setInterval(updateDashboard, 20000);

</script>

</body>
</html>

Save this file as index.html and open it in a browser.

For a real deployment, the webpage should also show the timestamp and data freshness. A failed cloud connection must display UNKNOWN/OFFLINE, not NORMAL.

12. Emergency prediction and trend analysis

The emergency prediction module is designed to identify unusual readings and changes over time.

It is important to distinguish between:

  • Abnormal-reading detection: Detects a reading outside configured limits.

  • Trend detection: Detects repeated changes or unusual patterns over time.

  • Medical prediction: Predicts a future medical event. This requires validated clinical data and a clinically evaluated model; simple threshold rules or an LLM cannot establish this capability.

Example trend-analysis logic

text
Collect last 10 valid readings
           |
           v
Calculate average values
           |
           v
Compare latest reading
with previous readings
           |
           v
Detect repeated abnormal values
           |
           v
Generate trend observation
           |
           v
Store result in Google Sheets
           |
           v
Notify authorized caregiver

For example:

Reading

SpO₂

Reading 1

98%

Reading 2

97%

Reading 3

96%

Reading 4

94%

Reading 5

92%

This illustrates a downward trend. It should trigger signal verification and an appropriate monitoring response, not an AI claim that a particular emergency will occur.

13. Project testing and expected results

Test each module independently before connecting the complete system.

Test

Expected result

ESP32 startup

Connects to Wi-Fi

MAX30102

Detects sensor and obtains valid samples

Temperature sensor

Produces a valid temperature

Webhook

Receives JSON

Code node

Validates data

Google Sheets

Adds a new row

ThingSpeak

Updates channel

AI agent

Generates structured interpretation

Telegram

Sends text notification

TTS

Generates audio

Telegram audio

Delivers audio file

Web dashboard

Displays cloud readings

Sample demonstration scenarios

These are software test cases, not recommended clinical alarm settings.

Scenario

Simulated input

Expected workflow

1

Normal readings

Store data

2

Elevated heart rate

Warning evaluation

3

Low SpO₂

Alert evaluation

4

High temperature

Warning evaluation

5

Invalid sensor data

Mark invalid

6

Wi-Fi disconnected

Mark device offline

7

Repeated abnormal readings

Trend analysis

8

Critical rule triggered

Immediate text alert

14. Security and reliability

Because this system handles sensitive health-related information, implement the following:

  1. Use HTTPS for communication between ESP32 and n8n.

  2. Authenticate each ESP32 device.

  3. Store API credentials in n8n credentials, not public code.

  4. Restrict access to Google Sheets.

  5. Avoid publishing patient-identifiable information.

  6. Use private ThingSpeak channels when appropriate.

  7. Add a watchdog and network reconnection mechanism.

  8. Store failed transmissions locally and retry.

  9. Prevent duplicate Telegram alerts.

  10. Monitor the n8n workflow for failures.

  11. Keep an audit trail of alerts and acknowledgements.

  12. Use explicit consent and an appropriate data-retention policy.

Emergency reliability: A network failure, dead battery, disconnected sensor, or failed AI API must never silently appear as a healthy reading. Add a separate device-health monitoring and communication-failure alert.

15. Suggested project development schedule

  1. Day 1 – Hardware setup

    Connect ESP32, MAX30102, and OLED. Test I²C communication.

  2. Day 2 – Sensor programming

    Implement heart-rate, SpO₂, and temperature acquisition.

  3. Day 3 – IoT cloud integration

    Connect Wi-Fi, n8n webhook, and ThingSpeak.

  4. Day 4 – Google Sheets

    Configure authentication and automatic logging.

  5. Day 5 – AI Agent

    Integrate AI analysis, validation, and trend detection.

  6. Day 6 – Telegram automation

    Configure text alerts, TTS, and audio delivery.

  7. Day 7 – Web dashboard

    Build the webpage and integrate cloud charts.

  8. Day 8 – System testing

    Test normal readings, simulated abnormal readings, sensor failures, and network outages.

16. Advantages of the project

  • Continuous remote health-data monitoring.

  • Wireless sensor connectivity.

  • Cloud-based data storage.

  • Automatic health-data logging.

  • AI-assisted interpretation.

  • Historical trend monitoring.

  • Telegram text and voice notifications.

  • Remote caregiver awareness.

  • Modular and expandable architecture.

  • Reduced need for manual data entry.

17. Future enhancements

The project can be extended with:

  • Mobile application using Flutter.

  • Patient and caregiver login.

  • Multiple-patient monitoring.

  • Fall detection using MPU6050.

  • ECG waveform analysis.

  • Battery monitoring.

  • GPS-based location sharing with consent.

  • Offline emergency SMS using a cellular module.

  • Advanced anomaly-detection models.

  • Clinically validated prediction models.

  • Secure hospital dashboard integration.

  • Voice interaction with an AI healthcare assistant.

18. Final project abstract

The following abstract can be used in your academic project report.

Writing
 

AI-Integrated Health Monitoring with Emergency Prediction Using ESP32, Agentic AI and n8n Automation

Abstract

The proposed project presents an Internet of Things (IoT)-based intelligent health monitoring system that integrates ESP32, biomedical sensors, Artificial Intelligence, cloud computing, and workflow automation to support continuous remote monitoring of health-related parameters.

The system uses an ESP32 microcontroller connected to a MAX30102 pulse oximeter sensor for measuring heart rate and peripheral oxygen saturation (SpO₂), along with a temperature sensor for monitoring temperature. Additional sensors, such as AD8232 ECG and MPU6050 motion sensors, can be incorporated to extend the monitoring capabilities.

The collected sensor information is transmitted through Wi-Fi to an n8n automation platform using an HTTP webhook. The automation workflow validates the incoming information, stores the readings in Google Sheets, and uploads the measurements to ThingSpeak for cloud-based visualization.

An AI agent is integrated into the automation workflow to interpret sensor readings, examine historical trends, generate understandable observations, and assist in classifying monitoring alerts. A separate rule-based emergency detection mechanism ensures that critical configured conditions can trigger notifications without depending on the availability of the AI service.

When an abnormal or critical monitoring condition is detected, the system automatically generates Telegram notifications. A text-to-speech service converts the alert message into audio, which is delivered to authorized caregivers through Telegram.

A web-based dashboard provides access to health measurements, monitoring status, and historical graphs. The proposed system demonstrates the integration of embedded electronics, IoT communication, cloud storage, AI-assisted analysis, and agentic automation in an extensible remote health-monitoring prototype.

The system is intended for educational and research purposes and requires clinical validation before any medical deployment.

19. Final project architecture – technology summary

Complete technology stack

Probots ESP32 38-Pin Dev Board | Type-C & CP2102 Buy Online India

Hardware

ESP32, MAX30102, DS18B20, optional ECG and motion sensors

Cómo utilizar el panel de n8n – Ayuda HostGator

Automation

n8n webhooks, conditions, integrations, AI Agent

Part 3 - Patient Monitoring System using 96Boards - 96Boards

Cloud monitoring

ThingSpeak, Google Sheets

Solution EMS CX³ : comment recevoir les infos de l'énergie serveur web sur son smartphone avec Telegram ? - professionnel | Legrand

Notifications

Telegram text, TTS and audio notifications

End-to-end data flow

ESP32 + Biomedical Sensors

Wi-Fi + n8n Webhook

AI Analysis + Rule Engine

Google Sheets

ThingSpeak

Telegram

Web Dashboard + Caregiver Notifications

20. Technical references

These official resources will help with implementation:

  1. Espressif ESP32 Arduino documentation  – ESP32 setup and programming.

  2. n8n documentation  – Automation and AI workflow construction.

  3. n8n Webhook documentation  – ESP32-to-n8n communication.

  4. n8n Telegram documentation  – Telegram notification integration.

  5. n8n Google Sheets documentation  – Cloud spreadsheet integration.

  6. ThingSpeak REST API  – IoT cloud data transfer.

21. Let's build the complete working project

The documentation above provides the architecture and initial code. To turn it into a fully integrated, uploadable project, I recommend building it in modules so each part can be tested independently.

I need one important hardware detail before preparing the final complete source-code package:

Which ESP32 board are you using?

1. ESP32 board

2. Sensors available

Select all the sensors you have.

3. Dashboard requirement

Prepare my complete project source code

This will let me tailor the next implementation to your actual hardware rather than give you incompatible wiring or code.

 

AI-Integrated Health Monitoring with Emergency Prediction

This project builds an agentic IoT health-monitoring system using an ESP32, wearable/body sensors, ThingSpeak for cloud visualization, Google Sheets for records, n8n for automation, and Telegram for instant text + voice emergency alerts. The AI agent evaluates sensor trends, predicts risk, and decides whether to notify a caregiver. ThingSpeak supports HTTP/MQTT writes from devices, while n8n can receive Telegram messages and send Telegram messages/audio through its Telegram integration.[se.mathworks][docs.n8n][docs.n8n]

Project Overview

The ESP32 continuously reads patient vitals, publishes them to ThingSpeak and n8n, stores them in Google Sheets, and triggers an AI-based emergency-prediction workflow when readings are abnormal or deteriorating.

Core capabilities

  • Real-time monitoring of heart rate, SpO2, body temperature, and optional fall detection.
  • Cloud dashboard using ThingSpeak.
  • Historical patient log in Google Sheets.
  • AI agent for risk classification and emergency prediction.
  • Telegram text alerts and voice-note alerts to caregivers.
  • Two-way Telegram commands such as STATUS, HELP, and MUTE 30.
  • Local buzzer/OLED warning on the ESP32.

    Important: This is an educational/prototype system, not a certified medical device. Do not rely on it for clinical diagnosis or life-critical decisions without validated hardware, calibration, and medical approval.

System Architecture

Patient / Sensors
      |
      v
+------------------+
| ESP32 Controller |
| - MAX30102 HR/SpO2|
| - DS18B20 Temp    |
| - MPU6050 Fall    |
| - OLED + Buzzer   |
+---------+--------+
          | Wi-Fi HTTPS / HTTP
          v
+------------------+         +------------------+
|    ThingSpeak    |<------->| Cloud Dashboard  |
|  Channel Fields  |         | Charts / History |
+---------+--------+         +------------------+
          |
          | Webhook JSON
          v
+------------------+
|       n8n        |
| AI Agent Logic   |
| Risk Prediction  |
| Alert Deduping   |
+---+----------+---+
    |          |
    v          v
+--------+  +----------------+
| Google |  | Telegram Bot   |
| Sheets |  | Text + Voice   |
+--------+  +----------------+

The ESP32 sends data to ThingSpeak using its REST API; n8n can also be triggered by Telegram messages and can send Telegram messages or audio files.[se.mathworks][docs.n8n][docs.n8n]

Hardware Required

Component Purpose Notes
ESP32 DevKit V1 Main microcontroller and Wi-Fi Prefer a board with enough GPIO and stable 3.3 V regulation
MAX30102 Heart rate and SpO2 I2C, finger/ear sensor
DS18B20 Body temperature Waterproof probe recommended
MPU6050 Fall/abnormal movement detection Optional but useful
0.96" OLED SSD1306 Local display Optional
Buzzer Local emergency alarm Optional
Push button Manual SOS Strongly recommended
3.7 V Li-ion battery + TP4056 Portable power Add proper protection circuitry
Breadboard / PCB, wires, enclosure Assembly Use medical-grade-safe enclosure for wearable use

Pin Connections

Use 3.3 V logic only. Do not connect sensors directly to 5 V unless the module is explicitly 5 V tolerant.

ESP32 Pin Connected To
3V3 MAX30102 VIN, MPU6050 VCC, OLED VCC
GND Common ground
GPIO 21 I2C SDA: MAX30102, MPU6050, OLED
GPIO 22 I2C SCL: MAX30102, MPU6050, OLED
GPIO 4 DS18B20 data pin, with 4.7 kΩ pull-up to 3.3 V
GPIO 25 Buzzer positive
GPIO 26 SOS button input, other side to GND
GPIO 27 Optional alert LED

Simplified Schematic

                    ESP32 DevKit
                 +----------------+
                 |                |
   MAX30102 ---- | 3V3  GND       |
   SDA ----------| GPIO21         |
   SCL ----------| GPIO22         |
                 |                |
   MPU6050 ----- | 3V3  GND       |
   SDA ----------| GPIO21         |
   SCL ----------| GPIO22         |
                 |                |
   OLED -------- | 3V3  GND       |
   SDA ----------| GPIO21         |
   SCL ----------| GPIO22         |
                 |                |
   DS18B20 ----- | GPIO4          |
        |        |                |
        +--4.7k--| 3V3            |
                 |                |
   Buzzer + ---- | GPIO25         |
   Buzzer - ---- | GND            |
                 |                |
   SOS button -- | GPIO26         |
        |        |                |
        +--------| GND            |
                 +----------------+

All I2C devices share SDA/SCL because each has a different I2C address.

Software Flow

Start ESP32
   |
   v
Connect Wi-Fi
   |
   v
Initialize sensors, OLED, buzzer
   |
   v
Read HR, SpO2, temperature, motion
   |
   +--> Display locally
   |
   +--> Send JSON to n8n webhook
   |
   +--> Send data to ThingSpeak
   |
   v
n8n AI agent:
   - Validate data
   - Compare thresholds and trends
   - Estimate emergency risk
   - Log to Google Sheets
   |
   +--> Normal: no alert
   |
   +--> Warning: Telegram text
   |
   +--> Emergency: Telegram text + voice alert + buzzer command

Emergency Prediction Logic

Use a layered model rather than one fixed threshold.

Level Example condition System response
Normal HR 60–100 bpm, SpO2 ≥ 95%, temp 36.1–37.8°C Log only
Warning SpO2 92–94%, HR 101–120 or 50–59 bpm, temp 37.9–38.5°C Telegram warning
High Risk SpO2 88–91%, HR >120 or <50 bpm, temp >38.5°C Emergency alert
Critical / Predicted Abnormal values persist, multiple vitals degrade, fall detected, or SOS pressed Voice call-style Telegram voice alert, repeated notification, caregiver escalation

A simple AI agent can use rules plus a trend score. For example:

RiskScore = W_1H + W_2S + W_3T + W_4F + W_5D

Where:

  • H = heart-rate abnormality score
  • S = SpO2 abnormality score
  • T = temperature abnormality score
  • F = fall/SOS score
  • D = deterioration trend score
  • W_1...W_5 = weights

Example weights: 0.20, 0.30, 0.15, 0.25, 0.10.

Risk levels:

  • 0–0.34: NORMAL
  • 0.35–0.59: WARNING
  • 0.60–0.79: HIGH RISK
  • 0.80–1.00: EMERGENCY

ESP32 Arduino Code

Install these Arduino libraries:

  • WiFi.h
  • HTTPClient.h
  • ArduinoJson
  • Adafruit MAX3010x
  • OneWire
  • DallasTemperature
  • MPU6050 or Adafruit MPU6050
  • Adafruit SSD1306
  • Adafruit GFX
#include <WiFi.h>
#include <HTTPClient.h>
#include <ArduinoJson.h>
#include <Wire.h>
#include <Adafruit_MPU6050.h>
#include <Adafruit_Sensor.h>
#include <Adafruit_MAX30102.h>
#include <OneWire.h>
#include <DallasTemperature.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>

// ---------- Wi-Fi ----------
const char* WIFI_SSID = "YOUR_WIFI_NAME";
const char* WIFI_PASS = "YOUR_WIFI_PASSWORD";

// ---------- n8n ----------
const char* N8N_WEBHOOK = "https://YOUR-N8N-DOMAIN/webhook/health-data";

// ---------- ThingSpeak ----------
const char* THINGSPEAK_API_KEY = "YOUR_THINGSPEAK_WRITE_API_KEY";
const char* THINGSPEAK_HOST = "api.thingspeak.com";

// ---------- Pins ----------
#define ONE_WIRE_BUS 4
#define BUZZER_PIN 25
#define SOS_PIN 26
#define ALERT_LED 27

OneWire oneWire(ONE_WIRE_BUS);
DallasTemperature tempSensor(&oneWire);

Adafruit_MPU6050 mpu;
Adafruit_MAX30102 maxSensor;

#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);

unsigned long lastN8nSend = 0;
unsigned long lastThingSpeakSend = 0;
const unsigned long N8N_INTERVAL = 5000;       // 5 seconds
const unsigned long THINGSPEAK_INTERVAL = 15000; // 15 seconds

float heartRate = 0;
float spo2 = 0;
float bodyTemp = 0;
bool fallDetected = false;

void connectWiFi() {
  WiFi.begin(WIFI_SSID, WIFI_PASS);
  Serial.print("Connecting to Wi-Fi");
  while (WiFi.status() != WL_CONNECTED) {
    delay(500);
    Serial.print(".");
  }
  Serial.println("\nWi-Fi connected");
  Serial.println(WiFi.localIP());
}

void setup() {
  Serial.begin(115200);

  pinMode(BUZZER_PIN, OUTPUT);
  pinMode(ALERT_LED, OUTPUT);
  pinMode(SOS_PIN, INPUT_PULLUP);

  Wire.begin(21, 22);

  if (!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
    Serial.println("OLED not found");
  }
  display.clearDisplay();
  display.setTextColor(SSD1306_WHITE);
  display.setTextSize(1);
  display.setCursor(0, 0);
  display.println("Health Monitor");
  display.println("Starting...");
  display.display();

  tempSensor.begin();

  if (!mpu.begin()) {
    Serial.println("MPU6050 not found");
  }

  if (!maxSensor.begin()) {
    Serial.println("MAX30102 not found");
  }
  maxSensor.setup();

  connectWiFi();
}

void readSensors() {
  // Temperature
  tempSensor.requestTemperatures();
  bodyTemp = tempSensor.getTempCByIndex(0);

  // Heart rate and SpO2
  // For a production device, use a proven algorithm and longer sampling window.
  uint32_t irValue = maxSensor.getIR();
  if (irValue > 50000) {
    heartRate = random(68, 92);   // Replace with real HR algorithm/library output
    spo2 = random(95, 99);        // Replace with real SpO2 algorithm/library output
  } else {
    heartRate = 0;
    spo2 = 0;
  }

  // Fall detection
  sensors_event_t a, g, t;
  mpu.getEvent(&a, &g, &t);
  float totalAccel = sqrt(
    a.acceleration.x * a.acceleration.x +
    a.acceleration.y * a.acceleration.y +
    a.acceleration.z * a.acceleration.z
  );

  fallDetected = totalAccel > 25.0; // Tune this threshold carefully

  bool sosPressed = digitalRead(SOS_PIN) == LOW;
  if (sosPressed) {
    fallDetected = true;
  }
}

void displayData() {
  display.clearDisplay();
  display.setCursor(0, 0);
  display.println("AI Health Monitor");
  display.setCursor(0, 16);
  display.print("HR: ");
  display.print(heartRate, 0);
  display.println(" bpm");

  display.setCursor(0, 28);
  display.print("SpO2: ");
  display.print(spo2, 0);
  display.println(" %");

  display.setCursor(0, 40);
  display.print("Temp: ");
  display.print(bodyTemp, 1);
  display.println(" C");

  display.setCursor(0, 52);
  display.println(fallDetected ? "ALERT: FALL/SOS" : "Status: Monitoring");
  display.display();
}

void sendToN8n() {
  if (WiFi.status() != WL_CONNECTED) return;

  HTTPClient http;
  http.begin(N8N_WEBHOOK);
  http.addHeader("Content-Type", "application/json");

  StaticJsonDocument<512> doc;
  doc["deviceId"] = "ESP32-HEALTH-01";
  doc["patientName"] = "Patient A";
  doc["heartRate"] = heartRate;
  doc["spo2"] = spo2;
  doc["temperature"] = bodyTemp;
  doc["fallDetected"] = fallDetected;
  doc["timestamp"] = millis();

  String payload;
  serializeJson(doc, payload);

  int code = http.POST(payload);
  Serial.print("n8n response: ");
  Serial.println(code);
  http.end();
}

void sendToThingSpeak() {
  if (WiFi.status() != WL_CONNECTED) return;

  HTTPClient http;
  String url = "http://" + String(THINGSPEAK_HOST) + "/update?api_key=" +
               String(THINGSPEAK_API_KEY) +
               "&field1=" + String(heartRate) +
               "&field2=" + String(spo2) +
               "&field3=" + String(bodyTemp) +
               "&field4=" + String(fallDetected ? 1 : 0);

  http.begin(url);
  int code = http.GET();
  Serial.print("ThingSpeak response: ");
  Serial.println(code);
  http.end();
}

void loop() {
  readSensors();
  displayData();

  unsigned long now = millis();

  if (now - lastN8nSend >= N8N_INTERVAL) {
    lastN8nSend = now;
    sendToN8n();
  }

  if (now - lastThingSpeakSend >= THINGSPEAK_INTERVAL) {
    lastThingSpeakSend = now;
    sendToThingSpeak();
  }

  if (fallDetected) {
    digitalWrite(BUZZER_PIN, HIGH);
    digitalWrite(ALERT_LED, HIGH);
  } else {
    digitalWrite(BUZZER_PIN, LOW);
    digitalWrite(ALERT_LED, LOW);
  }

  delay(500);
}

The random() values for heart rate and SpO2 are placeholders. For real deployment, replace them with a validated pulse-oximetry algorithm or a library that calculates HR/SpO2 from the MAX30102 red and IR waveform data.

n8n Workflow

Workflow 1: Health Data and Emergency Prediction

Webhook: /health-data
   |
   v
Function / Code Node: Validate and calculate risk
   |
   +--> IF Risk >= 0.80
   |       |
   |       +--> Google Sheets: Append emergency log
   |       |
   |       +--> Telegram: Send emergency text
   |       |
   |       +--> HTTP Request: Generate voice MP3
   |       |
   |       +--> Telegram: Send Audio / Voice Note
   |
   +--> IF Risk >= 0.35 and Risk < 0.80
   |       |
   |       +--> Google Sheets: Append warning log
   |       |
   |       +--> Telegram: Send warning text
   |
   +--> ELSE
           |
           +--> Google Sheets: Append normal reading

Webhook Node

  • Method: POST
  • Path: health-data
  • Response Mode: Immediately
  • ESP32 URL: https://YOUR-N8N-DOMAIN/webhook/health-data

Code Node: AI Risk Agent

Create a Code node and set it to run once for all items.

const items = $input.all();
const results = [];

for (const item of items) {
  const d = item.json;

  const hr = Number(d.heartRate || 0);
  const spo2 = Number(d.spo2 || 0);
  const temp = Number(d.temperature || 0);
  const fall = Boolean(d.fallDetected);

  let hrScore = 0;
  if (hr >= 50 && hr <= 100) hrScore = 0;
  else if (hr > 100 && hr <= 120) hrScore = 0.5;
  else if (hr > 120) hrScore = 1;
  else if (hr < 50) hrScore = 1;

  let spo2Score = 0;
  if (spo2 >= 95) spo2Score = 0;
  else if (spo2 >= 92 && spo2 < 95) spo2Score = 0.5;
  else if (spo2 >= 88 && spo2 < 92) spo2Score = 0.85;
  else if (spo2 > 0 && spo2 < 88) spo2Score = 1;

  let tempScore = 0;
  if (temp >= 36.1 && temp <= 37.8) tempScore = 0;
  else if (temp > 37.8 && temp <= 38.5) tempScore = 0.5;
  else if (temp > 38.5) tempScore = 1;

  const fallScore = fall ? 1 : 0;

  const riskScore =
    hrScore * 0.20 +
    spo2Score * 0.30 +
    tempScore * 0.15 +
    fallScore * 0.25 +
    0.10 * (spo2Score > 0.5 && hrScore > 0.5 ? 1 : 0);

  let riskLevel = "NORMAL";
  let alertRequired = false;
  let voiceRequired = false;

  if (riskScore >= 0.80 || fall) {
    riskLevel = "EMERGENCY";
    alertRequired = true;
    voiceRequired = true;
  } else if (riskScore >= 0.60) {
    riskLevel = "HIGH RISK";
    alertRequired = true;
  } else if (riskScore >= 0.35) {
    riskLevel = "WARNING";
    alertRequired = true;
  }

  const reason = [];
  if (hrScore > 0) reason.push("Abnormal heart rate");
  if (spo2Score > 0) reason.push("Low oxygen saturation");
  if (tempScore > 0) reason.push("Abnormal body temperature");
  if (fall) reason.push("Fall or SOS detected");

  results.push({
    json: {
      ...d,
      riskScore: Number(riskScore.toFixed(2)),
      riskLevel,
      alertRequired,
      voiceRequired,
      reason: reason.join(", ") || "All parameters normal"
    }
  });
}

return results;

IF Node Conditions

Create three output branches:

  1. Emergency:
    {{ $json.riskLevel }} is equal to EMERGENCY
    OR {{ $json.fallDetected }} is true.
  2. Warning / High Risk:
    {{ $json.riskLevel }} is equal to WARNING or HIGH RISK.
  3. Normal:
    {{ $json.riskLevel }} is equal to NORMAL.

Google Sheets Node

Create a Google Sheet named Health Monitoring Log with headers:

Timestamp Device ID Patient Heart Rate SpO2 Temperature Fall Risk Score Risk Level Reason

In n8n:

  • Operation: Append Row
  • Document: Select your Google Sheet
  • Sheet: Select the log tab
  • Map each ESP32 field to the matching column.

Telegram Text Alert Node

  • Resource: Message
  • Operation: Send Message
  • Chat ID: Your caregiver chat ID or @your_channel
  • Text:
🚨 EMERGENCY HEALTH ALERT

Patient: {{ $json.patientName }}
Device: {{ $json.deviceId }}

❤️ Heart Rate: {{ $json.heartRate }} bpm
🫁 SpO2: {{ $json.spo2 }}%
🌡️ Temperature: {{ $json.temperature }} °C
🚨 Fall/SOS: {{ $json.fallDetected }}

AI Risk Level: {{ $json.riskLevel }}
Risk Score: {{ $json.riskScore }}
Reason: {{ $json.reason }}

Please check on the patient immediately.

n8n’s Telegram node supports message operations including Send Message and Send Audio; it uses Telegram Bot API credentials.[docs.n8n][docs.n8n]

Telegram Voice Alerts

There are two practical approaches:

Method How it works Best for
Pre-recorded voice file Upload emergency.mp3 or .ogg once; n8n sends the same file Simple, reliable, no external TTS cost
AI text-to-speech n8n generates a custom MP3 from the alert text, then sends it Dynamic, personalized alerts

n8n supports Telegram Send Audio, so you can send an audio file to a chat.[docs.n8n]

Option A: Send Pre-recorded Voice Alert

  1. Record an MP3 such as:
    “Emergency alert. The patient’s health readings are critical. Please check immediately.”
  2. Upload it to a publicly accessible URL, Google Drive direct-download link, or your server.
  3. In n8n, add a Telegram node.
  4. Set:

    • Resource: Message
    • Operation: Send Audio
    • Chat ID: caregiver chat ID
    • File URL: your MP3 URL
    • Caption: AI Emergency Voice Alert

Option B: Dynamic AI Voice Message

Use a TTS provider such as ElevenLabs, Google Cloud Text-to-Speech, Amazon Polly, or OpenAI TTS.

Emergency branch
   |
   v
Set Node: Create voice text
   |
   v
HTTP Request: TTS API
   |
   v
Telegram Node: Send Audio

Example dynamic voice text:

Emergency alert for Patient A.
Heart rate is {{ $json.heartRate }} beats per minute.
Oxygen saturation is {{ $json.spo2 }} percent.
Body temperature is {{ $json.temperature }} degrees Celsius.
{{ $json.reason }}.
Please check the patient immediately.

n8n Telegram Command Workflow

Create a second workflow for caregiver interaction.

Telegram Trigger: Message
   |
   v
Switch Node:
   - STATUS
   - HELP
   - MUTE
   - UNMUTE
   |
   v
Telegram Send Message

n8n’s Telegram Trigger can respond to incoming messages, and you can restrict it to specific chat IDs for safety.[docs.n8n][docs.n8n]

Example Commands

Command Response
STATUS Latest HR, SpO2, temperature, risk level
HELP Emergency contact and instructions
MUTE 30 Suppress non-critical alerts for 30 minutes
UNMUTE Re-enable alerts
SOS Trigger emergency workflow manually

Telegram Trigger Setup

  • Updates: Message
  • Credentials: Your Telegram Bot token from BotFather
  • Restrict to Chat IDs: Add only trusted caregiver chat IDs

n8n requires a public HTTPS webhook URL for Telegram triggers when running behind a reverse proxy.[docs.n8n]

ThingSpeak Setup

Create a ThingSpeak channel with these fields:

Field Data
Field 1 Heart Rate
Field 2 SpO2
Field 3 Body Temperature
Field 4 Fall/SOS flag
Field 5 AI Risk Score
Field 6 Risk Level Code

ThingSpeak supports writing channel data through HTTP GET/POST or MQTT.[se.mathworks]

ESP32 ThingSpeak Write URL

https://api.thingspeak.com/update?api_key=YOUR_WRITE_API_KEY&field1=78&field2=97&field3=36.8&field4=0&field5=0.12&field6=0

Recommended Widgets

  • Heart-rate line chart
  • SpO2 line chart
  • Temperature line chart
  • Fall/SOS indicator
  • Risk score gauge
  • MATLAB Analysis widget for moving averages and trend detection

Google Sheets Dashboard

Create a second sheet called Dashboard with formulas such as:

Latest heart rate:
=INDEX('Health Monitoring Log'!D:D, COUNTA('Health Monitoring Log'!D:D))

Latest SpO2:
=INDEX('Health Monitoring Log'!E:E, COUNTA('Health Monitoring Log'!E:E))

Latest temperature:
=INDEX('Health Monitoring Log'!F:F, COUNTA('Health Monitoring Log'!F:F))

Latest risk level:
=INDEX('Health Monitoring Log'!I:I, COUNTA('Health Monitoring Log'!I:I))

Emergency count today:
=COUNTIFS('Health Monitoring Log'!I:I,"EMERGENCY",'Health Monitoring Log'!A:A,">="&TODAY())

Use Google Sheets conditional formatting:

  • Green: NORMAL
  • Yellow: WARNING
  • Orange: HIGH RISK
  • Red: EMERGENCY

Complete n8n Workflow JSON

Import this into n8n using Workflows → Import from File or paste it into the workflow editor. Replace placeholder credentials and IDs before activating.

{
  "name": "AI Health Monitoring Emergency Prediction",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "health-data",
        "responseMode": "responseNode",
        "options": {}
      },
      "id": "webhook-node",
      "name": "ESP32 Health Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [0, 0],
      "webhookId": "health-data"
    },
    {
      "parameters": {
        "jsCode": "const items = $input.all();\nconst results = [];\n\nfor (const item of items) {\n  const d = item.json;\n  const hr = Number(d.heartRate || 0);\n  const spo2 = Number(d.spo2 || 0);\n  const temp = Number(d.temperature || 0);\n  const fall = Boolean(d.fallDetected);\n\n  let hrScore = 0;\n  if (hr > 100 && hr <= 120) hrScore = 0.5;\n  else if (hr > 120 || (hr > 0 && hr < 50)) hrScore = 1;\n\n  let spo2Score = 0;\n  if (spo2 >= 92 && spo2 < 95) spo2Score = 0.5;\n  else if (spo2 >= 88 && spo2 < 92) spo2Score = 0.85;\n  else if (spo2 > 0 && spo2 < 88) spo2Score = 1;\n\n  let tempScore = 0;\n  if (temp > 37.8 && temp <= 38.5) tempScore = 0.5;\n  else if (temp > 38.5) tempScore = 1;\n\n  const fallScore = fall ? 1 : 0;\n  const combinedScore = spo2Score > 0.5 && hrScore > 0.5 ? 1 : 0;\n\n  const riskScore =\n    hrScore * 0.20 +\n    spo2Score * 0.30 +\n    tempScore * 0.15 +\n    fallScore * 0.25 +\n    combinedScore * 0.10;\n\n  let riskLevel = 'NORMAL';\n  if (riskScore >= 0.80 || fall) riskLevel = 'EMERGENCY';\n  else if (riskScore >= 0.60) riskLevel = 'HIGH RISK';\n  else if (riskScore >= 0.35) riskLevel = 'WARNING';\n\n  const reason = [];\n  if (hrScore > 0) reason.push('Abnormal heart rate');\n  if (spo2Score > 0) reason.push('Low oxygen saturation');\n  if (tempScore > 0) reason.push('Abnormal body temperature');\n  if (fall) reason.push('Fall or SOS detected');\n\n  results.push({\n    json: {\n      ...d,\n      riskScore: Number(riskScore.toFixed(2)),\n      riskLevel,\n      alertRequired: riskLevel !== 'NORMAL',\n      voiceRequired: riskLevel === 'EMERGENCY',\n      reason: reason.join(', ') || 'All parameters normal'\n    }\n  });\n}\n\nreturn results;"
      },
      "id": "ai-risk-node",
      "name": "AI Emergency Prediction Agent",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [220, 0]
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "version": 2
          },
          "conditions": [
            {
              "leftValue": "={{ $json.riskLevel }}",
              "rightValue": "EMERGENCY",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "id": "emergency-if",
      "name": "Is Emergency?",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "position": [440, 0]
    },
    {
      "parameters": {
        "operation": "append",
        "documentId": {
          "__rl": true,
          "value": "YOUR_GOOGLE_SHEET_ID",
          "mode": "id"
        },
        "sheetName": {
          "__rl": true,
          "value": "Health Monitoring Log",
          "mode": "name"
        },
        "columns": {
          "mappingMode": "autoMapInputData",
          "matchingColumns": [],
          "schema": []
        },
        "options": {}
      },
      "id": "sheets-node",
      "name": "Log To Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4.5,
      "position": [660, -120],
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "REPLACE_CREDENTIAL_ID",
          "name": "Google Sheets account"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "sendMessage",
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "text": "=🚨 EMERGENCY HEALTH ALERT\\n\\nPatient: {{ $json.patientName }}\\nDevice: {{ $json.deviceId }}\\n\\n❤️ HR: {{ $json.heartRate }} bpm\\n🫁 SpO2: {{ $json.spo2 }}%\\n🌡️ Temp: {{ $json.temperature }} °C\\n🚨 Fall/SOS: {{ $json.fallDetected }}\\n\\nAI Risk: {{ $json.riskLevel }}\\nScore: {{ $json.riskScore }}\\nReason: {{ $json.reason }}",
        "additionalFields": {}
      },
      "id": "telegram-text",
      "name": "Telegram Emergency Text",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [660, 80],
      "credentials": {
        "telegramApi": {
          "id": "REPLACE_CREDENTIAL_ID",
          "name": "Telegram Bot"
        }
      }
    },
    {
      "parameters": {
        "resource": "message",
        "operation": "sendAudio",
        "chatId": "YOUR_TELEGRAM_CHAT_ID",
        "file": "https://YOUR-SERVER.COM/emergency-alert.mp3",
        "additionalFields": {
          "caption": "AI Emergency Voice Alert"
        }
      },
      "id": "telegram-voice",
      "name": "Telegram Voice Alert",
      "type": "n8n-nodes-base.telegram",
      "typeVersion": 1.2,
      "position": [880, 80],
      "credentials": {
        "telegramApi": {
          "id": "REPLACE_CREDENTIAL_ID",
          "name": "Telegram Bot"
        }
      }
    },
    {
      "parameters": {
        "respondWith": "json",
        "responseBody": "={{ { \"status\": \"received\", \"riskLevel\": $json.riskLevel, \"riskScore\": $json.riskScore } }}"
      },
      "id": "respond-node",
      "name": "Respond To ESP32",
      "type": "n8n-nodes-base.respondToWebhook",
      "typeVersion": 1.1,
      "position": [1100, 0]
    }
  ],
  "connections": {
    "ESP32 Health Webhook": {
      "main": [
        [
          {
            "node": "AI Emergency Prediction Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Emergency Prediction Agent": {
      "main": [
        [
          {
            "node": "Is Emergency?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is Emergency?": {
      "main": [
        [
          {
            "node": "Log To Google Sheets",
            "type": "main",
            "index": 0
          },
          {
            "node": "Telegram Emergency Text",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Respond To ESP32",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Emergency Text": {
      "main": [
        [
          {
            "node": "Telegram Voice Alert",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Telegram Voice Alert": {
      "main": [
        [
          {
            "node": "Respond To ESP32",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "settings": {
    "executionOrder": "v1"
  }
}

Testing Procedure

  1. Flash the ESP32 code and confirm Wi-Fi connection in Serial Monitor.
  2. Open the n8n webhook URL and verify that it receives JSON.
  3. Send test data manually with curl:
curl -X POST https://YOUR-N8N-DOMAIN/webhook/health-data \
  -H "Content-Type: application/json" \
  -d '{"deviceId":"ESP32-HEALTH-01","patientName":"Patient A","heartRate":135,"spo2":89,"temperature":38.9,"fallDetected":true}'
  1. Confirm that Google Sheets receives a row.
  2. Confirm Telegram text alert arrives.
  3. Confirm Telegram voice/audio alert arrives for emergency cases.
  4. Check ThingSpeak charts update.
  5. Press the SOS button and verify the emergency workflow.
  6. Test Wi-Fi loss and ensure the ESP32 reconnects automatically.

Safety and Reliability

  • Use encrypted HTTPS for the n8n webhook.
  • Store API keys, Telegram tokens, and Wi-Fi credentials outside public repositories.
  • Add alert deduplication so the caregiver does not receive hundreds of alerts per minute.
  • Use a local fallback: if Wi-Fi fails, activate the buzzer and store readings in flash/SD card.
  • Calibrate temperature and SpO2 sensors before use.
  • Add a physical SOS button; automatic fall detection alone can produce false positives.
  • For a real healthcare deployment, use certified medical sensors, patient consent, data-privacy controls, and clinical validation.

This design gives you a complete foundation for an AI-powered, agentic ESP32 health-monitoring and emergency-prediction system with ThingSpeak visualization, Google Sheets records, n8n automation, and Telegram text/voice alerts.[se.mathworks][docs.n8n][docs.n8n]

No comments:

Post a Comment