Skip to content

Releases: MacNite/HiveInside

HiveInside V0.5 — flash it, don't build it 🐝

Choose a tag to compare

@github-actions github-actions released this 27 Aug 05:18
6aa497f

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.

📖 How to flash it →


🔥 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.bin over SWD. It links behind an MCUboot header
at the slot-0 offset, so on its own it leaves nothing at 0x0: the CPU faults
before main() 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.hex

OpenOCD 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 macOS

manifest.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 websitemacnite.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.bin in
    HiveHub. Nothing else to do; the node reboots and reports 0.5.0.
  • Over USB: flash the matching -factory.hex with the bundled script.
  • After the update the node appears as HiveInside-XXXX instead of
    HiveInside in 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.sh is 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

Read more

HiveInside V0.1 — the first release 🐝

Choose a tag to compare

@MacNite MacNite released this 12 Aug 10:09
d400eb4

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, fanning 30–100 Hz,
    activity 100–200 Hz — plus broadband RMS and peak.
  • Acoustics (dBFS): sub-bass 50–150 Hz, hum 150–300 Hz, piping
    300–550 Hz, stress 550–1500 Hz, high 1500–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.

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...
Read more