🚧 Bring-up in progress — not yet hardware-validated in the field

The sensor that lives
inside the hive.

HiveInside is a stand-alone, battery-powered in-hive sensor on a board the size of a thumbnail. It measures comb vibration, hive acoustics, temperature and humidity, reduces each to FFT bands on the device, and broadcasts the result as a BLE beacon — no cables into the hive, no pairing window, no wake-sync schedule.

Part of the open beehive-monitoring ecosystem. A HiveHub collector picks HiveInside up in the passive BLE scan it already runs and forwards the readings to your own backend, alongside weight and the rest of the hive.

Why a separate device?

Because the one measurement that predicts swarming can't be taken from outside the hive.

📳

Vibration, not just sound

Per the literature (Ramsey et al. 2020, Sci. Rep.), the frame-mounted accelerometer is the only reliable way to predict swarming up to ~30 days ahead. The critical signature sits around 20 Hz — a vibration in the comb that a microphone simply cannot capture.

🔌

No cables into the hive

A wired in-hive accelerometer means a cable through the wall of every box, and a connector that propolis and moisture will eventually find. HiveInside puts the accelerometer, mic and climate sensor on one small wireless board that just sits inside.

🔋

Made to be sealed and forgotten

It runs from a small LiPo, switches its sensor rail off between measurements, and takes firmware updates over the air — so a node can be closed into an enclosure and left there.

Feature set

Everything below is implemented in the firmware today. What is still open is field validation on production hardware — see the status note at the bottom.

📡

BLE beacon transport

The complete measurement — climate, vibration and acoustic FFT bands, battery — rides in a single 29-byte manufacturer-data advertisement, repeated every second. Reading it needs no connection, no pairing, no wake-sync. Any number of receivers can listen at once, and it costs the sensor nothing extra.

📳

Vibration FFT bands

~1024 samples at ~400 Hz from the on-board 6-axis IMU, gravity removed, reduced to the swarm / fanning / activity bands — including the ~20 Hz pre-swarm signature.

🔊

Acoustic FFT bands

The on-board PDM microphone is reduced to five bands from sub-bass to 3 kHz, covering hum, piping and stress — plus RMS and peak level in dBFS.

🌡️

Climate & battery

An external SHT40 gives temperature and humidity at 0.1 °C / 0.1 %RH resolution; the on-board nPM1300 fuel gauge reports battery voltage and state of charge with every measurement.

🔋

Ultra-low power

Between measurements the nRF54 idles with only the ~1 s advertiser running. The IMU + microphone rail is switched off for about 98.9 % of each five-minute cycle, and a dedicated low-power build profile drops the console UART and the status LED for deployment.

📥

Firmware over BLE (OTA)

MCUboot dual-slot updates: a small GATT service streams the signed image into the secondary slot, verifies size and CRC-32, then test-swaps with automatic rollback. A dropped or corrupted transfer always leaves the node on its old image.

🐕

Hardware watchdog

A sealed node has no console and nobody watching it. wdt31 is armed with a 60 s timeout and fed from the main loop, so a driver that wedges — a stuck I²C transfer, a PDM read that never returns — resets the node instead of quietly re-advertising a stale measurement forever.

🧩

Ecosystem-shared bands

The FFT bands are exactly the ones HiveHub and HiveScale use, so a value means the same thing wherever it is read — and a HiveInside reading can be compared to a wired sensor's directly.

🔎

Auto-detecting sensors

The accelerometer probe identifies the chip by WHO_AM_I, so an external LIS3DH / LIS2DH12 breakout at 0x18/0x19 runs the same pipeline as the on-board IMU — a bench setup behaves like the real thing.

🩹

Graceful partial hardware

Each sensor group carries its own validity flag. A missing or failed sensor prints n/a and clears its flag rather than sending zeroes, so the backend never mistakes a dead sensor for a real reading.

🏠

Home Assistant

Surface the data through HiveHub, or decode the advertisement locally with an ESPHome esp32_ble_tracker or a Bluetooth proxy — the frame layout is fully documented.

🛠️

Zephyr + sysbuild

One toolchain for everything: west --sysbuild builds MCUboot and the signed application together, and a checked-in west.yml pins the Zephyr revision so the workspace is reproducible. CI builds both profiles on every push.

Hardware

One module, one external sensor, one battery. The Seeed XIAO nRF54LM20A Sense folds the IMU, microphone, power management, charging and USB-C onto the board itself, so the whole node is a module, an SHT40 on four wires, and a LiPo.

