Skip to the content
PCBKitNew board
2 layers60 × 40 mmEsp ppo v2, the printed circuit board in 3D

Esp ppo v2

iho77/ppo_v25

This work is licensed under a [Creative Commons Attribution-NonCommercial 4.0 International License][cc-by-nc].

Size
60 × 40 mm
Copper layers
2
Thickness
1.6 mm
Parts
19
Nets
27
Pads
88
Tracks, vias
136, 4
Routed
Yes
KiCad
KiCad 9.0 (file 20241229)
Created
12 Sep 2025
Updated
6 Nov 2025

Overview

Esp ppo v2 is an open-source printed circuit board by iho77, from the iho77/ppo_v2 repository on GitHub. It is a 2-layer board of 60 × 40 mm with 19 parts on 27 nets, routed with 136 tracks and 4 vias.

It is built around the ESP32-C3-DEVKITM-1 and TPS63031DSK. Its parts include 6 capacitors, 5 resistors, 3 ICs, 3 connectors and 1 inductor. It belongs with the ESP32 and RISC-V boards of this library.

Main components

2

README

README.md

Shield: CC BY-NC 4.0

This work is licensed under a Creative Commons Attribution-NonCommercial 4.0 International License.

CC BY-NC 4.0

PPO2 Display

A high-precision Partial Pressure of Oxygen (PPO2) monitoring system for technical diving, built on ESP32-C3 with dual O2 sensor support and advanced signal processing algorithms.

Safety Notes

⚠️ WARNING:

OXYGEN PPO MONITORING SOFTWARE

This software is not a dive computer, life-support system, medical device, or safety-critical instrument. It is provided for informational and educational purposes only. Readings may be inaccurate, delayed, or fail due to sensor drift/aging, moisture, calibration error, power or hardware faults, electromagnetic interference, or software bugs.

Do not rely on this software to determine breathing-gas safety. Always follow certified dive training and procedures, use approved equipment, carry independent/redundant instruments, and maintain conservative dive plans. Diving—especially with rebreathers—carries inherent risks of serious injury or death.

The software is provided “AS IS,” without warranties of any kind. To the maximum extent permitted by law, the developer disclaims all liability for any loss, damage, injury, or death arising from use or misuse of this software. By downloading, installing, or using the software, you acknowledge and accept all risks and agree to release, indemnify, and hold the developer harmless from any claims.

If you do not agree, do not use this software.

⚠️ IMPORTANT: This sostware developed using Anthropic Claude heavly with lack of human verification and testing.

⚠️ IMPORTANT: This system is designed for TESTING PURPUSES ONLY. Users must:

  1. Validate Calibration: Always verify calibration with known gas mixtures
  2. Dual Sensor Monitoring: Never dive with single sensor operation
  3. Regular Maintenance: Check sensor health and calibration frequently
  4. Backup Systems: Always carry independent PPO2 monitoring
  5. Training Required: Proper technical diving certification essential

This system is a diving aid and should not be the sole method of gas monitoring during technical dives.

Required Tools & Environment

  • ESP-IDF Framework - Espressif's official development framework
  • CMake (3.16+) - Build system
  • Python - For ESP-IDF tools and flashing
  • Git - For version control and ESP-IDF installation

Hardware Platform

  • Target MCU: ESP32-C3 Development Board
  • Display: 128x128 SH1107 OLED (I2C at 0x3D, 400kHz)
  • Sensors: Internal ADC for O2 sensor readings
  • Buttons: 2x GPIO buttons (MODE/SELECT)
  • LED: Built-in RGB LED for warnings

Key Libraries & Components

  • FreeRTOS - Real-time operating system (1kHz tick)
  • ESP-IDF I2C Master Driver - Hardware communication
  • NVS Flash - Non-volatile storage for configuration
  • ESP Task Watchdog - System safety monitoring
  • Custom Components:
    • Display Manager (SH1107 driver)
    • Sensor Manager (O2 sensor interface)
    • Button Manager (GPIO with debouncing)
    • Warning Manager (LED control)
    • PPO2 Logger (data logging)

Pin Configuration

text
GPIO 0  -> ADC1_CH0 (O2 Sensor 1)
GPIO 1  -> ADC1_CH1 (O2 Sensor 2) 
GPIO 3  -> ADC1_CH3 (Battery voltage divider 1/3)
GPIO 6  -> I2C SDA (Display)
GPIO 7  -> I2C SCL (Display)
GPIO 5  -> MODE Button
GPIO 10  -> SELECT Button
GPIO 8  -> RGB LED (Warning system)

