Initial biometric data receiver implementation
This commit is contained in:
140
README.md
Normal file
140
README.md
Normal file
@@ -0,0 +1,140 @@
|
||||
# Pilot Bio-Data — Pulse Oximeter Logger
|
||||
|
||||
Receives real-time **heart rate (BPM)** and **blood-oxygen (SpO₂)** readings
|
||||
from the Controlytics AI pulse oximeter over a wired Ethernet connection and
|
||||
logs them to a timestamped CSV file.
|
||||
|
||||
---
|
||||
|
||||
## Hardware
|
||||
|
||||
| Item | Detail |
|
||||
|---|---|
|
||||
| Device | Controlytics AI Pulse Oximeter v1.0.0 |
|
||||
| Interface | Ethernet (UDP) |
|
||||
| Device Ethernet IP | `192.168.1.2` |
|
||||
| Device WiFi AP | `PULSE_OXI_WIFI` / password `controlytics` |
|
||||
| Device config page | `http://192.168.4.1` (Admin / Admin) |
|
||||
|
||||
---
|
||||
|
||||
## Network Setup
|
||||
|
||||
The device sends UDP packets to a configured destination address.
|
||||
The one-time setup below is already done; repeat only if hardware changes.
|
||||
|
||||
### Computer (receiver)
|
||||
|
||||
Assign a static IP to the Ethernet interface connected to the device:
|
||||
|
||||
```bash
|
||||
sudo ip addr add 192.168.1.100/24 dev <eth-interface>
|
||||
```
|
||||
|
||||
On this machine the interface is `enp1s0`:
|
||||
|
||||
```bash
|
||||
sudo ip addr add 192.168.1.100/24 dev enp1s0
|
||||
```
|
||||
|
||||
### Device configuration
|
||||
|
||||
Connect to `PULSE_OXI_WIFI`, open `http://192.168.4.1`, log in, and set:
|
||||
|
||||
| Field | Value |
|
||||
|---|---|
|
||||
| IP | `192.168.1.2` |
|
||||
| Gateway | `192.168.1.1` |
|
||||
| Subnet | `255.255.255.0` |
|
||||
| Destination address | `192.168.1.100` |
|
||||
| Destination port | `5005` |
|
||||
| Send interval (ms) | `500` |
|
||||
|
||||
Submit and restart the device (Log Out button).
|
||||
|
||||
---
|
||||
|
||||
## Requirements
|
||||
|
||||
Python 3.10 or later. No third-party packages — only the standard library is used.
|
||||
|
||||
```bash
|
||||
python3 --version # 3.10+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Running
|
||||
|
||||
```bash
|
||||
python3 receive.py
|
||||
```
|
||||
|
||||
Place the pilot's index finger on the sensor with light, steady pressure.
|
||||
Hold still for a few seconds for the reading to stabilise.
|
||||
|
||||
### Example output
|
||||
|
||||
```
|
||||
Listening on UDP 0.0.0.0:5005 | Logging to readings.csv
|
||||
TIME BPM SpO2 % STATUS
|
||||
----------------------------------------------------
|
||||
11:34:00.464 92 97 OK
|
||||
11:34:00.965 92 97 OK
|
||||
11:34:01.466 74 97 OK
|
||||
11:34:22.034 87 98 OK
|
||||
11:35:14.207 --- --- No finger
|
||||
```
|
||||
|
||||
Press `Ctrl+C` to stop.
|
||||
|
||||
---
|
||||
|
||||
## Output — readings.csv
|
||||
|
||||
Every packet is appended to `readings.csv` in the same directory.
|
||||
Rows where no finger is detected have empty `bpm` and `spo2` fields.
|
||||
|
||||
| Column | Description |
|
||||
|---|---|
|
||||
| `timestamp` | ISO-8601 local timestamp |
|
||||
| `bpm` | Heart rate in beats per minute (empty if no finger) |
|
||||
| `spo2` | Blood-oxygen saturation % (empty if no finger) |
|
||||
| `raw` | Raw JSON packet from device |
|
||||
|
||||
### Example rows
|
||||
|
||||
```
|
||||
timestamp,bpm,spo2,raw
|
||||
2026-06-12T11:34:00.464000,92,97,"{""bpm"":92,""spo2"":97}"
|
||||
2026-06-12T11:34:01.466000,74,97,"{""bpm"":74,""spo2"":97}"
|
||||
2026-06-12T11:35:14.207000,,,"{""bpm"":-1,""spo2"":-1}"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Packet Format
|
||||
|
||||
The device sends a UDP JSON payload every 500 ms:
|
||||
|
||||
```json
|
||||
{"bpm": 92, "spo2": 97}
|
||||
```
|
||||
|
||||
Values of `-1` indicate no finger is on the sensor.
|
||||
The parser also accepts `key=value` and bare CSV formats for forward compatibility.
|
||||
|
||||
---
|
||||
|
||||
## Project Structure
|
||||
|
||||
```
|
||||
pilot_bio_data/
|
||||
├── receive.py # UDP listener and CSV logger
|
||||
├── readings.csv # Auto-generated log (appended on each run)
|
||||
└── README.md
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
*Axial Aero — Internal tooling*
|
||||
Reference in New Issue
Block a user