FunctionPartInterfaceWhere
3-axis vibration (swarm prediction, ~20 Hz)LSM6DS3TR-C 6-axis IMUI²C 0x6Aon-board
Acoustics (hum, piping, stress)MSM261DGT006 PDM microphonePDMon-board
Temperature + humiditySHT40I²C 0x44external
Battery voltage + state of chargenPM1300 PMIC fuel gaugeon-board
Charging + USB-CnPM1300 PMICUSB-Con-board
Flashing + serial consoleSAMD11 CMSIS-DAP debuggerUSB-Con-board

🔌 Wiring the SHT40

Four wires to the XIAO's I²C header: VIN → 3V3, GND → GND, SDA → D4, SCL → D5. That is the entire external wiring. The on-board IMU sits on the internal i2c30 bus and needs nothing.

🔋 Battery

A single-cell 500 mAh LiPo on the XIAO's battery connector. The nPM1300 handles charging over USB-C and reports the fuel gauge with every measurement.

📦 Enclosure

A 3D-printable enclosure sized for the XIAO Sense, the SHT40 and the 500 mAh cell lives in enclosure/.

💾 Flash layout

The board's 2 MiB RRAM is partitioned for MCUboot: a 64 KiB bootloader plus two matching 449 KiB application slots, which is what makes the dual-slot OTA with rollback possible.

🖥️ One cable for everything

The on-board SAMD11 debugger means no external probe: west flash and the 115200 8N1 serial console both ride the same USB-C cable.

🧪 Bench variant

No Sense module to hand? Wire an external LIS3DH / LIS2DH12 to the same D4/D5 pads — the firmware detects it and runs the identical vibration pipeline.

Full connection reference in docs/wiring.md.

What it broadcasts

Every five minutes (by default) the node reads all four sensors, runs the FFTs on-device, and updates one advertisement. The Bluetooth controller then repeats that advertisement every second while the CPU sleeps — so a receiver's scan never has to be synchronised with anything.

📳

Vibration bands (mg, gravity removed)

  • Swarm — the pre-swarm signature8–30 Hz
  • Fanning — ventilation effort30–100 Hz
  • Activity — general colony motion100–200 Hz

Plus acceleration RMS and peak.

🔊

Acoustic bands (dBFS)

  • Sub-bass50–150 Hz
  • Hum — the resting colony150–300 Hz
  • Piping — queen signalling300–550 Hz
  • Stress550–1500 Hz
  • High1500–3000 Hz

Plus microphone RMS and peak.

📦 The 29-byte measurement frame (for anyone writing their own decoder)

Manufacturer-specific data, company ID 0x02E5, magic 0x48 ('H'), format version 2. All multi-byte fields are little-endian and offsets include the two company-ID bytes. Each group is only meaningful when its validity bit is set — a failed sensor clears the bit rather than sending zeroes.

OffsetFieldEncodingValid when
0..1Company ID0x02E5always
2Magic0x48 (H)always
3Format version2always
4Validity flagsbit 0 climate, 1 accel, 2 mic, 3 batteryalways
5..6Temperatureint16, 0.1 °C/LSBclimate
7..8Humidityuint16, 0.1 %RH/LSBclimate
9..10Battery voltageuint16, 1 mV/LSBbattery
11Battery chargeuint8, % (0–100)battery
12..13Acceleration RMSuint16, 0.1 mg/LSBaccel
14..19Vibration bands — swarm, fanning, activityuint16, 0.1 mg/LSBaccel
20Microphone RMSint8, 1 dBFS/LSBmic
21..25Acoustic bands — sub-bass, hum, piping, stress, highint8, 1 dBFS/LSBmic
26..27Acceleration peak (v2)uint16, 0.1 mg/LSBaccel
28Microphone peak (v2)int8, 1 dBFS/LSBmic

Version 2 keeps every version-1 field at the same offset, so an older decoder that only understands the 26-byte prefix safely ignores the two trailing peaks and keeps working. An active scan additionally receives a compact identity record (board ID and firmware version) and the device name HiveInside in the scan response — the measurement advertisement itself is unchanged.

Full frame documentation →

What it looks like on the console

---- HiveInside readout ----
  climate : 24.31 C   47.8 %RH
  accel   : x=-3.2 y=1.8 z=1004.6 mg  |a|=1004.6 mg
  accel AC: rms=2.4 peak=9.1 mg  (1024@416Hz)
  vib FFT : swarm=0.42 fan=0.18 act=0.09 mg
  sound   : rms=-61.4 dBFS  peak=-42.1 dBFS  (8000 frames)
  ac FFT  : sub=-58.2 hum=-49.7 pipe=-63.1 stress=-71.4 hi=-88.0 dBFS
  battery : 4.011 V  ~78%
----------------------------
[BLE] measurement advertised (flags=0x0f)

Build & flash it

The firmware is a Zephyr application built with west and sysbuild — the only supported build path. Everything below runs over the single USB-C cable; no external debug probe is needed.

