# tianshang301/tianshangpulse architecture

> Architecture diagram of the GitHub repository tianshang301/tianshangpulse, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-28). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/tianshang301/tianshangpulse
- Repository: https://github.com/tianshang301/tianshangpulse

## Overview

TianshangPulse is ESP32 smartwatch firmware for offline PPG/IMU monitoring, gated on-device AF detection, and BLE delivery to a companion app. The main task initializes device services and coordinates sampling and inference: sensor data is windowed, preprocessed, quality/motion-gated, converted to beat features, then classified; qualifying results are cached and notified over BLE. The README also describes configurable UI, power modes, and offline batch sync. The UI currently shows placeholders, and the sampled inference code does not establish a live display-data path. Unsampled subsystems are included only where the tree and README support them.

Main entry points: [`firmware/main/main.c`](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/main.c) (Task coordinator), [`firmware/main/ble/gatt_server.c`](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/gatt_server.c) (GATT server), [`firmware/main/sensors/sensor.c`](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/sensor.c) (Sensor interface), [`firmware/main/tflite/inference_engine.cc`](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/tflite/inference_engine.cc) (AF inference)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_sensing["Sensing"]
  node_entry["Task coordinator<br/>[main.c]"]
  node_sensor_api["Sensor interface<br/>[sensor.c]"]
  node_ppg_driver["PPG driver<br/>[max30102.c]"]
  node_imu_driver["IMU driver<br/>[mpu6886.c]"]
end

subgraph group_analysis["Signal analysis"]
  node_preprocess["PPG preprocessing<br/>[ppg_preprocess.c]"]
  node_signal_gate["Motion and SQI gate<br/>[signal_gate.c]"]
  node_features["Beat features<br/>[af_features.c]"]
  node_inference["AF inference"]
  node_coefficients["LR coefficients<br/>[af_lr_coefs.h]"]
end

subgraph group_connectivity["BLE connectivity"]
  node_gatt["GATT server<br/>[gatt_server.c]"]
  node_protocol["BLE protocol<br/>[protocol.c]"]
  node_advertising["BLE advertising<br/>[adv.c]"]
  node_cache["Offline event cache<br/>[offline_cache.c]"]
end

subgraph group_device["Device services"]
  node_ui["UI manager<br/>[ui_manager.c]"]
  node_display["Display driver<br/>[display_driver.c]"]
  node_power["Power manager<br/>[power_manager.c]"]
end

node_wearer(("Wearer"))
node_max_hw["MAX30102"]
node_imu_hw["MPU6886"]
node_companion(("Android app"))

node_wearer -->|"wears"| node_max_hw
node_max_hw -->|"provides PPG"| node_ppg_driver
node_imu_hw -->|"provides motion"| node_imu_driver
node_entry -->|"initializes and samples"| node_sensor_api
node_sensor_api -->|"reads PPG"| node_ppg_driver
node_sensor_api -->|"reads IMU"| node_imu_driver
node_entry -->|"gets samples"| node_sensor_api
node_entry -->|"normalizes windows"| node_preprocess
node_entry -->|"evaluates motion and SQI"| node_signal_gate
node_entry -->|"extracts beat features"| node_features
node_entry -->|"runs and reads results"| node_inference
node_inference -->|"scores with"| node_coefficients
node_entry -->|"sends heart rate and anomalies"| node_gatt
node_entry -->|"queues anomaly events"| node_cache
node_gatt -->|"packs and parses"| node_protocol
node_gatt -->|"starts and restarts"| node_advertising
node_gatt -->|"reads batches and acknowledges"| node_cache
node_companion -->|"configures and syncs"| node_gatt
node_gatt -->|"notifies and serves events"| node_companion
node_entry -->|"initializes"| node_ui
node_ui -->|"initializes display"| node_display
node_entry -->|"initializes"| node_power
node_gatt -->|"sets active on connect"| node_power

