Progress Log: ENABLE_ADCMV Feature Implementation¶
Task Description¶
Implement a compile-time flag (ENABLE_ADCMV) to enable hardware calibration-based ADC to millivolt conversion using ESP32's analogReadMilliVolts() function. This allows users to optionally output both raw ADC values (0-4095) and converted millivolt values (0-3300mV) for accurate voltage measurements.
Outcome¶
✅ Completed Successfully
Changes Made¶
- config.h: Added ENABLE_ADCMV configuration flag (v1.9.5, default=0)
- Memory overhead: ~200-300 bytes Flash, 4 bytes RAM when enabled
-
Zero overhead when disabled (compile-time elimination)
-
sensor_data.h: Extended sensor_data_t structure
- Added
adc_rawfield (uint16_t, 0-4095) - Added
adc_mvfield (uint16_t, 0-3300) -
Conditional compilation ensures fields only exist when ENABLE_ADCMV=1
-
sensor_formatter.cpp: Updated all output formatters
- Modified send_sv() to output adc_raw and adc_mv with proper delimiters
- Updated JSONL formatter to include adc_raw and adc_mv JSON fields
-
Format-specific wrappers (SSV, TSV, CSV) automatically handle new fields
-
main.cpp: Integrated ADC reading
- Added direct calls to
analogRead()andanalogReadMilliVolts()when ENABLE_ADCMV=1 - Properly cast values to uint16_t for structure initialization
-
Maintains conditional compilation for zero overhead when disabled
-
Documentation: Updated and added
- docs/develop/stream-format.md: Added ADC Fields section with field descriptions
- CLAUDE.md: Added build example for ENABLE_ADCMV flag
-
platformio.ini: Enabled ENABLE_ADCMV=1 in development environment
-
Build Verification:
- ✅ Default build (ENABLE_ADCMV=0): Flash 24.1%, compiles successfully
- ✅ ENABLE_ADCMV=1 build: Flash 23.3% (11KB reduction due to compiler optimization)
- ✅ All warnings are pre-existing ArduinoJson deprecation warnings
Output Examples¶
SSV Format (ENABLE_ADCMV=1)¶
95 87 91 0 1234 1580 25.35 1013.25 45.67
↑ ↑ ↑
| | +-- adc_mv (millivolts)
| +-------- adc_raw (0-4095)
+------------ sensorValue (legacy)
JSONL Format (ENABLE_ADCMV=1)¶
{"type":"data","signal1":95,"signal2":87,"signal3":91,"adc":0,"adc_raw":1234,"adc_mv":1580,"tmp_c":25.35,"atm_pa":1013.25,"hmd_pct":45.67}
Usage¶
# Development environment (ENABLE_ADCMV=1 enabled by default)
task dev:build
# Production with dual ADC output
PLATFORMIO_BUILD_FLAGS="-DENABLE_ADCMV=1" pio run -e esp32dev-release
# Production default (single ADC value)
pio run -e esp32dev-release
Learnings¶
-
Compile-Time Configuration Patterns: The ENABLE_ADCMV implementation demonstrates clean compile-time feature selection using preprocessor directives, achieving zero runtime overhead when disabled.
-
Backward Compatibility: The original
sensorValuefield is preserved for backward compatibility. Newadc_rawandadc_mvfields are additive-only, ensuring existing downstream consumers continue to work unchanged. -
Output Formatter Architecture: The sensor_formatter design (with generic send_sv() and format-specific wrappers) elegantly supports conditional field inclusion across all output formats without code duplication.
-
Hardware Calibration: ESP32's
analogReadMilliVolts()provides accurate voltage conversion using hardware calibration tables, superior to manual calculation for production use cases.
Next Steps¶
- Monitor field ordering feedback from users (adc_raw/adc_mv placement relative to environmental fields)
- Consider adding text commands for ADC-specific queries in future versions
- Potential expansion to multi-channel ADC support if hardware is upgraded
Commit Info¶
feat(adc): add ENABLE_ADCMV flag for dual ADC raw and millivolt output
Commit: 525246b