1

Set up a west workspace

The manifest pins the Zephyr revision the firmware is built against, so the workspace is reproducible.

west init -m https://github.com/MacNite/HiveInside hiveinside-workspace
cd hiveinside-workspace && west update
2

Build the bootable image

--sysbuild is not optional: the firmware boots through MCUboot, so a bootable device needs the bootloader and the signed application — and only a sysbuild build produces both (plus the OTA payload).

west build --sysbuild -b xiao_nrf54lm20a/nrf54lm20a/cpuapp \
  -d debug hiveinside/firmware-nrf54lm20a
⚠️ Never flash a build made without --sysbuild. With MCUboot enabled the application links at the slot-0 offset, so flashing it alone leaves nothing at 0x0: the device goes silent — no serial, no BLE.
3

Flash and watch it

west flash programs MCUboot and the signed app through the on-board debugger. The console runs at 115200 8N1 on the same cable.

west flash -d debug
picocom -b 115200 /dev/ttyACM0            # Linux
picocom -b 115200 /dev/cu.usbmodemXXXX    # macOS

Prefer an IDE? The nRF Connect extension for VS Code / VSCodium is documented in docs/vscode-build.md.

4

Build the deployment image

The default build keeps the UART console, floating-point printk() and the measurement LED for bring-up. For a sealed, battery-powered node, layer the low-power profile on top — it drops all three and stops the sensor island being held powered from reset.

west build --sysbuild -b xiao_nrf54lm20a/nrf54lm20a/cpuapp \
  -d lowpower hiveinside/firmware-nrf54lm20a -- \
  -DEXTRA_CONF_FILE=low-power.conf \
  -DEXTRA_DTC_OVERLAY_FILE=low-power.overlay

BLE advertising and OTA are unchanged by the profile. See docs/low-power.md for the full audit and the measurement method.

5

Put it in a hive

Print the enclosure, seal the node in with the SHT40 and battery, and pair it from HiveHub by its identity address as HiveInside (nRF54LM20A) — beacon. From then on updates go over the air.

Each build writes a version-stamped copy of the signed image, e.g. hiveinside-nrf54lm20a-v0.4.5-lowpower.signed.bin — upload that file rather than zephyr.signed.bin, so a console-enabled bring-up image can never be mistaken for a deployment one. The HiveHub dashboard reads the target and version straight out of the filename.

🐝 Set up a HiveHub to collect it

Where it fits

HiveInside is a sensor, not a system — it has no Wi-Fi and talks to nobody directly. A HiveHub collector is what turns its broadcasts into stored, charted history.

🐝 HiveHub — the hub of the ecosystem

HiveHub is the ESP32 data collector for up to 16 hives: weight, temperature, humidity, sound, vibration and power state, sent to your own self-hosted FastAPI + PostgreSQL backend with a built-in dashboard. It already runs a shared passive BLE scan, so picking up a HiveInside node costs it nothing extra — pair it and the readings appear alongside the rest of the hive.

Open the HiveHub site →
📳 HiveInside ──BLE beacon──▶ 🐝 HiveHub ──HTTPS──▶ 🗄️ Your backend ──▶ 📊 Dashboard / HivePal

⚖️ HiveScale

Weight and external sensing — the other half of the ecosystem, and the relay that streams an OTA image down to HiveInside over BLE.

GitHub →

🐝 BeeCounter

Entrance traffic counting: bees in and out, bridged into the same backend.

🏠 Home Assistant

Take the data from HiveHub, or decode the advertisement locally with ESPHome or a Bluetooth proxy.

docs/homeassistant.md →

Dig deeper

📻 Firmware & frame

The readout format, the full BLE frame layout, the watchdog, and the roadmap.

firmware-nrf54lm20a/README.md →

🔌 Wiring

SHT40, battery and the optional external accelerometer.

docs/wiring.md →

⚡ Flashing

Flashing details, the external-probe alternative, and what to do when a device is silent.

docs/flashing.md →

🔋 Low power

The code-and-hardware audit, the deployment build profile, and how to measure the result properly.

docs/low-power.md →

📥 OTA over BLE

The streaming relay, the partition layout, and the release artifact naming.

docs/ota-over-ble.md →

🧑‍💻 Building in VS Code

The nRF Connect extension setup with the debug and lowpower configurations.

docs/vscode-build.md →

🚧 Status: bring-up in progress; not yet hardware-validated in the field. The firmware reads all four sensors, runs the vibration and acoustic FFTs, prints the readout, broadcasts the HiveHub-compatible beacon, and accepts firmware over BLE on top of MCUboot. What is still outstanding is a season in a real hive — battery figures on this page are planning estimates from component data, not measurements of an assembled board.