click node_entry "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/main.c"
click node_sensor_api "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/sensor.c"
click node_ppg_driver "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/max30102.c"
click node_imu_driver "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/mpu6886.c"
click node_preprocess "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/ppg_preprocess.c"
click node_signal_gate "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/signal_gate.c"
click node_features "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/af_features.c"
click node_inference "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/tflite/inference_engine.cc"
click node_coefficients "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/af_lr_coefs.h"
click node_gatt "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/gatt_server.c"
click node_protocol "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/protocol.c"
click node_advertising "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/adv.c"
click node_cache "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/offline_cache.c"
click node_ui "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ui/ui_manager.c"
click node_display "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ui/display_driver.c"
click node_power "https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/power/power_manager.c"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_entry,node_sensor_api,node_ppg_driver,node_imu_driver toneBlue
class node_preprocess,node_signal_gate,node_features,node_inference,node_coefficients toneAmber
class node_gatt,node_protocol,node_advertising,node_cache toneMint
class node_ui,node_display,node_power toneRose
class node_wearer,node_max_hw,node_imu_hw,node_companion toneIndigo
```

## Components

### Sensing

- [Task coordinator](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/main.c): `firmware/main/main.c`
- [Sensor interface](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/sensor.c): `firmware/main/sensors/sensor.c`
- [PPG driver](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/max30102.c): `firmware/main/sensors/max30102.c`
- [IMU driver](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/mpu6886.c): `firmware/main/sensors/mpu6886.c`

### Signal analysis

- [PPG preprocessing](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/ppg_preprocess.c): `firmware/main/sensors/ppg_preprocess.c`
- [Motion and SQI gate](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/signal_gate.c): `firmware/main/sensors/signal_gate.c`
- [Beat features](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/sensors/af_features.c): `firmware/main/sensors/af_features.c`
- [AF inference](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/tflite/inference_engine.cc): `firmware/main/tflite/inference_engine.cc`
- [LR coefficients](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/af_lr_coefs.h): `firmware/main/af_lr_coefs.h`

### BLE connectivity

- [GATT server](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/gatt_server.c): `firmware/main/ble/gatt_server.c`
- [BLE protocol](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/protocol.c): `firmware/main/ble/protocol.c`
- [BLE advertising](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/adv.c): `firmware/main/ble/adv.c`
- [Offline event cache](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ble/offline_cache.c): `firmware/main/ble/offline_cache.c`

### Device services

- [UI manager](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ui/ui_manager.c): `firmware/main/ui/ui_manager.c`
- [Display driver](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/ui/display_driver.c): `firmware/main/ui/display_driver.c`
- [Power manager](https://github.com/tianshang301/tianshangpulse/blob/main/firmware/main/power/power_manager.c): `firmware/main/power/power_manager.c`

### Other components

- **Wearer**
- **MAX30102**
- **MPU6886**
- **Android app**

## Connections

- Wearer → MAX30102: wears
- MAX30102 → PPG driver: provides PPG
- MPU6886 → IMU driver: provides motion
- Task coordinator → Sensor interface: initializes and samples
- Sensor interface → PPG driver: reads PPG
- Sensor interface → IMU driver: reads IMU
- Task coordinator → Sensor interface: gets samples
- Task coordinator → PPG preprocessing: normalizes windows
- Task coordinator → Motion and SQI gate: evaluates motion and SQI
- Task coordinator → Beat features: extracts beat features
- Task coordinator → AF inference: runs and reads results
- AF inference → LR coefficients: scores with
- Task coordinator → GATT server: sends heart rate and anomalies
- Task coordinator → Offline event cache: queues anomaly events
- GATT server → BLE protocol: packs and parses
- GATT server → BLE advertising: starts and restarts
- GATT server → Offline event cache: reads batches and acknowledges
- Android app → GATT server: configures and syncs
- GATT server → Android app: notifies and serves events
- Task coordinator → UI manager: initializes
- UI manager → Display driver: initializes display
- Task coordinator → Power manager: initializes
- GATT server → Power manager: sets active on connect
