Intellidwell Logo Docs
Intellidwell โ†—

โšก Embedded Firmware Architecture

IntelliKeep firmware spans two radically different operational domains: the low-power, event-driven sleep loop on the ESP32-C3 tag, and the always-on, multi-tasking FreeRTOS gateway stack on the ESP32-S3 base station hub.

1. BLE Tag Firmware Lifecycle

Early prototype iterations utilized a connection-oriented GATT architecture where the tag advertised, waited for a base station connection handshake, and exchanged cryptographic acknowledgments. While technically functional, maintaining connections extended tag awake times to 2.5โ€“4.0 seconds per wake cycle, draining the coin-cell battery in weeks.

๐Ÿ’ก Shift to Pure Beacon Architecture

The final production firmware transitioned to an optimized non-connectable, broadcast-only beacon model. The tag simply wakes, transmits a short burst of non-connectable undirected advertisements carrying vital telemetry, and returns to deep sleep in under 300 ms. Presence inference and missing evaluation are delegated entirely to the base station and cloud backend.

Tag Execution Timeline (270 ms Wake Cycle)

1
Wakeup & Hardware Initialization (~70 ms)

MCU wakes from RTC timer (5-minute cadence), optical comparator tamper interrupt (GPIO pin change), or NFC field detection. The RISC-V core configures system clocks and restores NVS configuration.

2
Cached Battery Measurement (~50 ms)

To avoid spending high battery power on ADC sampling every 5 minutes, battery voltage is sampled only every 12th cycle (once per hour) using the switched MOSFET divider and cached in RTC fast memory.

3
BLE Broadcast Window (~150 ms)

The radio synthesizer boots and transmits the 5-byte manufacturer data payload (Company ID 0x1337) across standard BLE advertising channels 37, 38, and 39 at 20 ms intervals.

4
Deep Sleep Re-entry (< 5 ms)

Peripherals are powered down, RF synthesizer disabled, RTC timer re-armed for 300 seconds, and the ESP32-C3 enters deep sleep (< 5 ยตA draw).

2. Base Station Hub Firmware (ESP32-S3)

The base station runs an asynchronous multi-threaded software stack on ESP-IDF / FreeRTOS. It is structured into modular subsystems located under components/:

ble_scanner

Continuous active NimBLE discovery engine. Filters incoming advertising packets by company identifier 0x1337.

whitelist

Manages local NVS registered tag table. Updates runtime cache of RSSI, battery, tamper status, and last-seen epoch.

mqtt_bridge

Formats and publishes real-time JSON telemetry payloads to local brokers on topic intellikeep/base/<MAC>.

server_bridge

HTTPS client handling cloud self-registration, 15-second heartbeat synchronization, observation posting, and alert dispatch.

portal

Captive onboarding SoftAP (IK-Base-Setup) and DNS intercept engine for initial headless network provisioning.

status_server

Embedded HTTP server hosting a local browser-based device dashboard and administrative JSON REST endpoints.

FreeRTOS Task Decomposition

To ensure real-time responsiveness without packet loss, responsibilities are split across independent FreeRTOS priority tasks:

Task / Timer Name Execution Cadence Stack / Priority Functional Description
ble_scanner Continuous (100% duty) 4 KB / Priority 5 Continuous active scanning with itvl = window = 0x0130 (~190 ms). Intercepts 0x1337 beacon packets with zero inter-window gap.
missing_monitor Periodic (Every 30 s) 3 KB / Priority 3 Scans local whitelist table. If a tag's last-seen timestamp exceeds the 11-minute grace window, flags state as Missing and dispatches alert.
server_hb Periodic (Every 15 s) 8 KB / Priority 3 Executes HTTPS GET to /api/v1/base/info. Synchronizes base name, updates tag whitelist, and checks remote action flags (factory reset, reboot).
wifi_monitor Periodic (Every 30 s) 3 KB / Priority 2 Monitors station connection state. Implements exponential backoff on disconnects and triggers SoftAP fallback if network remains unavailable.
dns_cap Event-driven (SoftAP) 2 KB / Priority 1 Captive portal DNS server listening on UDP port 53. Redirects all HTTP requests to the base station setup IP (192.168.4.1).

Non-Volatile Storage (NVS) Schema

The base station functions as a stateful gateway. System configuration, Wi-Fi credentials, API keys, and registered tag lists are persisted in flash NVS partitions so the hub recovers completely after power loss without requiring cloud re-provisioning:

Namespace Key Name(s) Data Type Contents / Description
ikcfg wifi_ssid, wifi_pass String Target 2.4 GHz Wi-Fi network SSID and WPA2/WPA3 passphrase.
ikcfg app_user, app_upass String Owner username and bcrypt password hash for local web UI login.
ikcfg base_name String Human-readable location identifier (e.g., "Main Cabin Living Room").
ikcfg mqtt_uri, mqtt_user, mqtt_pass String Optional local MQTT broker URI (e.g., mqtt://192.168.1.100:1883) and credentials.
ikcfg srv_key String Unique 32-character base station cloud API key (X-API-Key).
ikwhite m00 .. m31 String BLE MAC address slots for up to 32 enrolled tags (e.g., "AA:BB:CC:DD:EE:FF").
ikwhite n00 .. n31 String Friendly asset name corresponding to each MAC slot (e.g., "Sony Bravia 65").
iktoken token String Short-lived cryptographic enrollment token for pairing verification.

SoftAP Onboarding Portal

When booting without valid network credentials, the base station initializes a 802.11 b/g/n Access Point named IK-Base-Setup on channel 1.

Captive DNS Intercept
// Intercept all domain resolutions and return 192.168.4.1
static void dns_recv_cb(void *arg, struct udp_pcb *upcb, struct pbuf *p,
                        const ip_addr_t *addr, u16_t port) {
    dns_header_t *dns_hdr = (dns_header_t *)p->payload;
    dns_hdr->flags = htons(0x8180); // Response, No Error
    // Append Answer record pointing to 192.168.4.1
    udp_sendto(upcb, reply_pbuf, addr, port);
}

Operating systems (iOS, Android, Windows, macOS) detect captive state and open the configuration page directly. The user selects an existing Wi-Fi network, enters the network password, assigns the base station name, and submits. The hub records the parameters to ikcfg in NVS and immediately restarts in Station mode.

Embedded Local Status UI

Even if internet access is interrupted or the cloud backend is unavailable, the base station provides an independent local management interface served directly from the ESP32 on port 80:

  • Real-Time Tag Table: Live RSSI, battery percentages, tamper indicators, and seconds since last check-in.
  • Manual Tag Registration: Form to manually whitelist new tag MAC addresses and friendly names.
  • Transport Configuration: Update local MQTT broker parameters and cloud server URL.
  • Factory Reset & Diagnostics: Clear NVS tables, trigger re-provisioning mode, and download diagnostic serial logs.