V2 Protocol Reference¶
Current Version
V2 is the active development branch (main). This is the recommended protocol for all new integrations.
V2 uses a unified device response protocol: all output — detection events and command responses — share a common JSON envelope.
For the legacy V1 protocol, see V1 API Reference.
Message Envelope¶
Every message is a single JSON object (JSONL format) with these envelope fields:
| Field | Type | Description |
|---|---|---|
type |
string | "response" (command reply) or "event" (detection) |
status |
string | "ok" or "error" |
sent_us |
uint64 | Unix timestamp in microseconds when the message was sent |
Success Response¶
{"type":"response","status":"ok","sent_us":1748012345678901,"version":"2.6.0"}
Error Response¶
{"type":"response","status":"error","sent_us":1748012345678901,"error_code":1,"error_message":"Invalid argument"}
Additional error fields:
| Field | Type | Description |
|---|---|---|
error_code |
uint8 | Error code (see table below) |
error_message |
string | Human-readable description |
Error Codes¶
| Code | Name | Description |
|---|---|---|
| 0 | SUCCESS |
Command executed successfully |
| 1 | INVALID_ARG |
Invalid command or argument format |
| 2 | OUT_OF_RANGE |
Argument value exceeds valid range |
| 3 | HARDWARE_ERROR |
SPI/I2C/sensor communication failure |
| 4 | NOT_SUPPORTED |
Feature not enabled in this build |
| 5 | UNKNOWN |
General error |
Detection Events (type="event")¶
Detection events are emitted each time a cosmic ray is detected. The adc, hit1, hit2, hit3 fields are always present. All other fields are conditional on build flags.
Always-Present Fields¶
| Field | Type | Description |
|---|---|---|
hit1 |
int | Detection count, channel 1 (GPIO12) |
hit2 |
int | Detection count, channel 2 (GPIO19) |
hit3 |
int | Detection count, channel 3 (GPIO27) |
adc |
int | Raw ADC value (0–4095); 0 if dependent channel has no detection |
Conditional Fields¶
| Field | Type | Build Flag | Description |
|---|---|---|---|
hit_type |
uint8 | ENABLE_HITTYPE=1 |
Bitmask of active channels (bit0=CH1, bit1=CH2, bit2=CH3) |
adc_raw |
int | ENABLE_ADCMV=1 |
Raw ADC value (0–4095) |
adc_mv |
uint16 | ENABLE_ADCMV=1 |
ADC converted to millivolts (0–3300) |
tmp_c |
float | ENABLE_BME280=1 |
Temperature (°C) |
atm_pa |
float | ENABLE_BME280=1 |
Atmospheric pressure (Pa) |
hmd_pct |
float | ENABLE_BME280=1 |
Relative humidity (%) |
uptime_ms |
uint32 | ENABLE_TIMESTAMP=1 |
Device uptime at detection (ms) |
timedelta_us |
uint64 | ENABLE_TIMESTAMP=1 |
Time since previous event (µs) |
detected_us |
uint64 | ENABLE_RTC=1 |
Detection moment unix timestamp (µs) |
gnss_latitude |
float | ENABLE_GNSS=1 |
Latitude (decimal degrees) |
gnss_longitude |
float | ENABLE_GNSS=1 |
Longitude (decimal degrees) |
gnss_altitude |
float | ENABLE_GNSS=1 |
Altitude above sea level (m) |
Example: Minimal Event (v2 defaults)¶
{"type":"event","status":"ok","sent_us":1748012345678901,"hit1":85,"hit2":72,"hit3":91,"adc":2048,"hit_type":7,"adc_mv":1960,"tmp_c":25.35,"atm_pa":101325.0,"hmd_pct":45.67,"uptime_ms":45000,"timedelta_us":1000000,"detected_us":1748012345678456}
Example: Full Event (all flags enabled)¶
{
"type": "event",
"status": "ok",
"sent_us": 1748012345678901,
"hit1": 85,
"hit2": 72,
"hit3": 91,
"adc": 2048,
"hit_type": 7,
"adc_raw": 2048,
"adc_mv": 1960,
"tmp_c": 25.35,
"atm_pa": 101325.0,
"hmd_pct": 45.67,
"uptime_ms": 45000,
"timedelta_us": 1000000,
"detected_us": 1748012345678456,
"gnss_latitude": 35.6762,
"gnss_longitude": 139.6503,
"gnss_altitude": 45.9
}
Build Flags¶
Feature Flags¶
| Flag | v2 Default | Purpose |
|---|---|---|
ENABLE_BME280 |
1 |
Environmental sensor (temperature, pressure, humidity) |
ENABLE_RTC |
1 |
Absolute unix timestamps (detected_us) |
ENABLE_TIMESTAMP |
1 |
Uptime and inter-event timing fields |
ENABLE_HITTYPE |
1 |
Channel activity bitmask field |
ENABLE_ADCMV |
1 |
ADC millivolt conversion |
ENABLE_GPIO_ABSTRACTION |
1 |
HAL API instead of direct register access |
ENABLE_QUEUE |
1 |
FreeRTOS event queue |
ENABLE_WIFI |
0 |
WiFi AP interface |
ENABLE_GNSS |
0 |
GNSS positioning |
Always-on in v2
ENABLE_DEVICE_RESPONSE and ENABLE_TEXT_COMMAND are hardcoded in v2 and cannot be disabled.
Customizing Build Flags¶
Create platformio.override.ini in the project root to override defaults without modifying tracked files:
; platformio.override.ini
[env:esp32dev-v2]
build_flags =
-D ENABLE_WIFI=1
-D ENABLE_GNSS=1
See Build Flags Overview for the full flag reference.
Architecture Overview¶
┌─────────────────────────────────────────┐
│ HOST (PC / DAQ system) │
│ • Sends text commands over USB serial │
│ • Receives JSONL events and responses │
└─────────────────────────────────────────┘
↕ UART 115200 baud
┌─────────────────────────────────────────┐
│ ESP32 (OSECHI) │
│ │
│ CommandQueue ──→ Handlers │
│ ↑ ↓ │
│ Serial Input device_response_t │
│ ↓ │
│ CosmicDetector → DetectionProcessor │
│ ↓ │
│ EventQueue │
│ ↓ │
│ Serial Output (JSONL) │
└─────────────────────────────────────────┘
Key Components¶
| Component | Role |
|---|---|
CosmicDetector |
Polls GPIO12/19/27 at configurable rate; returns hit counts |
DetectionProcessor |
Reads sensors on detection; builds and queues event |
CommandQueue |
Receives and dispatches text commands (10-item FIFO) |
EventQueue |
Buffers detection events for serial output (200-item FIFO) |
Command (singleton) |
Type-safe access to device configuration |
device_response_t |
Unified envelope for all output messages |
See Also¶
- Commands Reference — All available text commands and response fields
- Device Response Schema — JSON schema for validation
- Build Flags Overview — Full build flag reference
- V1 API Reference — Legacy protocol (maintenance only)