Releases: MacNite/HiveInside
Release list
HiveInside V0.5 — flash it, don't build it 🐝
HiveInside is a stand-alone, battery-powered in-hive environmental and
acoustic sensor. It sits inside the hive, measures climate, vibration and
sound, and broadcasts the result as a BLE beacon that a
HiveHub / HiveScale picks up with a passive
scan and forwards to the backend.
V0.1 could only be built. This release ships the firmware itself: prebuilt,
signed images for both build profiles, a factory image you can flash over the
board's USB-C cable with one command, and the tools to do it — no Zephyr
toolchain, no west workspace, no external probe. A node that is already running
takes the same firmware over the air through HiveHub.
🔥 Flash it without building it
Which file do I need?
| File | What it is | Flash it with |
|---|---|---|
hiveinside-nrf54lm20a-v0.5.0-<variant>-factory.hex |
MCUboot at 0x0 plus the signed application in slot 0 — a complete, bootable device image |
SWD over USB-C |
hiveinside-nrf54lm20a-v0.5.0-<variant>.signed.bin |
The signed application alone — the BLE OTA payload | HiveHub, over the air |
…and pick the right variant:
lowpower— the deployment profile: no console, no LED, minimum idle
current. This is the one that goes into a hive.bringup— console on at 115200 8N1, for bench work and wiring up an
SHT40.
Both advertise identically, so a bringup image in a sealed hive looks perfectly
healthy from HiveHub and simply drains the battery. Check the suffix before you
flash.
⚠️ Never flash a.signed.binover SWD. It links behind an MCUboot header
at the slot-0 offset, so on its own it leaves nothing at0x0: the CPU faults
beforemain()and the node goes completely silent — no console, no BLE. The
flashing scripts refuse it for you.
A fresh board, over USB-C
Download hiveinside-flash-tools.zip and the factory hex for your variant, unzip,
and run:
./flash.sh hiveinside-nrf54lm20a-v0.5.0-lowpower-factory.hex.\flash.ps1 -Image hiveinside-nrf54lm20a-v0.5.0-lowpower-factory.hexOpenOCD on PATH is the only prerequisite. The XIAO's on-board SAMD11 CMSIS-DAP
debugger does the rest over the same cable that powers it — no external probe.
The scripts run the same OpenOCD sequence west flash --verify runs, read the
image back to verify it, and correct the board's RRAM loader first: upstream
leaves the 16-byte write buffer enabled and never commits it, so the tail of any
image that is not 16-byte aligned never reaches RRAM and MCUboot then rejects
slot 0 — silently, on a dark device. That one-character difference is the
difference between a working node and an unexplained brick.
Full instructions, the manual OpenOCD command, and the troubleshooting path:
docs/flashing.md.
A node that is already running, over the air
Upload the .signed.bin in HiveHub's firmware form. It reads the target and the
version straight out of the file name, streams the image into the node's
secondary slot, and MCUboot test-swaps it with automatic rollback. Nothing is
committed until size and CRC-32 verify, so a dropped or corrupted transfer always
leaves the node on its old firmware.
See docs/ota-over-ble.md.
Verify what you downloaded
sha256sum -c SHA256SUMS # shasum -a 256 -c SHA256SUMS on macOSmanifest.txt lists each payload's byte size and CRC-32 — the two values the OTA
BEGIN frame carries — plus the commit, the pinned Zephyr revision, and the
build that produced them. west-manifest-frozen.yml and build-info-<variant>.zip
(both images' Kconfig, the domain layout, the devicetree) are attached so anyone
can rebuild these exact images.
🔑 On authenticity. These images are signed with MCUboot's development
key, which is public. That gives image formatting, not proof of origin: a
device running them accepts any image signed with the same public key. Check
the SHA-256 to know you got the file we built, and for a deployment you control,
provision your own signing key and build your own images — see the
production checklist.
🏷️ Per-node names (firmware 0.4.7 → 0.5.0)
Every node used to advertise the bare name HiveInside. In a yard running more
than one, a scanner listed several identical entries and the only thing telling
them apart was the raw BLE address — which is not written on the enclosure and
not something anybody has memorised.
Each node now advertises as HiveInside-8A3F: the last two bytes of its own
BLE identity address, in hex. Several nodes in one apiary are distinguishable in
any scanner app and in HiveHub's dashboard with no provisioning step at all,
and because the suffix is derived from the address rather than stored, it
survives a factory erase and every firmware update. The GAP Device Name
characteristic is kept in step with the scan response, so a node never calls
itself one thing while advertising another.
The measurement advertisement is untouched — still the same 29-byte
manufacturer-data frame, format version 2, at the same offsets. Only the scan
response carries the name, so existing HiveHub decoders keep working unchanged.
Two build-time asserts hold the sizing against the 31-byte legacy advertising
limit, so the name can never silently push the identity record off the air.
📦 Also in this release
- The 3D-printable enclosure — bottom and top STL, the STEP and Fusion
source, sized for the XIAO Sense, the SHT40 and a 500 mAh LiPo. Attached as
hiveinside-enclosure.zip, so printing it needs no repository clone. - A project website — macnite.github.io/HiveInside:
the feature set, the hardware, and the full BLE frame layout on one page. - Every CI build keeps its images, so a change can be tried on real hardware
before it is ever tagged.
📄 Assets in this release
| Asset | Purpose |
|---|---|
hiveinside-nrf54lm20a-v0.5.0-lowpower-factory.hex |
Deployment image, SWD over USB-C |
hiveinside-nrf54lm20a-v0.5.0-lowpower.signed.bin |
Deployment image, BLE OTA payload |
hiveinside-nrf54lm20a-v0.5.0-bringup-factory.hex |
Bench image with console, SWD over USB-C |
hiveinside-nrf54lm20a-v0.5.0-bringup.signed.bin |
Bench image with console, BLE OTA payload |
hiveinside-flash-tools.zip |
flash.sh / flash.ps1, the board's OpenOCD config, and a README |
hiveinside-enclosure.zip |
STL / STEP / F3Z enclosure files |
manifest.txt |
Size + CRC-32 per payload, commit, Zephyr revision, signing-key note |
SHA256SUMS |
Checksums for every asset above |
west-manifest-frozen.yml, build-info-<variant>.zip |
Everything needed to reproduce these images |
🧩 Component versions in this release
| Component | Version | Notes |
|---|---|---|
| HiveInside firmware | 0.5.0 | firmware-nrf54lm20a/, Zephyr + west --sysbuild |
| Target board | Seeed XIAO nRF54LM20A Sense | on-board LSM6DS3TR-C, MSM261DGT006, nPM1300 |
| External sensor | SHT40 | I²C 0x44, on the XIAO I²C header |
| BLE beacon format | version 2 | 29 bytes, unchanged since V0.1 |
| Scan response | name + identity record v1 | HiveInside-XXXX, board ID 2, major/minor/patch |
| Bootloader | MCUboot (dual-slot, 449 KiB per slot) | via sysbuild |
| Signing key | MCUboot development key (public) | see the authenticity note above |
| Requires | HiveHub V0.4 or newer | identity readout, version gating, OTA relay |
⬆️ Upgrading from V0.1
- Over the air: upload
hiveinside-nrf54lm20a-v0.5.0-lowpower.signed.binin
HiveHub. Nothing else to do; the node reboots and reports 0.5.0. - Over USB: flash the matching
-factory.hexwith the bundled script. - After the update the node appears as
HiveInside-XXXXinstead of
HiveInsidein scanner apps. The measurement frame is unchanged, so nothing
downstream needs adjusting.
🚧 Status & known limitations
- The firmware is complete and OTA is verified on hardware. Long-term field
validation in a live colony is still ongoing — treat this as a solid
release, not as a multi-season-proven product. - The prebuilt images are built and checked by CI, not yet flashed from this
release onto a board by hand. If the very first thing you try is the
factory hex, keep a USB cable and
docs/flashing.md
within reach. flash.ps1(Windows) has not yet been run on Windows.flash.shis the
tested path.- The measurement advertisement fills the 31-byte legacy limit exactly, so the
optional BLE Flags element is omitted. The node is therefore formally
non-discoverable: generic scanner apps that filter on the discoverable bits
may not list it. HiveHub's passive scan and a direct connect by address are
unaffected. - Idle current is an audit based on component and configuration analysis; a
power-analyzer measurement of the assembled board is still the number that
counts.
📚 Documentation
docs/flashing.md— prebuilt images, flashing, and troubleshootingdocs/ota-over-ble.md— the OTA protocol ...
HiveInside V0.1 — the first release 🐝
HiveInside is a stand-alone, battery-powered in-hive environmental and
acoustic sensor. It sits inside the hive, measures climate, vibration and
sound, and broadcasts the result as a BLE beacon that a
HiveHub / HiveScale picks up with a passive
scan and forwards to the backend. No cabling into the hive, no pairing window,
no wake-sync schedule — and, from this release on, firmware updates over the
air.
This is the first tagged release. The firmware is feature-complete for its
intended job: all four sensor groups, the shared FFT band analysis, the
HiveHub-compatible beacon, a watchdog, a measured low-power deployment profile,
and MCUboot-based BLE OTA that has been fixed and verified on real hardware.
Why a separate device?
The frame-mounted accelerometer is, per the literature (Ramsey et al. 2020,
Sci. Rep.), the only reliable way to predict swarming up to ~30 days
ahead — microphones cannot capture the critical ~20 Hz vibrational
signature. HiveInside puts that accelerometer, plus acoustic FFT bands and
climate sensing, inside the hive on a tiny wireless board, avoiding the cabling
a wired sensor needs.
Hardware
Built on the Seeed XIAO nRF54LM20A Sense, which folds most of the discrete
sensors onto one module, plus one external climate sensor.
| Function | Part | Interface |
|---|---|---|
| 3-axis vibration (swarm prediction, ~20 Hz) | LSM6DS3TR-C — on-board 6-axis IMU | I²C |
| Acoustic FFT (piping, hum, stress) | MSM261DGT006 — on-board PDM mic | PDM |
| Temperature + humidity | SHT40 (external, 0x44) |
I²C |
| Battery voltage + charge | nPM1300 PMIC fuel gauge — on-board | — |
The accelerometer probe auto-detects the chip by WHO_AM_I, so an external
LIS3DH / LIS2DH12 breakout at 0x18/0x19 runs the same pipeline for bench
comparisons. A 3D-printable enclosure for the XIAO, the SHT40 and a 500 mAh LiPo
lives in enclosure/.
Features
Full in-hive measurement, every 5 minutes. Each cycle reads all four sensor
groups and reduces them to the ecosystem-shared FFT bands, so a value means
the same thing here as it does on a HiveScale:
- Vibration (mg, gravity removed): swarm
8–30 Hz, fanning30–100 Hz,
activity100–200 Hz— plus broadband RMS and peak. - Acoustics (dBFS): sub-bass
50–150 Hz, hum150–300 Hz, piping
300–550 Hz, stress550–1500 Hz, high1500–3000 Hz— plus RMS and peak. - Climate: temperature and relative humidity.
- Battery: cell voltage and state of charge.
Each group carries its own validity flag, so a failed or missing sensor is
reported as absent rather than as a zero-filled reading the backend would
mistake for real data. A partial board still gives a useful readout.
BLE beacon transport — no connection required. The full measurement is a
29-byte manufacturer-data advertisement, repeated every second by the
Bluetooth controller and read out of the air by HiveHub's existing passive scan.
Format version 2 keeps every version-1 field at its original offset and appends
acceleration peak and microphone peak, so an older HiveHub decoder keeps working
unchanged while an updated one gains both peaks. A compact identity record
in the scan response reports board ID and firmware version to active scans, which
is what lets HiveHub display and version-gate each node.
Firmware-over-BLE (OTA) — implemented and working. HiveInside has no WiFi, so
HiveHub is the relay:
backend (signed .bin + CRC-32) ──► HiveHub ──(BLE GATT)──► HiveInside
firmware_releases (WiFi) OTA service (dual slots)
- MCUboot dual-slot with test-swap and automatic rollback.
- Three GATT characteristics (control / data / status) — the only GATT
attributes the device exposes; the measurement is never read over a
connection. - Nothing is buffered on either side. HiveHub streams the HTTPS download
straight through; HiveInside writes each chunk directly into its inactive
slot. Nothing is committed until size and CRC-32 verify, so a dropped or
corrupted transfer always leaves the node on its old image. - A transfer that stalls mid-stream is abandoned instead of hanging.
- The STATUS characteristic reports state, bytes received, error and the
failing operation's errno — the whole field diagnosis for a sealed node
with no console.
The one hardware-level blocker found during bring-up is fixed: on the nRF54,
RRAM writes run inside a radio timeslot, and at the driver default every OTA
died at exactly 488 bytes on the first real flash write. The write buffer is now
raised to a full 512-byte line flush per timeslot (with CONFIG_IMG_BLOCK_BUF_SIZE
pinned to match), and advertising restarts from a work item so a node comes back
after every OTA attempt instead of going dark until the next cycle.
See docs/ota-over-ble.md.
Ultra-low power, audited. The node idles with only the ~1 s advertiser
running; there is no deep-sleep rendezvous machinery to keep in sync. The whole
sensor island — IMU and microphone — is switched off between measurements at
both the nPM1300 LDO1 and the upstream power_en gate, and the firmware
explicitly releases Zephyr's boot-time regulator reference so the disable
actually reaches hardware instead of merely reporting success. PDM is stopped
after capture, the accelerometer is powered down, the SHT40 uses its
lowest-power single-shot command, and CONFIG_TICKLESS_KERNEL keeps the CPU off
between events. A separate lowpower deployment profile drops the UART,
console printk() and the measurement LED, and removes the regulator-boot-on
defaults so nothing is held powered from reset. BLE measurement advertising and
OTA are unchanged in that profile.
See docs/low-power.md.
Watchdog. A sealed node has nobody watching it, and a hang inside a driver —
a stuck I²C transfer, a dmic_read() that never returns — would otherwise leave
the firmware alive enough to keep advertising the last good measurement
forever, which from HiveHub looks like a hive that simply stopped changing. A
hardware watchdog catches that and resets the node.
One build system, reproducible. Zephyr with west --sysbuild is the only
supported build path — it builds MCUboot and the signed application together,
which is what makes both a bootable device and an OTA payload. A pinned
west.yml makes the workspace reproducible, and every build also drops a
version-stamped, variant-stamped copy of the signed image beside
zephyr.signed.bin:
hiveinside-nrf54lm20a-v0.4.7-bringup.signed.bin # console on
hiveinside-nrf54lm20a-v0.4.7-lowpower.signed.bin # deployment profile
The version comes from the same constants the node advertises, so the artifact
name and the on-air version can never drift apart — and the HiveHub dashboard
reads that name to fill in target and version by itself. CI builds both
configurations on every change.
Home Assistant. Through HiveHub's MQTT bridge, a HiveInside node appears as
its own Home Assistant device with exactly the entities it reports — climate,
cell voltage, firmware version, and its vibration and acoustic bands.
See docs/homeassistant.md.
Component versions in this release
| Component | Version | Notes |
|---|---|---|
| HiveInside firmware | 0.4.7 | firmware-nrf54lm20a/, Zephyr + west --sysbuild |
| Target board | Seeed XIAO nRF54LM20A Sense | on-board LSM6DS3TR-C, MSM261DGT006, nPM1300 |
| External sensor | SHT40 | I²C 0x44, on the XIAO I²C header |
| BLE beacon format | version 2 | 29 bytes, backward-compatible with the v1 26-byte prefix |
| Identity record | version 1 | board ID 2, major/minor/patch |
| Bootloader | MCUboot (dual-slot, 449 KiB per slot) | via sysbuild |
| Enclosure | 3D-printable, XIAO + SHT40 + 500 mAh LiPo | enclosure/ |
| Requires | HiveHub V0.4 or newer | for identity readout, version gating and OTA relay |
The firmware version string (
0.4.x) is the firmware's own counter and is
independent of this repository release tag (V0.1).
Quick start
west init -m https://github.com/MacNite/HiveInside hiveinside-workspace
cd hiveinside-workspace && west update
west build --sysbuild -b xiao_nrf54lm20a/nrf54lm20a/cpuapp -d debug hiveinside/firmware-nrf54lm20a
west flash -d debug
picocom -b 115200 /dev/ttyACM0--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). A plain west build yields
an application-only image with nothing at 0x0, which does not boot.
For a hive deployment, build the lowpower profile and flash that image —
then let HiveHub keep it up to date over the air.
docs/vscode-build.md— build from VS Code / VSCodiumdocs/flashing.md— flashing and troubleshootingdocs/wiring.md— XIAO ↔ SHT40 connectionsdocs/low-power.md— the deployment profiledocs/ota-over-ble.md— the OTA protocolfirmware-nrf54lm20a/README.md— readout format, BLE frame layout, roadmap
Status & known limitations
- The firmware is complete and OTA is verified on hardware. Long-term field
validation in a live colony is still ongoing — treat V0.1 as a solid first
release, not as a multi-season-proven product. - The measurement advertisement fills the 31-byte legacy limit exactly, so the
optional BLE Flags element is omitted. The n...