Skip to content
~/amoghshendre
← back to projects

BLE Biosensor Pipeline

ESP32-S3 heart-rate monitor with gap-detection and backfill sync to Android and a Pi backend.

private sourcec++esp32-s3max30102kotlinnode.js

the problem

Continuous heart-rate capture over Bluetooth Low Energy is lossy — phones sleep, connections drop, people walk out of range. A monitor that silently loses data during those gaps isn't a monitor. I wanted a complete record in spite of the dropouts.

architecture

  1. MAX30102optical sensor
  2. ESP32-S3C++ firmware + buffer
  3. BLE
  4. AndroidKotlin client
  5. Raspberry PiNode.js backend

A MAX30102 optical sensor feeds an ESP32-S3 running C++ firmware, which streams readings over BLE to a Kotlin Android client and on to a Node.js backend on a Raspberry Pi. The pipeline detects gaps in the record and backfills them on reconnect, so a dropped link becomes a delay rather than a hole.

engineering decisions

  • Gap detection and backfill instead of best-effort streaming

    Rather than assume the link is up, each tier tracks what it has and what it's missing, then reconciles on reconnect. Completeness is designed in, not hoped for.

  • Buffering at the edge

    The ESP32-S3 holds readings so a disconnected phone doesn't mean lost samples — the device keeps recording and hands the backlog over when the link returns.

  • A tiered edge → phone → server path

    Each hop has a clear job: the microcontroller captures and buffers, the phone relays and caches, the Pi is the durable store. Failures at any hop degrade gracefully.

reliability & security

Gap detection and backfill are the reliability story: the record converges to complete once connectivity returns, so a lost connection costs latency, not data.

constraints

A constrained microcontroller, an intermittent BLE link, and a phone that will sleep whenever the OS decides. The design assumes the connection is unreliable by default.