scheme

Key Features

Sensor Management

  • Dual O2 Sensor Support: Independent sensor processing with disagreement detection
  • Single sensor auto detection: Short Sensor + in cable connector to ground - device starts to work in 1 sensor modeI
  • Multipoint Calibration System: Air (21%), O2 (100%) or custom mix calibration points
  • Advanced Signal Processing: Median-of-5 → EMA → Slew-rate limiting pipeline
  • Sensor Health Monitoring: Automatic failure detection and recovery
  • Battery Monitoring: Real-time voltage and percentage display

Display System

  • Main Display: Large PPO2 values with calibration status indicators
  • Warning System: Scrolling text warnings with LED color coding
  • Battery Display: Dynamic battery icon with voltage readout
  • Menu System: Clean navigation with visual selection indicators

Warning System

  • PPO2 Thresholds: Configurable low/high warning and alarm levels
  • Sensor Disagreement: Automatic detection of sensor variance
  • Visual Alerts: Color-coded LED (Green/Yellow/Red) with blinking patterns
  • Display Integration: Warning messages shown on main screen

Core Algorithms

1. Robust Signal Processing Pipeline

The system implements a sophisticated 3-stage filtering pipeline for each O2 sensor:

Use 3 stages: spike removal → low-pass → rate limit + debounced alarms.

Spike/outlier killer (median-of-5) At each 20 Hz step, keep the last 5 raw samples and take the median.

Purpose: remove single-sample glitches without adding much lag (~0.1–0.15 s).

Exponential moving average (EMA) with ~5 s time constant Let y[n] = y[n−1] + α (x_med[n] − y[n−1]), where x_med is from step 1.

Sampling period dt = 1/20 = 0.05 s.

Choose time constant τ ≈ 5 s → α = dt/τ = 0.05/5 = 0.01.

Why: 5 s LPF kills high-freq jitter while keeping latency modest (~τ behind fast ramps).

Slew-rate limiter (enforce physics) If the environment cannot change by more than Δ_meaningful per 10 s, set

S_max = Δ_meaningful / 10 (units per second).

Per-sample limit: Δ_per_sample = S_max * dt. Then clamp the EMA output change: y_lim[n] = clamp(y[n−1] − Δ_per_sample, y[n], y[n−1] + Δ_per_sample).

Purpose: guarantees your displayed value can’t “move” faster than reality.

Debounced, hysteretic warnings (no flicker)

Trigger threshold: T_hi. Clear threshold: T_lo (with T_lo closer to normal than T_hi → hysteresis gap).

Require persistence: only raise a warning if y_lim[n] > T_hi continuously for T_confirm (e.g., 2–3 s).

Only clear if y_lim[n] < T_lo continuously for T_clear (e.g., 2–3 s).

Implement with two counters that increment while condition holds and reset otherwise.

That stack is O(1) memory and CPU, super stable, and easy to tune.

2. Multipoint Calibration System

Replaces traditional linear calibration with a robust 1 or 2-point system:

Calibration Points
  1. Air Calibration (21% O2 at 1 bar): PPO2 = 0.21 bar
  2. Oxygen Calibration (100% O2 at 1 bar): PPO2 = 1.00 bar
  3. Custom mix Calibration (Custom % O2 at 1 bar)

System can works with 1 point calibration or 2 points calibration. In case of 1 point calibration second point is 0 mv\ 0% oxygen.

3. Sensor Health Monitoring

Health Checks
  1. Voltage Range Validation: 0-1000mV acceptable range
  2. Calibration Validity: Both sensors must have valid calibration
  3. Sensor Disagreement: PPO2 difference > 0.05 bar triggers warning
  4. Communication Errors: ADC read failures tracked and recovered

Calibration-Based Drift & Linearity Tracking (Strategy 1)

A clear, hands-on guide you can mirror in logs, a spreadsheet, or firmware notes.

What you track (per sensor)

  • Gain / sensitivity k (mV/ata): millivolts per 1.0 ata ppO₂.
  • Offset b (mV): reading at ppO₂ = 0 (should be near 0).
  • Normalized sensitivity S = k / k₀ vs new-sensor baseline k₀.
  • Linearity across multiple known ppO₂ points: R² and max residual (mV).
  • Drift rate (e.g., %/month) and predicted EOL date (when S hits your fail threshold, e.g., 0.70).

Two-Point Calibration (minimum viable)

