NephroSense is my most ambitious project to date — an IoT-based real-time kidney health monitoring system that combines ESP32 microcontrollers, health sensors, AWS IoT Core, and a machine learning model to predict Chronic Kidney Disease (CKD) risk. Here's the full technical breakdown.
The Problem We're Solving
CKD affects over 850 million people worldwide, but 90% don't know they have it until it's in advanced stages because early symptoms are silent. Traditional monitoring requires frequent hospital visits and lab tests. NephroSense aims to bring non-invasive, continuous monitoring to the home.
"Early detection saves lives. If IoT can make that detection accessible, we have a responsibility to build it."
Hardware Architecture
Components used:
- ESP32 DevKit v1 — main microcontroller (WiFi + Bluetooth built-in)
- MAX30102 — Pulse oximetry + heart rate sensor (I2C)
- DS18B20 — Body temperature sensor (OneWire protocol)
- AD8232 — ECG signal measurement module
- OLED 0.96" display (SSD1306) — local readout via I2C
- 18650 LiPo battery + TP4056 charging module — portable power
Firmware: ESP32 + Arduino Framework
The ESP32 reads sensor data every 5 seconds and publishes to AWS IoT Core via MQTT over TLS:
#include <WiFiClientSecure.h>
#include <PubSubClient.h>
#include <MAX3010x.h>
#include <DallasTemperature.h>
// Publish sensor payload to MQTT
void publishReading(float heartRate, float spo2, float temp) {
char payload[256];
snprintf(payload, sizeof(payload),
"{\"device\":\"nephrosense-01\",\"hr\":%.1f,\"spo2\":%.1f,\"temp\":%.2f,\"ts\":%lu}",
heartRate, spo2, temp, millis()
);
mqttClient.publish("nephrosense/readings", payload);
}
AWS IoT Pipeline
The cloud backend processes readings in real-time:
- AWS IoT Core — MQTT broker with TLS mutual auth (X.509 device certs)
- IoT Rules Engine → routes messages to Lambda and DynamoDB
- Lambda function — runs CKD risk scoring on each reading batch
- DynamoDB — stores time-series readings with TTL for 90-day retention
- SNS — sends SMS/email alert if risk score exceeds threshold
The ML Model
The CKD prediction model was trained on the UCI CKD dataset (400 patients, 24 features). We used Random Forest (best accuracy: 98.3%) deployed as a Lambda layer:
import joblib, json
model = joblib.load('/opt/ckd_model.pkl')
scaler = joblib.load('/opt/scaler.pkl')
def handler(event, context):
features = [event['hr'], event['spo2'], event['temp'], ...]
scaled = scaler.transform([features])
risk_prob = model.predict_proba(scaled)[0][1]
risk_level = 'HIGH' if risk_prob > 0.7 else 'MEDIUM' if risk_prob > 0.4 else 'LOW'
return {'risk_level': risk_level, 'probability': round(risk_prob, 3)}
Mobile Dashboard
The mobile dashboard (built with React Native) shows:
- Live heart rate and SpO2 gauge charts (update every 5s)
- 24-hour trend graphs with anomaly markers
- CKD risk indicator with color coding (green/yellow/red)
- Push notifications for threshold breaches
Key Takeaways
Building NephroSense taught me that IoT projects are harder than they look — but also more rewarding. The biggest challenges were sensor calibration drift, WiFi reconnection handling, and keeping AWS Lambda cold-start times under 500ms. All solvable with persistence and good architecture.