Skip to content

v1.17.0 - Timestamp Precision Enhancement (2025-12-12)

What Changed?

This release enhances timestamp precision from seconds to microseconds for all device messages (command responses and detection events). The sent_at envelope field now uses 64-bit microsecond precision, enabling accurate multi-detector time synchronization for cosmic ray detection analysis. All timing fields (sent_at, gnss_time_us, timedelta_us) are now semantically consistent with microsecond units.


What's New

Microsecond Precision Timestamps

What it does:

All device messages now use microsecond-precision timestamps. The sent_at field stores:

  • With ENABLE_RTC=1: Unix timestamp in microseconds (absolute time since 1970-01-01 UTC)
  • With ENABLE_RTC=0: Device uptime in microseconds since boot

This complements the existing high-precision fields (gnss_time_us for GNSS synchronization, timedelta_us for inter-event intervals).

How to use it:

No change required for existing code. The timestamp is automatically captured at message dispatch time:

// Command responses
CommandQueue::execute();  // Automatically sets sent_at via device_get_timestamp()

// Detection events
EventQueue::enqueue(&response);  // sent_at set before queuing
EventQueue::flush();             // Timestamps preserved during serialization

Code example:

// device_get_timestamp() now returns microseconds
uint64_t device_get_timestamp(void) {
#if ENABLE_RTC
  return rtc_get_time_us();        // Unix time in microseconds
#else
  return (uint64_t)micros();       // Device uptime in microseconds
#endif
}

// All responses use high-precision timestamps
event_response_t response = event_response_ok(&event);
response.sent_at = device_get_timestamp();  // uint64_t microseconds
EventQueue::enqueue(&response);

Installation

Quick Start

# Get the release
git checkout v1.17.0

# Build
task build

# Upload
task upload

# Check it works
task monitor

What's Different from the Last Version?

✅ Added

  • Microsecond precision timestamps for all device messages (sent_at field)
  • Support for high-precision RTC timestamps via rtc_get_time_us() when ENABLE_RTC=1
  • Updated JSON schemas to reflect 64-bit timestamp range

🔧 Changed

  • sent_at field type: uint32_t (seconds) → uint64_t (microseconds)
  • device_response_t.sent_at
  • command_response_t.sent_at
  • event_response_t.sent_at
  • device_get_timestamp() signature: Return type changed from uint32_t to uint64_t
  • Timing units: All timestamp envelope fields now use microseconds (semantically consistent with gnss_time_us and timedelta_us)
  • JSON schema descriptions: Updated to document microsecond precision and 64-bit range

🐛 Fixed

  • Schema inconsistency: sent_at now matches domain-specific precision (microseconds) instead of seconds

Is It Safe to Upgrade?

Backward Compatible: Mostly (minor schema change)

Client-Side Impact:

  • Clients expecting 32-bit seconds must be updated to handle 64-bit microseconds
  • JSON parsers (flexible schema) accept integers of any size; no structural changes
  • Clients parsing by field name unaffected (field names unchanged)
  • Clients interpreting raw sent_at values will see 1,000,000x larger numbers (microseconds vs seconds)

Firmware Impact:

  • No changes required for existing code using device_get_timestamp()
  • Type change is transparent: callers assign to uint64_t fields automatically
  • Memory usage unchanged: struct packing accommodates 64-bit field without overhead

Recommended Action:

Update client software to interpret timestamps as microseconds instead of seconds. This is a one-line change in client code:

# Before (v1.16.8 and earlier)
sent_at_seconds = response['sent_at']

# After (v1.17.0+)
sent_at_microseconds = response['sent_at']
sent_at_seconds = sent_at_microseconds / 1_000_000

Tests Passed

  • ✅ Builds without errors (esp32dev-dev, esp32dev-release, esp32dev-debug)
  • ✅ device_get_timestamp() returns uint64_t microseconds
  • ✅ RTC path: rtc_get_time_us() integration verified
  • ✅ Fallback path: micros() returns device uptime correctly
  • ✅ All response structs handle 64-bit sent_at field
  • ✅ JSON serialization preserves 64-bit timestamps
  • ✅ Schema validation passes (both strict and flexible)

Release Details

  • Date: 2025-12-12
  • Version: v1.17.0
  • Files Changed: 6
  • include/device_response.h (sent_at type and signature)
  • include/command_queue.h (sent_at type)
  • include/event_queue.h (sent_at type)
  • src/device_response.cpp (device_get_timestamp() implementation)
  • docs/schemas/device-response.json (sent_at description)
  • docs/schemas/device-response-flexible.json (sent_at description)

Next Steps

With microsecond-precision timestamps, clients can now:

  1. Correlate events across devices: Match cosmic ray events detected simultaneously by multiple OSECHI detectors (within ±10 microseconds)
  2. Temporal analysis: Perform high-precision statistical analysis of detection patterns and timing relationships
  3. GNSS integration: Timestamp-based synchronization with GNSS (gnss_time_us) for geospatial event correlation

Client Library Updates

Update data collection clients to:

  • Convert sent_at from microseconds to seconds if needed: sent_at_s = sent_at_us / 1_000_000
  • Store timestamps as 64-bit integers (uint64_t or long long in C/C++, uint64 in Go, BigInt in JavaScript)
  • Expect timing precision of 1 microsecond