At each calibration, expose the sensor to two known ppO₂ points and record:

  • (p₁, m₁): e.g., air at surface → p₁ ≈ 0.209 ata, measured m₁ (mV)
  • (p₂, m₂): e.g., 100% O₂ at surface → p₂ = 1.00 ata, measured m₂ (mV)

Fit a line m = k·p + b:

text
k = (m₂ − m₁) / (p₂ − p₁)
b = m₁ − k · p₁

Then compute normalized sensitivity:

text
S = k / k₀

Where k₀ is your new-sensor baseline (mV/ata).


Worked Example A — two-point checks over time (one sensor)

Assume k₀ = 52.0 mV/ata (≈ 11 mV in air, ≈ 52 mV at 1.0 ata O₂).

DateAir mV m₁O₂ mV m₂Estimated k (mV/ata)b (mV)S = k/k₀
2025-01-0110.9952.2552.160.091.003
2025-05-0110.4549.5149.370.140.950
2025-10-019.4845.8646.00−0.140.885
2026-03-018.1839.8239.99−0.180.769

Interpretation

  • Sensitivity S drifts from ~1.00 → 0.77 over ~14 months (≈ 1.6 %/month).
  • Caution when S < 0.80 (here: 2026-03-01).
  • Predict EOL when S hits 0.70: extrapolation from the last trend ≈ Aug 2026 (~19 months from first calibration).

Log each time: the two mV readings and the computed k, b, S, plus a trendline of S vs time (and ETA to S = 0.70).


Practical guardrails

  • If |b| > 2–3 mV or it drifts steadily, investigate (zero-current leakage, moisture, wiring).
  • If degradation accelerates (> ~3–5 %/month), plan an early swap.
Failure Recovery
  • Graceful Degradation: System continues with single sensor
  • Fail-Safe PPO2: Conservative 0.21 bar default during total failure
  • Automatic Recovery: Sensors re-validated on successful reads

4. Warning State Machine

Warning States
c
typedef enum {
    WARNING_STATE_NORMAL = 0,    // Green LED - PPO2 in range
    WARNING_STATE_WARNING,       // Yellow blinking - PPO2 at limits  
    WARNING_STATE_ALARM         // Red blinking - PPO2 dangerous
} warning_state_t;
PPO2 Thresholds (Configurable)
  • Low Warning: 0.19 bar (hypoxia risk)
  • Low Alarm: 0.18 bar (severe hypoxia)
  • High Warning: 1.4 bar (oxygen toxicity risk)
  • High Alarm: 1.6 bar (severe toxicity risk)
LED Patterns
  • Normal: Solid green
  • Warning: Yellow blink at 2Hz (250ms on/off)
  • Alarm: Red blink at 4Hz (125ms on/off)

System Architecture

Component Organization

text
├── main/                   # Main application and mode management
│   ├── main.c             # System initialization and 20Hz main loop
│   └── modes/             # Mode-specific implementations
├── components/
│   ├── app_common/        # Shared types and configuration
│   ├── sensor_manager/    # O2 sensor processing and calibration
│   ├── display_manager/   # LVGL display driver and UI
│   ├── warning_manager/   # LED warning system
│   ├── button_manager/    # GPIO button handling
│   └── sh1107_driver/     # Low-level display driver

Data Flow

text
Sensors (20Hz) → Filtering → Calibration → Warning Analysis → Display Update
                     ↓
              Health Monitoring → Recovery Actions

Menu System

Main Menu Items

  1. Sensor Calibration - Dual sensor calibration with gas selection
  2. Reset Calibration - Individual or bulk calibration reset
  3. Print Logs - Debug output to serial console
  4. Sensor Health - Real-time sensor diagnostics
  5. System Setup - Configuration and thresholds
  6. Power Off - System shutdown

Calibration Workflow

  1. Gas Selection: Air, O2, or Custom (configurable %)
  2. Dual Sensor Display: Live mV readings for both sensors
  3. Calibration Action: Simultaneous calibration of both sensors
  4. Validation: Automatic sanity checks and confirmation

Setup Options

  • PPO2 Thresholds: Warning and alarm levels for low/high PPO2
  • Display Settings: Brightness and contrast
  • Sensor Configuration: Individual sensor enable/disable
  • System Parameters: Sample rates and filter constants

Technical Specifications

Performance

  • Update Rate: 20 Hz sensor sampling and display refresh
  • Response Time: ~5 seconds (90% settling due to EMA filtering)
  • Accuracy: ±0.01 bar PPO2 (post-calibration)
  • Resolution: 12-bit ADC (0.25mV resolution)

