No description
Find a file
2025-10-14 15:55:32 +02:00
docs add calibration hints 2025-10-14 15:55:32 +02:00
include add calibration hints 2025-10-14 15:55:32 +02:00
lib initial commit 2025-10-13 15:20:57 +02:00
src add calibration hints 2025-10-14 15:55:32 +02:00
test initial commit 2025-10-13 15:20:57 +02:00
.gitignore initial commit 2025-10-13 15:20:57 +02:00
.pre-commit-config.yaml initial commit 2025-10-13 15:20:57 +02:00
.python-version initial commit 2025-10-13 15:20:57 +02:00
platformio.ini initial commit 2025-10-13 15:20:57 +02:00
pyproject.toml initial commit 2025-10-13 15:20:57 +02:00
README.md initial commit 2025-10-13 15:20:57 +02:00
uv.lock initial commit 2025-10-13 15:20:57 +02:00

ESP32 Voltage Measurement

Serial voltage measurement system using ESP32 with JSON-based communication protocol.

Features

  • 🔌 JSON-based serial communication protocol
  • 📊 Voltage measurement via ADC (0-30V with voltage divider)
  • 🔄 Request-response architecture (no streaming)
  • 📝 Auto-generated protocol documentation
  • Pre-commit hooks for code quality
  • 📈 Multi-sample averaging for stability
  • 💾 Flash-based configuration storage
  • 🔧 Configurable ADC parameters

Hardware

  • Board: AZ-Delivery DevKit v4 (ESP32)
  • Communication: Serial over USB (115200 baud)
  • ADC Pin: GPIO34 (ADC1_CH6)
  • Voltage Range: 0-30V (requires voltage divider: R1=82kΩ, R2=10kΩ)

For detailed hardware setup and voltage divider circuit, see docs/HARDWARE.md.

Protocol

The device uses a JSON-based protocol over serial. See docs/PROTOCOL.md for complete documentation.

Quick Example

import serial
import json

def read_json_response(ser):
    """Read and parse only valid JSON lines (filters out bootloader messages)."""
    while True:
        line = ser.readline().decode().strip()
        if not line:
            continue
        try:
            return json.loads(line)
        except json.JSONDecodeError:
            # Ignore bootloader and other non-JSON output
            continue

ser = serial.Serial('/dev/ttyUSB0', 115200, timeout=2)

# Wait for ready message (automatically skips bootloader output)
ready = read_json_response(ser)
print(ready)
# {"type": "ready", "status": "ok", "version": "1.0",
#  "max_voltage": 25.74, "config": {...}}

# Request voltage reading
ser.write(b'{"cmd": "read"}\n')
response = read_json_response(ser)
print(response)  # {"type": "voltage", "value": 23.47, "unit": "V", "status": "ok"}

# Get current configuration
ser.write(b'{"cmd": "config", "action": "get"}\n')
config = read_json_response(ser)
print(config)  # {"type": "config", "config": {...}, "status": "ok"}

# Set voltage divider resistors (persists to flash)
ser.write(b'{"cmd": "config", "action": "set", "param": "r1_ohms", "value": 82000}\n')
response = read_json_response(ser)
print(response)  # Returns updated config with new R1 value

Setup

PlatformIO (ESP32)

# Build and upload to ESP32
pio run --target upload

# Monitor serial output
pio device monitor

Python (Documentation Only)

Python and uv are only used for documentation generation, not for the main firmware.

# Install dependencies
uv sync

# Install pre-commit hooks
uv run pre-commit install

# Generate protocol documentation
uv run python docs/generate_protocol_docs.py

Development

Pre-commit Hooks

This project uses pre-commit hooks to maintain code quality:

  • Ruff - Python linting and formatting
  • Protocol docs - Auto-generates docs/PROTOCOL.md when protocol.yaml changes
  • Standard checks - Trailing whitespace, file endings, YAML/JSON validation

Install hooks:

uv run pre-commit install

Run manually:

uv run pre-commit run --all-files

Protocol Updates

When updating the communication protocol:

  1. Edit docs/protocol.yaml with new commands/fields
  2. Update src/main.cpp with implementation
  3. Run uv run python docs/generate_protocol_docs.py (or let pre-commit do it)
  4. Commit changes - the hook will ensure docs are up to date

Project Structure

esp32 Voltage Measurement/
├── src/
│   └── main.cpp                   # ESP32 firmware (C++)
├── include/
│   └── config.h                   # Configuration struct and constants
├── lib/                           # Libraries
├── test/                          # Unit tests
├── docs/
│   ├── protocol.yaml              # Protocol definition (source of truth)
│   ├── generate_protocol_docs.py  # Documentation generator (Python)
│   ├── PROTOCOL.md                # Auto-generated protocol documentation
│   ├── HARDWARE.md                # Hardware setup guide
│   └── CONFIGURATION.md           # Configuration system guide
├── platformio.ini                 # PlatformIO configuration
├── pyproject.toml                 # Python/uv configuration (docs only)
└── .pre-commit-config.yaml        # Pre-commit hooks

Future Enhancements

  • Real ADC voltage measurement
  • Multi-sample averaging
  • Flash-based configuration storage
  • Runtime configuration commands (set samples, divider ratio, etc.)
  • Voltage calibration command
  • Multiple channel support
  • Advanced filtering (moving average, median filter)
  • Continuous monitoring mode

License

This project is licensed under the GNU General Public License v3.0 or later (GPL-3.0-or-later).

See the GNU GPL v3 license text for details.