Contributing

Contributions welcome! Please read CONTRIBUTING.md for guidelines on:

  • Code style and standards
  • Testing requirements
  • Safety considerations for diving equipment

Parts

19
QtyValueFootprintReferences
210KResistor_SMD:R_0805_2012MetricR1, R2
210uFCapacitor_SMD:C_0805_2012MetricC4, C5
21uFCapacitor_SMD:C_0805_2012MetricC1, C2
2Conn_01x02_SocketConnector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_VerticalJ1, J2
11.5uHInductor_SMD:L_0402_1005MetricL1
1100KResistor_SMD:R_0805_2012MetricR4
110kResistor_SMD:R_0805_2012MetricR5
110uFCapacitor_SMD:C_0603_1608MetricC6
1200kResistor_SMD:R_0805_2012MetricR3
14.7uFCapacitor_SMD:C_0805_2012MetricC3
1BatteryConnector_JST:JST_XH_B2B-XH-A_1x02_P2.50mm_VerticalBT1
1Conn_01x04_SocketConnector_JST:JST_XH_B4B-XH-AM_1x04_P2.50mm_VerticalJ3
1ESP32-C3-DevKitM-1PCM_Espressif:ESP32-C3-DevKitM-1U1
1TPS63031DSKPackage_SON:WSON-10-1EP_2.5x2.5mm_P0.5mm_EP1.2x2mmU3
1~1_Ivans_Library:128x128_OLEDU2

Questions

How big is the Esp ppo v2 PCB?

It measures 60 × 40 mm and has 2 copper layers, 1.6 mm thick.

What parts does the Esp ppo v2 use?

19 parts, built around the ESP32-C3-DEVKITM-1 and TPS63031DSK. The full list of its parts is on this page, with links to each part's symbol and footprint where PCBKit's library has them.

Where can I download the Esp ppo v2 KiCad files?

From the iho77/ppo_v2 repository on GitHub, at the commit this page was made from: the board is pcb/esp_ppo_v2.kicad_pcb and its schematic pcb/esp_ppo_v2.kicad_sch. PCBKit opens the board in the browser, with nothing to install.

Can I use the Esp ppo v2 design in my own project?

Its repository states no licence, so its author keeps all rights: ask iho77 before reusing the design.

Similar boards

  • 4 layers94.1 × 152 mmDevelopment board panel, the printed circuit board in 3D

    Development board panel

    portapack-mayhem/mayhem-mdk

    PortaPack - Module Develoment Kit

    298 parts88GPL-3.0
  • 2 layers69.4 × 113 mmEpaper reader hw, the printed circuit board in 3D

    Epaper reader hw

    mathias4833/epaper-reader-hw

    An open-source e-paper reader

    126 parts75CERN-OHL-W-2.0
  • 4 layers41.4 × 108 mmM17 3310, the printed circuit board in 3D

    M17 3310

    M17-Project/M17_3310

    Mainboard replacement for Nokia 3310

    124 parts68
  • 4 layers54.7 × 78.5 mmDisplayModule PONSv71, the printed circuit board in 3D

    DisplayModule PONSv71

    MasaoC/GPS-TFT-Map_PONS

    鳥人間コンテストに特化したGNSS誘導システム。人力飛行機のパイロットが使いやすいことを目標にした航法装置です。ハードとソフトをオープンソースで開発しています。

    151 parts14MIT
  • 2 layers48.3 × 22.9 mmBuddhabox, the printed circuit board in 3D

    Buddhabox

    jonbro/aleatorium

    lua scriptable musicbox

    54 parts7
  • 2 layers106.5 × 66 mmTry, the printed circuit board in 3D

    Try

    Ahmed-YSY/FleetGuard

    IoT vehicle telematics for fleet & logistics — ESP32 + SIM7600G 4G/GPS tracker with fuel-theft detection, tamper/cargo security alarms, offline-resilient MQTT reporting, and OBD2 data over ESP-NOW.

    18 parts6
  • 2 layers22 × 15 mmTPS63031, the printed circuit board in 3D

    TPS63031

    cernohorsky/TPS63031

    High Efficiency Single Inductor Buck-Boost Converter With 1-A Switches

    10 parts6
  • 2 layers101.2 × 199.1 mmApollo, the printed circuit board in 3D

    Apollo

    Professor-plum/SAINTCON-BADGE-2026

    Electronic badge for SAINTCON2026

    80 parts5MIT