Use Your AI Agent to Talk to Your Products with Notehub IQ

Blues Developers
What’s New
Resources
API Reference
Notecard and Notehub API documentation
Blog
Technical articles for developers
Connected Product Guidebook
In-depth guides for connected product development
Developer Certification
Get certified on wireless connectivity with Blues
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Webinars
Listing of Blues technical webinars
Blues.comNotehub
Shop
Docs
Help
Support DocsNotehub StatusSecurity AdvisoriesVisit our Forum
Sign In
Docs Home
What’s New
Resources
API Reference
Notecard and Notehub API documentation
Blog
Technical articles for developers
Connected Product Guidebook
In-depth guides for connected product development
Developer Certification
Get certified on wireless connectivity with Blues
Newsletter
The monthly Blues developer newsletter
Terminal
Connect to a Notecard in your browser
Webinars
Listing of Blues technical webinars
Blues.comNotehub
Shop
Docs
Example Apps
Samples
Building a Simple Asset Tracker
Building Edge AI Applications
Continuous Asset Tracking with External GPS and Immediate Location Sync
Controlling Device State and Receiving Acknowledgment
Managing a Notecard's WiFi Network Remotely
Putting a Host to Sleep Between Sensor Readings
Routing Data from Notehub to a Custom Cloud Endpoint
Using LEDs and NeoPixels to Monitor Notecard Status
Accelerators
Asset Location Tracking
Heavy Equipment Hours-of-Use & Utilization Tracker
Returnable Container / Tote Pool Tracker
Untethered Trailer and Chassis Fleet Tracker
Asset Performance Optimization
Legacy Diesel Generator Fleet Performance Uplift
Solar Array String-Level Performance Dashboard
Battery Management Systems
Aerial Lift / Rental Equipment Battery Health Monitor
Off-Grid Solar Battery Site Controller
Remote Cabinet Backup Battery Sentinel
Downtime Prevention
Municipal Wastewater Lift Station Monitor
Rooftop HVAC Predictive Maintenance
VFD Pump Predictive Maintenance
Energy Monitoring Solutions
Commercial Tenant Sub-Metering Bridge
EV Charger Session & Utilization Monitor
Utility Distribution Transformer Load Monitor
Energy Savings
Commercial Plug-Load & After-Hours Waste Dashboard
Demand-Response Solar + Battery Dispatcher
Multi-Site Walk-In Cooler Energy & Setpoint Monitor
Industrial Equipment Monitoring
CNC Machine Spindle Load and Cycle Time Tracker
Injection Molding Shot-to-Shot Process Monitor
Trailer Manufacturer Connected Trailer Platform
Loss Prevention
Construction Equipment Anti-Theft Tracker with Immobilizer
Reefer Trailer Cold-Chain & Door-Event Monitor
Remote Patient Monitoring
Cellular Medication Adherence Pillbox
Post-Discharge Vitals Relay Hub
Remotely Monitored Assets
Off-Grid Livestock Water Tank Monitor
Remote Apiary Hive Health Monitor
Safety Assurance
Construction Site Environmental & Noise Exposure Monitor
Lone Worker Panic and Fall Detection Beacon
Regulatory-Grade Pharmacy and Lab Cold Storage Audit Monitor
Supply Chain Tracking
Pallet-Attached Cold Chain Logger
Rail Car Condition & Interchange Tracker
Truck Roll Reduction
Commercial Grease Interceptor Level Monitor
Propane / LPG Tank Fill Telemetry
homechevron_rightExample Appschevron_rightAcceleratorschevron_rightRemote Apiary Hive Health Monitor

Remote Apiary Hive Health Monitor

Remote Apiary Hive Health Monitor banner
note

This reference application is here to give you ideas and help you get started quickly. It's built on specific hardware that may not match yours, so focus on the sections that fit your use case. If you'd like to talk through your project and whether it's a good fit for Blues, reach out.

Building with an AI assistant? Point it at this accelerator's firmware in firmware/apiary_hive_monitor/ so it can learn how the device works and help you adapt it to your hardware.

This project is a solar-powered hive monitor that turns each hive into a remotely-monitored asset. It tracks hive weight and brood-box climate every 15 minutes and records a short acoustic snapshot of the colony once a day. All of that gets reported without grid power, and without a truck roll every time the data looks wrong. A single Notecard for Skylo carries cellular, Skylo satellite, and WiFi radios on one module and fails over between them automatically. The same hardware and firmware reach the Blues Notehub cloud service whether the hive sits in an orchard with cell coverage or a meadow beyond any tower.

1. Project Overview

The problem. Commercial beekeepers run apiary yards in orchards, fields, and forest edges with no electrical infrastructure and no cellular signal worth depending on. A full-sized Langstroth hive in production can weigh 40–80 kg. What separates a thriving colony from a dead one, or from a hive that just swarmed and took 10,000 bees with it, shows up in kilograms, in degrees, and in a subtle shift in the pitch of the colony's hum. You can't see any of that from a distance without instruments. A traditional inspection means opening the box, smoking the bees, and physically weighing the stand. It takes time, disturbs the colony, and can't happen every 15 minutes. So hive collapse, swarm departure, and queen loss routinely get discovered days after the fact, when the economic damage is already done.

This project gives a beekeeper the remote eyes and ears they'd want at every yard but can't afford to station there in person. One weatherproof enclosure on the hive stand reads three independent signals: weight (colony biomass and honey stores), temperature and humidity inside the brood box (brood viability), and acoustic features sampled from an analog microphone at the hive entrance (behavioral state). The device processes all three locally, sampling weight and temperature every 15 minutes and capturing audio once a day, then rolls them into a daily summary and pushes it to Notehub. The summary goes out over cellular where a tower is in reach and over the Skylo satellite network where one isn't, and Notecard for Skylo picks the path automatically. In steady state the beekeeper gets one notification a day, plus an immediate alert whenever any signal crosses a threshold.

note

POC scope: daily audio snippet, features only. The acoustic path captures a single ~0.75-second snippet once per summary window (once a day by default). It computes zero-crossing rate (ZCR), RMS energy, and peak amplitude entirely on-device, and each summary carries only those three numbers. No raw audio is buffered, stored, or transmitted. Once a day fits the project scope, because colony acoustic state changes over hours, not minutes, and it avoids the power and payload cost of continuous acoustic sampling. See §7 and §11 for details.

Why Notecard for Skylo. Apiaries are put far from human infrastructure on purpose. The idea is to place bees near crops, meadows, or forest edges where there's forage and little human disturbance. Those sites have no AC power, and cellular coverage is often marginal or missing. Each of those constraints rules out the conventional IoT stack. A gateway-plus-cloud-SIM architecture takes months of site negotiation per yard, and a device that only works with strong cellular signal will fail in exactly the places where bees are most productive. Notecard for Skylo (NOTE-NBGLWX) carries three radios on one M.2 module and picks among them automatically. There's cellular (LTE-M / NB-IoT / GPRS) with its own prepaid global SIM, satellite over the Skylo non-terrestrial network (NTN), and WiFi. You don't negotiate with IT at each site or sign a carrier contract, and the yards in coverage gaps don't need a second device or part number. The firmware sets a single card.transport preference of wifi-cell-ntn (prefer WiFi, fall back to cellular, then fall back again to Skylo satellite). The Notecard handles the failover itself, and the host firmware never branches on which network is live. Skylo's geostationary (GEO) network covers open-sky terrain well, and a hive stand in an open orchard or meadow has plenty of open sky. Skylo coverage depends on geography and service region, so verify current coverage for your deployment region and review the satellite best practices guide before relying on satellite as the sole backhaul. Here, low-power cellular with automatic satellite failover is the core of the architecture, and it's what makes this deployable in the real operating environment of commercial apiculture.

New to Blues?

Learn what we do in this 3-minute video that walks you through how we simplify wireless connectivity.

Learn what we do in this 3-minute video that walks you through how we simplify wireless connectivity.

Deployment scenario. The monitor lives in a small weatherproof enclosure zip-tied or screwed to the side of the hive stand. A 5 W solar panel on a short gooseneck bracket feeds a Li-ion battery through a solar MPPT charger, and the load cell platform slides under the hive. Two sensor probes thread through existing seams or ventilation holes, one for temperature and humidity in the brood box and one for the microphone. You don't have to modify the hive body at all, and the bees never know anything changed.

2. System Architecture

System architecture: sensors → Notecarrier CX with STM32 host → Notecard for Skylo (cellular / WiFi / satellite) → cellular/NTN → Notehub → routes; power from solar panel → Sunny Buddy BATT (Li-ion) and LOAD → Notecarrier

Device-side responsibilities. Every 15 minutes the Notecard's ATTN pin wakes the Notecarrier CX's onboard STM32L433 host through card.attn. The host reads hive weight and brood-box temperature and humidity, checks three independent threshold rules, and folds the results into a running summary in RAM. Audio only happens once a day. Colony acoustic state changes over hours, so the firmware captures a ~0.75-second snippet on the rollover wake itself, computes the ZCR, RMS, and peak amplitude on-device, and throws away the raw samples, which never leave the device. A tripped threshold queues an alert Note immediately, while a normal day's summary waits on the Notecard for the next outbound sync. Between wakes the host sleeps in STM32 STOP2, drawing a few microamps with RAM intact, until the Notecard's ATTN pin raises it again.

Notecard responsibilities. Notecard for Skylo buffers each Note in its on-device flash queue and opens a network session on the hub.set outbound cadence you configure. The card.transport wifi-cell-ntn preference set at boot picks the path automatically. It uses cellular where a tower is in reach and Skylo satellite where the orchard is beyond terrestrial coverage, so the daily summary still reaches Notehub whether the apiary has cellular bars or not, and the firmware never branches on which radio is live. Alert Notes carry sync:true to skip the outbound timer. The beekeeper hears about a weight-drop event in the same minute it crosses the threshold (or within minutes when the unit is on satellite) instead of at the next scheduled flush. Environment variables pushed from Notehub retune thresholds and cadences in the field, so nobody has to drive out to reflash firmware.

Notehub responsibilities. Each unit's embedded global SIM gets the Notecard onto carrier cellular networks worldwide and delivers data over the Internet to Notehub, which ingests every event and applies the project's routes. Hive summaries and alerts arrive in separate Notefiles, so one device can feed both the beekeeper's SMS endpoint and the long-term weight-trend store without any filter logic in between.

Routing to the cloud (high level). Notehub can route to HTTP, MQTT, AWS, Azure, GCP, Snowflake, and other targets. Route setup depends on your project and is out of scope here, so see the Notehub routing docs for details.

3. Technical Summary

  1. Flash the firmware. Replace PRODUCT_UID in firmware/apiary_hive_monitor/apiary_hive_monitor.ino with your Notehub ProductUID, then install the dependencies, build, and upload:

    arduino-cli core install STMicroelectronics:stm32
    arduino-cli lib install "Blues Wireless Notecard" "STM32duino Low Power" "STM32duino RTC" "HX711 Arduino Library" "Adafruit SHT31 Library"
    arduino-cli compile --fqbn STMicroelectronics:stm32:Blues:pnum=CYGNET,usb=none firmware/apiary_hive_monitor/apiary_hive_monitor.ino
    arduino-cli upload -p /dev/ttyACM0 --fqbn STMicroelectronics:stm32:Blues:pnum=CYGNET,usb=none firmware/apiary_hive_monitor

    The usb=none board option turns off the USB CDC stack, and it has to be off for the host to sleep (see §7). The board options match firmware/apiary_hive_monitor/sketch.yaml, so if you run the commands from the sketch directory you can drop --fqbn.

  2. Wire sensors. Following §5, connect the HX711 (D5, D6), SHT31-D (SDA, SCL), and MAX9814 (A0) to the Notecarrier CX, and fit the ATTN→D9 jumper that lets the Notecard wake the host. Seat Notecard for Skylo in the M.2 slot and connect its MAIN and GPS antennas.

  3. Validate power. Use Mojo (bench only) to confirm ~15–40 mA while active and ~100–400 µA while asleep. Before field deployment, check that temperature/humidity readings and the audio ZCR show up in the summaries.

  4. Commission in Notehub. Create a project, claim the Notecard, set hx711_calibration with the known-weight test (the §9 procedure), and set environment variables at the fleet level. Then deploy.

What you'll have: A device that sends one compact daily Note with hive weight (kg), temperature/humidity averages, and acoustic features (ZCR, RMS, peak), plus immediate alerts for weight drops, temperature anomalies, or acoustic changes. It deploys fully to off-grid sites with no cellular infrastructure.

Payload example for hive_summary.qo (daily, compact template):

{
  "weight_kg": 42.3,
  "weight_delta": -0.8,
  "temp_c_avg": 34.7,
  "humidity_avg": 67.2,
  "zcr_avg": 724,
  "rms_avg": 0.12,
  "peak_avg": 0.38,
  "samples": 96,
  "batt_mv": 3842
}

Alert example for hive_alert.qo (immediate, sync:true):

{
  "alert": "weight_drop",
  "value1": 4.7,
  "value2": 37.6,
  "batt_mv": 3901
}

Here is a sample Note this device emits:

{
  "file": "hive_summary.qo",
  "body": {
    "weight_kg":     42.3,
    "weight_delta":  -0.8,
    "temp_c_avg":    34.7,
    "humidity_avg":  67.2,
    "zcr_avg":       724,
    "rms_avg":       0.12,
    "peak_avg":      0.38,
    "samples":       96,
    "batt_mv":       3842
  }
}

4. Hardware Requirements

PartQtyRationale
Notecarrier CX (buy)1Integrated carrier with an embedded STM32L433 host MCU, so you don't need a separate Swan. It has A0–A5 analog inputs, SDA/SCL I2C, and enough digital GPIO pins for all three sensors plus the ATTN wake jumper. The host sleeps in STOP2 between wakes, and the Notecard's ATTN pin wakes it.
Notecard for Skylo (NOTE-NBGLWX) (buy)1One M.2 module carrying cellular (LTE-M / NB-IoT / GPRS, Quectel BG95-S5 modem), Skylo satellite (NTN), and WiFi (Silicon Labs WFM200S) radios. It seats in the Notecarrier CX M.2 slot. The firmware's card.transport wifi-cell-ntn setting makes it prefer WiFi where an access point is in range, fall back to cellular at apiaries with coverage, and fall back again to the Skylo satellite network at yards beyond cellular reach. You don't have to pick a second device or part number, and there's no separate satellite enclosure. With the integrated prepaid global SIM, there's no carrier contract and no per-site IT negotiation. Skylo GEO coverage varies by geography and service region, so verify coverage for your deployment area before relying on satellite as the sole backhaul (see satellite best practices). This design doesn't configure or transmit device location. The satellite stack uses the board's GPS/GNSS receiver internally for timing and ephemeris, not as a user-facing location source. Requires the antennas below.
M16 cable glands (nylon, IP68)2One for the sensor cable bundle and one where the antenna pigtail passes through the main enclosure.
Blues Mojo (buy)1Bench commissioning only. Coulomb counter for validating the power budget. It sits inline on the Sunny Buddy load rail between the charger and the Notecarrier CX +VBAT pad, and connects to the Notecarrier CX Qwiic port during bench testing. Take it out of the field assembly before deployment. See §9 for how to use it.
SparkFun Load Cell Amplifier HX711 (SEN-13879)124-bit ADC front end built for Wheatstone-bridge load cells. It talks to the host over two GPIO pins with a bit-banged protocol.
Zemic H8C-C3-100KG single-ended shear-beam load cell1IP67-rated alloy-steel single-ended shear-beam cell with 100 kg capacity, OIML C3 accuracy class, and a 4-wire Wheatstone bridge on a 1 m cable. The H8C is normally one of 3–4 cells in a platform scale. For this single-cell POC it's mounted as a cantilever weigh module, with the fixed end bolted to a rigid bracket and the free end carrying the load through a button or rocker pin. See §5 for the mount detail and §11 for the off-center loading limitations this brings. It's sized for a loaded double-brood Langstroth with supers (typically 40–80 kg). Available through Zemicus USA and Zemic-authorized scale-supply distributors.
Adafruit Sensirion SHT31-D Temperature & Humidity Sensor (product #2857)1I2C sensor for temperature and humidity inside the brood box, rated for high-humidity operation. Four female-to-female jumper wires connect it to the Notecarrier CX I2C header pins (VIN, GND, SDA, SCL), because the Notecarrier CX dual 16-pin header uses 0.1″ pitch and won't take a Qwiic/STEMMA QT connector directly. Brood temperature has to stay at 34–35 °C for healthy brood development, which makes it the most sensitive single health indicator in the hive.
Adafruit Electret Microphone Amplifier MAX9814 (product #1713)1Amplified analog electret microphone with automatic gain control (AGC). Its output connects to A0 on the Notecarrier CX for ADC sampling. The AGC keeps the signal in range across the wide swing in amplitude between a quiet winter cluster and an agitated, defensive colony.
SparkFun Sunny Buddy MPPT Solar Charger (PRT-12885)1Maximum power point tracking (MPPT) solar charger for single-cell Li-ion or LiPo (both chemistries share a 4.2 V CC/CV charge profile). The solar panel connects to the barrel-jack input (IN+/IN−), and the battery connects to the BATT JST connector or the BAT+/GND screw terminals. The LOAD+/GND output supplies the downstream device rail, through Mojo to the Notecarrier CX on the bench or directly in the field.
Adafruit Lithium Ion Battery Pack 3.7V 4400mAh (#354)1Energy buffer for overnight and cloudy-day operation. The pack is two 18650-format Li-ion cells in parallel with integrated protection. Both the form factor and the chemistry differ from a LiPo pouch, and the thermal-limit guidance in §11 is written specifically for Li-ion. At the nominal 15-minute sample cadence with the sleep-dominant firmware profile, estimated active-phase daily consumption is roughly 12–18 mAh (96 wakeup cycles × ~10 seconds at ~40 mA, plus one daily LTE-M/NB-IoT sync at ~250 mA × ~60 seconds). The sleeping assembly also draws approximately 100–400 µA quiescent (Notecard low-power idle plus the Notecarrier CX regulator and Sunny Buddy quiescent draw, per the §9 power table), which adds roughly 2.4–9.6 mAh/day. That puts the whole-system daily budget at approximately 14–28 mAh/day. A 4 400 mAh pack at 80 % depth of discharge (3 520 mAh usable) then gives you on the order of 125–250 days of reserve without any solar contribution. Actual reserve depends on NTN session frequency, cellular signal quality, and how ambient temperature affects Li-ion capacity, so validate it with Mojo during bench commissioning. The pack includes a JST-PH 2-pin connector that mates directly with the Sunny Buddy BATT JST port.
Voltaic Systems P105 5W 6V ETFE Solar Panel15 W, 6 V (peak 6.12 V / 940 mA) monocrystalline ETFE panel rated for long-term outdoor use. It ships with a 3.5 mm × 1.1 mm DC plug that goes straight into the Sunny Buddy's barrel-jack solar input. The Sunny Buddy caps charge current at 450 mA by default, so a full recharge of the 4400 mAh pack from empty takes roughly 10 hours of direct sun.
Hammond 1554F2GY polycarbonate enclosure (IP66, 120 × 90 × 60 mm)1IP66 polycarbonate enclosure with an opaque lid, sized for the Notecarrier CX, Sunny Buddy, and Li-ion pack. Drill two M16 cable-gland holes, one for the sensor cable bundle and one for the SMA antenna pigtail. The antenna mounts outside the enclosure (see the antenna rows below), so the opaque lid doesn't affect the satellite or cellular link. Available from Hammond and authorized distributors.
4× female-to-female jumper wires, 150–200 mm (e.g. Adafruit #266)1 setConnect the SHT31-D breakout's 0.1″ header pins (VIN, GND, SDA, SCL) to the matching pins on the Notecarrier CX dual 16-pin header.
STEMMA QT / Qwiic cable, 100 mm1Connects Mojo's Qwiic port to the Notecarrier CX Qwiic connector during bench commissioning, so you can read the coulomb-counter tally from the blues.dev In-Browser Terminal. Remove this cable before field deployment.
Skylo-certified LTE/satellite antenna included with Notecard for Skylo (u.FL)1Connects to the MAIN u.FL port and carries both the terrestrial cellular signal and the Skylo satellite link, so one antenna serves both networks. Use only the Skylo-certified antenna supplied with Notecard for Skylo, because an uncertified substitute risks regulatory non-compliance and link failure. Mount it outdoors on the enclosure lid or a hive-stand upright with an unobstructed view of the sky (in the northern hemisphere, the southern sky toward the equator, where Skylo's GEO satellites sit), and route it through a liquid-tight fitting. If you'd rather use an external SMA mount than the bare u.FL antenna, add a u.FL-to-SMA-F bulkhead pigtail (e.g. Adafruit #851) through the enclosure wall.
Passive GPS/GNSS antenna (u.FL) per the Notecard for Skylo datasheet1Connects to the GPS u.FL port and supplies the GNSS time/ephemeris the satellite stack uses internally. Mount it outdoors next to the main antenna with a clear view of the sky, and route it through a liquid-tight fitting.

Bundled connectivity (Notecard for Skylo): It ships with an active global SIM that includes 500 MB of cellular data and 10 years of service, plus 10 KB of bundled Skylo satellite data, with no activation fees, no monthly subscription, and no separate satellite provider subscription. Syncing inbound less often saves the bundled satellite allocation, and §2 and §7 have guidance on that.

5. Wiring and Assembly

Wiring diagram: HX711 on D5/D6, SHT31-D via 4-wire jumpers on SDA/SCL, MAX9814 on A0, ATTN → D9 jumper so the Notecard can wake the host from STOP2, Skylo-certified antenna on MAIN u.FL plus GPS antenna, power chain: solar → Sunny Buddy (Li-ion at BATT) → LOAD → Mojo → Notecarrier +VBAT

The enclosure mounts on the hive stand, and the bees never know it's there. Three sensor leads thread through existing seams, one short jumper on the header lets the Notecard wake the host, the antenna lives outside on the lid, and a small solar panel on a nearby gooseneck bracket powers the whole thing. Every host I/O lands on the Notecarrier CX dual 16-pin headers, and Notecard for Skylo seats in the M.2 slot. Its MAIN u.FL port connects to the included Skylo-certified antenna, which carries both the cellular and satellite signals, and its GPS u.FL port connects to the passive GPS/GNSS antenna. Both antennas mount outside the box with an unobstructed view of the sky.

Power chain. The Sunny Buddy MPPT charger sits between the solar panel and the Li-ion battery, and the Li-ion pack connects to the Sunny Buddy's BATT JST connector (or the BAT+/GND screw terminals). The system load comes off the Sunny Buddy's LOAD+/GND screw terminals. The Notecarrier CX +VBAT pad connects to LOAD+, and GND connects to the common ground rail. During bench commissioning, Mojo sits inline on the positive load rail to measure downstream device current:

  • Solar panel DC plug → Sunny Buddy barrel jack (IN+/IN−)
  • Battery JST-PH → Sunny Buddy BATT JST connector (charges the battery from solar through MPPT, and battery negative sits at Sunny Buddy GND, which is common with LOAD GND and IN− on the Sunny Buddy PCB)
  • Sunny Buddy LOAD+ → Mojo BAT input → Mojo LOAD output → Notecarrier CX +VBAT (bench only)
  • Sunny Buddy LOAD GND → Mojo GND → Notecarrier CX GND (bench: Mojo only intercepts the positive rail, and ground stays unbroken and common across all three boards)
  • Sunny Buddy LOAD+ → Notecarrier CX +VBAT (field deployment, remove Mojo)
  • Sunny Buddy LOAD GND → Notecarrier CX GND (field deployment, direct ground return)

In this position, Mojo measures the current flowing from the Sunny Buddy's load rail to the Notecarrier. That's the total downstream device draw, not the battery's charge/discharge current directly. Mojo never interrupts ground, which passes straight through to the Notecarrier CX and back to the Sunny Buddy.

HX711 load cell amplifier:

  • HX711 VCC → Notecarrier CX +3V3_OUT
  • HX711 GND → Notecarrier CX GND
  • HX711 DOUT → Notecarrier CX D5
  • HX711 PD_SCK → Notecarrier CX D6
  • Load cell E+ (excitation positive) → HX711 E+
  • Load cell E− (excitation negative) → HX711 E−
  • Load cell A+ (signal positive) → HX711 A+
  • Load cell A− (signal negative) → HX711 A−

Mount the H8C as a single-cell weigh module. Bolt the fixed end (the end with the strain-gauge cable exit) to a rigid steel angle bracket secured to the base or pad block, and leave the free end unconstrained so it can deflect under load. Thread a loading button or rocker pin into the tapped hole on the free end, then rest the hive stand on that loading point plus three outrigger anti-tip pads. The outriggers carry no load. They're only there to keep the platform from tipping. This turns a single-ended shear-beam, normally one of 3–4 cells in a platform scale, into a workable single-cell hive scale, at the cost of the off-center loading errors documented in §11. Follow the orientation and bolt-torque values in the H8C datasheet, because a cell installed upside-down or loaded on the wrong end gives incorrect readings and can damage the gauges. Run a thin bead of RTV silicone sealant around the cable exit to keep moisture out.

SHT31-D temperature and humidity sensor:

The Notecarrier CX dual 16-pin header uses 0.1″ pitch and won't take Qwiic/STEMMA QT connectors directly, so run four female-to-female jumper wires to the SHT31-D breakout's 0.1″ through-hole pads:

  • SHT31-D VIN → Notecarrier CX +3V3_OUT
  • SHT31-D GND → Notecarrier CX GND
  • SHT31-D SDA → Notecarrier CX SDA
  • SHT31-D SCL → Notecarrier CX SCL

The SHT31-D's default address is 0x44, so it shares the I2C bus with the Notecard without any conflict.

  • POC caveat: in-hive placement. The Adafruit SHT31-D breakout isn't a sealed probe. It's an exposed PCB with a bare humidity membrane. The brood box interior runs at 34–36 °C and ≥ 85 % RH year-round, and propolis builds up on the PCB body over time. The Sensirion SHT31 sensor element itself is rated for high-humidity operation, but the breakout's solder joints and traces aren't hardened for indefinite in-hive service. For short-term POC validation, thread the board in through an existing seam or ventilation slot, position the sensor head between frames 2 and 3 at mid-frame height, and coat the PCB body (not the sensing element) with beeswax or conformal coating to slow propolis adhesion. For production deployments, use a sensor with a sealed stainless probe tip instead of an exposed breakout board, and pot all external cable exits with marine-grade silicone or epoxy.

MAX9814 microphone:

  • MAX9814 Vin → Notecarrier CX +3V3_OUT
  • MAX9814 GND → Notecarrier CX GND
  • MAX9814 Out → Notecarrier CX A0
  • Leave the MAX9814 Gain pin floating for the default 60 dB gain setting. If the AGC saturates in high-traffic hives, you can bring it down to 50 or 40 dB with resistors.
  • POC caveat: microphone placement. The Adafruit MAX9814 breakout is an unenclosed PCB with an exposed electret capsule, and it isn't hardened for in-hive service. Instead of placing it fully inside the hive body, mount the breakout board outside or at the edge of the hive entrance, close enough to pick up colony sound through the landing board gap. Between 85 %+ RH, hive acids, and propolis building up on and around the capsule opening, the acoustic response will fade over time, so this isn't supported as a long-term, maintenance-free installation. For anything beyond short-term bench validation, apply conformal coating to the PCB (masking the capsule mesh opening) and thread only a thin wiring lead through the seam. If the application needs acoustic sensing from deep inside the brood box, use a sealed MEMS microphone module rated for high-humidity environments.

Analog reference (+V_AREF pin): Leave it unconnected. The STM32L433 ADC uses the internal 3.3 V reference for the A0 microphone input.

ATTN-to-D9 jumper (host sleep):

Fit a short jumper between the ATTN and D9 pins on the Notecarrier CX. Both are on the same 16-pin header as the D5/D6 HX711 lines. D5 is the usual choice for this jumper, but here it carries the HX711 data line, so the firmware uses D9 instead through CX_ATTN_PIN. The Notecard pulls ATTN low while the host sleeps and raises it when the next sample is due, and the rising edge on D9 wakes the host from STOP2. Leave the Notecarrier CX EN pin unconnected. On the CX it enables the shared 3.3 V VIO rail (host, Qwiic, 3V3_OUT, and Notecard I/O), so driving it from ATTN would brown out the whole board instead of putting the host to sleep. Putting a Host to Sleep Between Sensor Readings covers the full pattern.

Antennas (single board, cellular + satellite + GPS):

Notecard for Skylo's MAIN u.FL antenna carries both the cellular and the Skylo satellite signal. That one antenna replaces what used to be a separate cellular whip plus the antenna on an external satellite module.

  1. Connect the included Skylo-certified antenna's u.FL connector to the Notecard's MAIN u.FL port. Orient the connector with the cable center-pin facing the port, and it clicks firmly when it's fully seated. Use only the Skylo-certified antenna supplied with the board, since an uncertified substitute risks regulatory non-compliance and link failure.
  2. Connect the passive GPS/GNSS antenna's u.FL connector to the Notecard's GPS u.FL port.
  3. Mount both antennas outside the enclosure with an unobstructed view of the sky. For satellite operation in the northern hemisphere, give the main antenna a clear view of the southern sky (toward the equator), where Skylo's GEO satellites sit, and tilt and orient it to see as much sky as possible. Route each one through an M16 cable-gland port in the enclosure wall. If you'd rather use an external SMA-mount antenna, use a u.FL-to-SMA-F bulkhead pigtail (e.g. Adafruit #851) and secure the bulkhead with its lock nut from outside.

Because the satellite link shares the MAIN antenna with cellular, a placement that gets a good cellular signal also enables satellite fallback. There's no second module to mount and no JST cable to run. The opaque Hammond lid doesn't matter either, since both antennas live outside the box.

Mojo bench connection (remove before field deployment). During bench commissioning, run the STEMMA QT / Qwiic cable from Mojo's Qwiic port to the Notecarrier CX Qwiic connector. The Notecard can then report the Mojo coulomb-counter tally (cumulative mAh, charge/discharge rate) when you send card.power requests from the blues.dev In-Browser Terminal. Remove the Mojo and Qwiic cable before you seal the field enclosure, since the production firmware doesn't query Mojo in the deployed build.

6. Notehub Setup

  1. Create a project. Sign up at notehub.io and create a project. Copy the ProductUID and paste it into firmware/apiary_hive_monitor/apiary_hive_monitor.ino as PRODUCT_UID.

  2. Claim the Notecard. Power up the unit somewhere with cellular (or WiFi) coverage. Notecard for Skylo associates with your project on its first non-NTN sync. Satellite won't work until this initial cellular/WiFi sync happens. That sync registers the device with Notehub, registers the Notefile templates, downloads the current satellite ephemeris, and sets device time, and no NTN transmission will succeed without all of them. Commission each unit where it has terrestrial coverage, even if it will usually run over satellite. See the satellite best practices guide.

    First-boot timing note. The firmware anchors the summary window to the first successful card.time response, which is the moment the Notecard returns a valid epoch instead of an error. Any sensor readings collected before that anchor get discarded, and the window clock starts there. So the first hive_summary.qo Note arrives after a full report_interval_hr window has passed from the first successful time sync (24 hours from that anchor by default). If the unit is commissioned indoors or somewhere with weak signal, that can be later than first power-up, because it has to get a cellular or satellite lock first. That's intentional. A summary sent before there's a valid time reference would hold at most one sensor reading and no meaningful weight delta.

  3. Set a fleet per apiary yard. Fleets group devices for shared configuration. With one fleet per yard, you can set threshold environment variables at the yard level, since all the hives in an orchard see similar ambient conditions, and still override them per device for a hive that's known to be a heavy producer or an established swarm catcher.

  4. Set environment variables. In Notehub, go to Fleet → Environment and set any of the values below. They're all optional, and the table shows the firmware defaults. Any value set at the fleet or device level overrides the compile-time default on the device's next inbound sync. Smart Fleets can automate fleet assignment based on device metadata.

    Commissioning note: inbound cadence. The firmware sets inbound: 10080 (one week) to keep satellite session costs down. That means the device won't pull env var changes from Notehub until the next scheduled inbound, which could be up to seven days away. During bench commissioning, force an immediate inbound sync after each env var change by sending {"req":"hub.sync"} from the blues.dev In-Browser Terminal (the terminal button in the upper right of any blues.dev page). You can also shorten the inbound interval for the bench session by sending {"req":"hub.set","mode":"periodic","outbound":1440,"inbound":15} from the terminal. Just restore the weekly inbound ("inbound":10080) before field deployment.

    VariableDefaultPurpose
    sample_interval_min15Minutes between sensor readings and threshold evaluations.
    report_interval_hr24Hours between summary Notes. Changing it also changes the Notecard's outbound sync cadence (outbound = report_interval_hr × 60 minutes). The firmware reissues hub.set automatically on the next wake cycle after the env var is applied, so cellular and NTN transmission cost scales with how often you send summaries.
    weight_alert_kg_drop2.0Weight loss (kg) over the current summary window above which a weight_drop alert fires. The weight baseline (weight_first_kg) resets at the start of every summary window, so this threshold covers whatever report_interval_hr is set to. Change the report interval to 12 hours and it becomes a 12-hour loss threshold. Tune it per hive, because a productive colony naturally loses weight on cool, rainy days.
    temp_low_c32.0Brood-box temperature (°C) below which temp_anomaly fires. Below 32 °C, brood viability drops fast.
    temp_high_c36.0Brood-box temperature (°C) above which temp_anomaly fires. Above 36 °C, the colony is probably overheating or the sensor has moved.
    audio_zcr_alert1200Zero-crossing rate (counts per second) above which audio_anomaly fires. A high ZCR means the colony's behavior has shifted from its normal acoustic pattern, and it takes a physical inspection to find out why. The baseline is typically 600–800 for calm, settled colonies, but it varies by strain, season, and ambient noise.
    hx711_calibration2280.0HX711 scale factor (raw ADC counts per kg). Set this first using the known-weight procedure in §9.
    hx711_zero_offset_kg0.0Platform tare offset in kg. After you calibrate the scale factor, set this to the reading from the empty platform (the hive stand structure with no hive body). The firmware subtracts it from every weight reading. See the tare procedure in §9.
    reset_state(not set)Set it to 1 and force an inbound sync to clear all accumulated summary-window data and restart the time anchor on the next wake. The firmware throws away any partial window in progress and starts a fresh accumulation cycle once it gets the next valid card.time response. The reset is one-shot. The firmware records the current value in persisted state, so later wakes that still read reset_state=1 are silently skipped. (That can go on for up to one inbound period, a week by default, before Notehub delivers the cleared value.) You can leave reset_state=1 in Notehub or remove it, and either way the reset won't repeat. If you set the variable back to 0, or remove it, and later set it to 1 again, a second reset fires exactly once. It's for starting a known-clean calibration window during bench commissioning. See §9.
  5. Configure routes. Add one route for hive_alert.qo (low volume, sent to an SMS/email gateway or a CMMS endpoint) and a second for hive_summary.qo (daily, sent to a long-term analytics store for weight trend analysis across the season). Because the Notefiles are separate at the source, each one can go to a different destination without filter logic inside the route.

7. Firmware Design

Most of the time the firmware does almost nothing, and that's by design. Each 15-minute wake reads three sensors, folds the readings into a running summary, fires an alert if anything crossed a threshold, and goes back to sleep. The sketch is split across four files in one directory, which keeps the wake-cycle logic apart from the sensor drivers, Notecard helpers, and host-sleep mechanics:

  • firmware/apiary_hive_monitor/apiary_hive_monitor.ino: the main sketch, with wakeup sequencing, accumulation, alert evaluation, and sleep.
  • firmware/apiary_hive_monitor/apiary_hive_monitor_helpers.h: the shared HiveState struct, extern declarations, and function prototypes.
  • firmware/apiary_hive_monitor/apiary_hive_monitor_helpers.cpp: sensor drivers, Notecard helper functions, and summary/alert emission.
  • firmware/apiary_hive_monitor/cx_sleep.h: host sleep (card.attn request, STOP2 entry, ATTN wake).

To open the sketch in the Arduino IDE, choose File → Open and navigate to firmware/apiary_hive_monitor/apiary_hive_monitor.ino. The IDE picks up the helper files automatically because they're in the same directory.

Dependencies:

  • Arduino core for STM32 (stm32duino/Arduino_Core_STM32), from the Arduino IDE Boards Manager.
  • Blues Wireless Notecard (the note-arduino library), from the Arduino Library Manager. The note-arduino releases page lists available versions. Check the changelog for breaking API changes before you upgrade.
  • HX711 Arduino Library by Bogdan Necula and Lukas Bachschwell, from the Library Manager.
  • Adafruit SHT31 Library, from the Library Manager.
  • STM32duino Low Power and its dependency STM32duino RTC, from the Library Manager. Low Power provides the STOP2 entry and ATTN-pin wake used in cx_sleep.h.

Build settings: The Notecarrier CX's host is the same STM32L433 as the Blues Cygnet, so select Blues boards → Cygnet (pnum=CYGNET) and set USB support (if available) to None (usb=none). If the USB CDC stack is enabled and no USB host is attached (battery power, or the Notecarrier CX USB-C switch in NC), the STM32's USB wakeup interrupt fires continuously and the host never stays in STOP2. Debug output (when DEBUG_SERIAL is defined in apiary_hive_monitor_helpers.h) goes to the LPUART on the Notecarrier CX debug jack instead, which an ST-LINK V3 exposes as a virtual COM port (see Serial Logging With STLINK).

Modules

ResponsibilityWhere
Notecard configuration (hub.set, card.transport wifi-cell-ntn for automatic cellular→Skylo satellite fallback, env.template so environment variables reach the device over NTN, accelerometer disabled; no location configured, since only the satellite stack uses the board's GPS receiver, internally)notecardConfigure()
Note template definitions (compact, satellite-safe)defineTemplates()
Environment variable fetch and clampingfetchEnvOverrides()
HX711 10-sample weight averagereadWeightKg()
SHT31-D I2C temperature and humidityreadTempHumidity()
Streaming audio feature extraction (ZCR, RMS, peak)readAudioFeatures()
Threshold evaluation and immediate alert emissionsendAlert()
Daily aggregated summary emissionsendSummary()
Host sleep (STOP2 until the Notecard raises ATTN on D9)loop() → sleepUntilAttn() → cx_sleep.h: cxSleepBegin(), cxSleepUntilAttn()
Application state (held in RAM across sleep cycles)HiveState

Sensor reading strategy

Weight. The firmware wakes the HX711 by pulling the PD_SCK pin low, then takes 10 readings in a row and averages them. The HX711 library handles the bit-bang timing internally. A calibration factor (the hx711_calibration env var) converts raw 24-bit ADC counts to kilograms. After the read, the firmware puts the HX711 back to sleep (PD_SCK held high) to cut its ~1.5 mA idle draw during the sleep cycle.

Temperature and humidity. A single SHT31-D measurement takes roughly 15 milliseconds, and the library manages the I2C transaction and CRC check internally. Values go into running sums for the daily average. If the I2C read fails (returns NaN), that sample stays out of the sum, so a disconnected sensor doesn't drag the average toward zero.

Audio feature extraction. Audio is captured once per summary window (once a day by default). The firmware checks the audio_sampled flag after it evaluates window expiry, not before. On a successful rollover the flag gets cleared before the audio check runs, so audio is captured on the rollover wake itself. That makes the rollover wake the true first wake of the new window for all three sensor paths. On every later wake in the same window, audio_sampled is set and the microphone isn't sampled again. On a failed rollover (sendSummary() returned false), audio_sampled is still true from the previous window and the block is skipped, which matches the frozen-snapshot retry behavior for weight and temperature.

When the firmware samples audio, readAudioFeatures() runs 12 consecutive 256-sample windows on A0 at approximately 4 kHz (AUDIO_SAMPLE_PERIOD_US = 225 µs), for a ~0.75-second snippet in total. It computes the features one window at a time from a 512-byte stack buffer instead of storing the whole snippet, which would take about 6 KB at 16-bit resolution. readAudioFeatures() also returns a validity flag and rejects the read if the signal is implausible. That covers a DC offset outside the expected mid-rail band (a floating or disconnected A0), more than 30 % of samples within 32 LSB of the ADC rail (clipping), or normalized RMS below a minimum threshold (a dead or shorted microphone). On an invalid read, audio_anomaly isn't evaluated, audio_sampled still gets set to prevent retries on every wake, and zcr_avg, rms_avg, and peak_avg report −9999. That's the same sentinel convention used for weight timeouts and temperature NaN reads. The firmware only stores or transmits the three computed features and never records raw audio.

  • Zero-crossing rate (ZCR): The number of sign changes per second. A higher ZCR means more high-frequency content, which means more active colony sound.
  • RMS energy: Root-mean-square of the windowed samples, normalized to the 12-bit ADC range. It tracks the hive's overall activity level.
  • Peak amplitude: Normalized maximum sample value in the window.

The firmware averages these three features across the 12 windows and stores them in the daily accumulator. ZCR is the main anomaly indicator, and RMS and peak add context in the daily summary payload.

Event payload design

The device uses two template-backed Notefiles with "format": "compact". Skylo NTN (satellite) operation requires it, and it's good practice anyway. Compact templates shrink on-wire payload size by 3–5× compared with free-form JSON, which keeps each Note well under the 256-byte NTN payload ceiling.

hive_summary.qo (daily, templated compact):

{
  "file": "hive_summary.qo",
  "body": {
    "weight_kg":     42.3,
    "weight_delta":  -0.8,
    "temp_c_avg":    34.7,
    "humidity_avg":  67.2,
    "zcr_avg":       724,
    "rms_avg":       0.12,
    "peak_avg":      0.38,
    "samples":       96,
    "batt_mv":       3842
  }
}

hive_alert.qo (immediate, sync:true, templated compact):

{
  "file": "hive_alert.qo",
  "body": {
    "alert":   "weight_drop",
    "value1":  4.7,
    "value2":  37.6,
    "batt_mv": 3901
  },
  "sync": true
}

The value1 and value2 fields carry alert-specific data. For weight_drop they hold the daily loss in kg and the current hive weight, for temp_anomaly the current temperature and humidity, and for audio_anomaly the ZCR and RMS values. One compact template handles all three alert types.

Low-power strategy

After each 15-minute sample cycle, loop() calls sleepUntilAttn(), which calls cxSleepUntilAttn() (in cx_sleep.h). That sends a card.attn sleep request for sample_interval_min × 60 seconds, waits for the Notecard to pull ATTN low, and drops the STM32L433 into STOP2, which costs a few microamps and keeps RAM intact. When the interval is up, the Notecard raises ATTN, the rising edge on D9 wakes the host, and execution continues on the next line of loop(). The host resumes in place instead of cold-booting, so the runtime state just stays in RAM in the HiveState struct: the summary-window accumulators, last-alert timestamps, the weight baseline, and the audio_sampled flag. Nothing gets serialized to the Notecard, and setup() runs only once per power-up. If the sleep request fails or ATTN never goes low (say the jumper is missing), loop() waits out the interval awake and tries again on the next cycle, so the sample cadence holds either way.

Between cellular sessions the Notecard drops into its published low-power idle state (~8–20 µA per the Notecard datasheet). The firmware puts the HX711 to sleep through its PD_SCK pin after each weight reading. The MAX9814 and SHT31-D stay powered from +3V3_OUT while the host sleeps, because the rail stays up in this design. Their quiescent draw is small, though, and audio sampling only happens on one of the 96 daily wake cycles.

At power-up, notecardConfigure() also issues a one-time card.transport {"method":"wifi-cell-ntn"} so Notecard for Skylo prefers WiFi, then cellular, then Skylo satellite. The fallback happens in the Notecard, and the firmware never branches on which radio is live. NTN isn't enabled by default, so this call is what makes satellite fallback possible at all. The Notecard saves the setting in its own flash, so sending it once is enough. notecardConfigure() also registers an env.template that lists every variable in §6, because over NTN Notehub only delivers the environment variables named in that template.

The initial sync cadence is outbound: 1440 (daily), which keeps satellite transmission costs down at sites that run over NTN. sync:true on alert Notes skips this timer and forces an immediate cellular or NTN session. Following the satellite best practices guide, inbound is set to 10080 (one week), because each inbound satellite ping costs approximately 50 bytes of the bundled 10 KB satellite allocation. Environment variable changes take effect on the next scheduled inbound sync.

When you change report_interval_hr in Notehub, the firmware reissues hub.set with outbound = report_interval_hr × 60 on the next wake after it picks up the env var. That keeps the Notecard's transmission schedule lined up with the local summary cadence. Setting report_interval_hr to 12, for example, shortens the summary window and cuts the outbound sync interval to 720 minutes on the same wake cycle, with no manual hub.set needed.

Retry and error handling

  • The first Notecard transaction, hub.set inside notecardConfigure(), uses requestAndResponse() so the code can inspect the Notecard's err response field before treating the call as a success. first_boot only gets cleared when the Notecard confirms it accepted hub.set without an error, not just when the I2C transport finished. A configuration that was rejected or silently dropped never skips setup for good.
  • SHT31-D reads that return NaN stay out of the daily temperature and humidity averages. The firmware keeps a separate temp_valid_count of successful SHT31-D reads so failed reads don't pull the average toward zero. If temp_valid_count is zero at summary time (every read failed), sendSummary() calls safeAvg(), which reports −9999 as a sentinel. That lets downstream analytics tell a total sensor failure apart from a valid near-zero reading.
  • HX711 reads that time out (no data-ready pulse within 500 milliseconds) return −1.0 and are left out of the daily weight average.
  • The alert cooldown (ALERT_COOLDOWN_MIN, 60 minutes by default) keeps a slowly drifting sensor from sending a new page every 15 minutes until someone corrects the threshold or the condition clears.
  • Audio reads that fail the hardware-plausibility checks get rejected entirely. readAudioFeatures() returns false in three cases: the DC offset is outside the expected mid-rail band (a floating or disconnected A0 input reads near 0 or 4095), more than 30 % of samples in a window fall within 32 LSB of the ADC rail (a railed or badly clipping input), or the normalized RMS falls below the minimum signal threshold (a dead or shorted microphone capsule). On an invalid read, audio_anomaly isn't evaluated, audio_sampled is still set so it doesn't retry on every wake for the rest of the window, and zcr_avg, rms_avg, and peak_avg report −9999 in the summary. That matches the sentinel convention for weight timeouts (−1.0 read → excluded, safeAvg emits −9999) and temperature NaN reads. If −9999 keeps showing up across consecutive daily summaries, there's a hardware failure (a disconnected wire, failed capsule, or corroded contact) that needs a physical inspection.

Key code snippet 1: compact template definition

Skylo NTN (satellite) operation requires the "format": "compact" field, and it cuts the per-Note wire size by 3–5× (a 200-byte JSON Note becomes ~40–80 bytes in compact form, for example). port must be in the range 1–100. The numeric format codes (e.g., 14.1, 12) describe the wire encoding, where 14.1 means a 4-byte IEEE 754 float and 12 means a 2-byte signed integer. Notecard handles the encoding and decoding automatically, so there's no manual work. The firmware reads the response and treats an err field as a failure. defineTemplates() only returns true once this template and the hive_alert.qo template (port 11, a string hint for alert plus floats for value1 and value2) are both accepted. Until then first_boot stays set, and loop() retries the setup on each wake before it reads any sensors or adds any Notes.

J *req = notecard.newRequest("note.template");
JAddStringToObject(req, "file",   "hive_summary.qo");
JAddNumberToObject(req, "port",   10);
JAddStringToObject(req, "format", "compact");
J *body = JAddObjectToObject(req, "body");
JAddNumberToObject(body, "weight_kg",    14.1);  // 4-byte float
JAddNumberToObject(body, "weight_delta", 14.1);
JAddNumberToObject(body, "temp_c_avg",   14.1);
JAddNumberToObject(body, "humidity_avg", 14.1);
JAddNumberToObject(body, "zcr_avg",      12);    // 2-byte signed int
JAddNumberToObject(body, "rms_avg",      14.1);
JAddNumberToObject(body, "peak_avg",     14.1);
JAddNumberToObject(body, "samples",      12);
JAddNumberToObject(body, "batt_mv",      12);
{
    J *rsp = notecard.requestAndResponse(req);
    if (rsp == NULL) return false;
    const char *err = JGetString(rsp, "err");
    if (err && *err) { notecard.deleteResponse(rsp); return false; }
    notecard.deleteResponse(rsp);
}

Key code snippet 2: two-pass streaming audio feature extraction

The firmware processes each 256-sample window in two passes, so the per-window DC operating point comes from the actual samples instead of being assumed to sit at the ADC midpoint (2048). The MAX9814's AGC shifts the quiescent DC level from one installation to the next, and measuring it directly lets the ZCR threshold carry over without per-board recalibration. ZCR also comes from the measured wall-clock window duration (t1 − t0) instead of a nominal sample rate, so it stays accurate whatever the MCU speed or analogRead() latency. The excerpt skips the clip count and the per-window validity gate that sit between the two passes (see Retry and error handling). PIN_MIC_LOCAL is A0, and AUDIO_ADC_HALFRANGE (2048) normalizes each centered sample to the range −1 to 1. If micros() didn't advance, dur_s falls back to the nominal 4 kHz rate (AUDIO_SAMPLE_RATE_HZ).

analogReadResolution(12);
// ...
for (int w = 0; w < AUDIO_NUM_WINDOWS; w++) {
    // --- Pass 1: collect raw ADC samples, sum for DC mean, count clips --
    int16_t samples[AUDIO_WINDOW_SAMPLES];
    int32_t dc_sum  = 0;
    // ...
    unsigned long t0 = micros();
    samples[0] = (int16_t)analogRead(PIN_MIC_LOCAL);
    dc_sum = samples[0];
    for (int i = 1; i < AUDIO_WINDOW_SAMPLES; i++) {
        delayMicroseconds(AUDIO_SAMPLE_PERIOD_US);
        samples[i] = (int16_t)analogRead(PIN_MIC_LOCAL);
        dc_sum += samples[i];
    }
    unsigned long t1 = micros();
    int32_t dc_offset = dc_sum / AUDIO_WINDOW_SAMPLES;
    // ...
    float dur_s = (t1 > t0) ? (float)(t1 - t0) * 1e-6f
                             : (float)AUDIO_WINDOW_SAMPLES / (float)AUDIO_SAMPLE_RATE_HZ;

    // --- Pass 2: compute ZCR / RMS / peak with measured DC removed ----
    uint32_t crossings = 0;
    float    sum_sq    = 0.0f;
    float    peak_abs  = 0.0f;

    int32_t prev = (int32_t)samples[0] - dc_offset;
    for (int i = 1; i < AUDIO_WINDOW_SAMPLES; i++) {
        int32_t cur = (int32_t)samples[i] - dc_offset;

        if ((prev < 0 && cur >= 0) || (prev >= 0 && cur < 0)) crossings++;

        // Normalise to [-1, 1] using the ADC half-range as the divisor.
        float norm = (float)cur / (float)AUDIO_ADC_HALFRANGE;
        sum_sq += norm * norm;
        float abs_n = (norm < 0.0f) ? -norm : norm;
        if (abs_n > peak_abs) peak_abs = abs_n;
        prev = cur;
    }

    zcr_accum  += (float)crossings / dur_s;
    rms_accum  += sqrtf(sum_sq / (float)(AUDIO_WINDOW_SAMPLES - 1));
    peak_accum += peak_abs;
}

After the loop, dividing these sums by the number of windows that passed the gate (at least 7 of the 12 in AUDIO_NUM_WINDOWS) produces the zcr_avg, rms_avg, and peak_avg fields in hive_summary.qo.

Key code snippet 3: sleeping until the Notecard raises ATTN

The sketch's sleepUntilAttn() wrapper calls cxSleepUntilAttn(), which asks the Notecard to hold ATTN low for the requested seconds, confirms the pin went low, and puts the STM32 into STOP2. Because the host stays alive, the firmware checks the result of the card.attn request instead of treating it as fire-and-forget. setup() arms the wake once with cxSleepBegin(), and the last line of loop() sleeps for sample_interval_min × 60 seconds. The HX711 already has D5, so the sketch defines CX_ATTN_PIN as D9 before including cx_sleep.h.

// D5 is the HX711 data line, so the ATTN jumper lands on D9 instead.
#define CX_ATTN_PIN D9
#include "cx_sleep.h"
// ...
static void sleepUntilAttn(uint32_t seconds) {
    // ...
    if (!cxSleepUntilAttn(notecard, seconds, NULL, log)) {
        // The Notecard didn't take the sleep request, or ATTN never went low
        // (check the ATTN -> D9 jumper). Keep the sample cadence and retry.
        // ...
        delay(seconds * 1000UL);
    }
}
// ...
    // Wake from STOP2 on the ATTN rising edge (ATTN jumpered to D9).
    cxSleepBegin();
// ...
    sleepUntilAttn((uint32_t)sampleMin * 60u);

8. Data Flow

Data flow: sensors sampled every 15 minutes → three threshold rules → hive_alert.qo (sync:true, immediate) and hive_summary.qo (daily, compact template) → Notehub → routes

Collected. Every 15 minutes, the device reads hive weight in kg (a 10-sample HX711 average) plus brood-box temperature (°C) and relative humidity (%). Once per summary window (daily by default, on the rollover wake), it takes the audio zero-crossing rate (counts/s), RMS energy, and peak amplitude from a ~0.75-second acoustic snapshot.

Accumulated. Readings get summed into per-metric accumulators in RAM, which survive STOP2 sleep. The Notecard only ever receives aggregated values and alert conditions, never raw samples.

Transmitted.

  • hive_summary.qo: one compact-template Note every report_interval_hr (24 hours by default). Each numeric field is the mean of its valid samples over the window, and a field with zero valid reads reports −9999. The weight_delta field is the difference between the day's first and last valid weight readings, so a swarm departure shows up in the summary right away even if no threshold alert fired.
  • hive_alert.qo: sent immediately when a threshold trips, with sync:true to force an immediate cellular or NTN uplink. After an alert type fires, it's suppressed for ALERT_COOLDOWN_MIN (60 minutes).

Routed. Both Notefiles land in Notehub, and from there they go wherever the project's routes send them.

Triggers. Three rules fire alerts:

  • weight_drop: weight loss ≥ weight_alert_kg_drop (2.0 kg by default) from the first valid reading of the current summary window to the most recent reading. The baseline resets with each summary, so the effective threshold window equals report_interval_hr. This is the main indicator for swarm departure (fast, over 1 kg/hour), theft, or gradual starvation.
  • temp_anomaly: brood-box temperature outside the temp_low_c–temp_high_c band (32–36 °C by default). It can mean chilling brood (late-fall cluster shrinkage), overheating (poor ventilation), or a queen loss that reduces the cluster's heat production.
  • audio_anomaly: audio ZCR exceeds audio_zcr_alert (1200 counts/s by default). A high ZCR means the colony's acoustic behavior has measurably changed from a settled colony's typical pattern. ZCR alone can't tell you the biological cause, whether that's defensive arousal, a disrupted colony, or environmental noise, so it takes a physical inspection. The firmware doesn't currently flag a sustained low ZCR on an otherwise healthy hive, since that would need a per-colony baseline model.

9. Validation and Testing

Expected cadence in steady state. A healthy, settled colony produces one hive_summary.qo Note a day and no hive_alert.qo Notes. Plan on a short tuning period after deployment to make sure the weight, temperature, and audio thresholds suit that particular hive. A heavy honey super changes the weight baseline, an aggressive strain may have a higher natural ZCR, and early-spring colonies run cooler than peak-season ones.

Bench validation sequence. Before field deployment:

warning

Key constraint for weight calibration. weight_kg in hive_summary.qo is the mean of all valid readings accumulated across the entire summary window, not an instantaneous reading. The platform load has to stay constant and unchanged for the full length of every summary window you use for calibration or tare. A change to report_interval_hr takes effect on the next wake after the env var is applied. The firmware re-runs the expiry test now − last_report_epoch ≥ reportHr × 3600 on every wake with the current env var value, so a shorter interval can make the current window expire right on that wake. Always start calibration from a known-clean window boundary with the reset_state env var (see step 1b below).

  1. Scale-factor calibration.

    a. Shorten the window. In Notehub, set report_interval_hr to 1. Force an immediate inbound sync by sending {"req":"hub.sync"} from the blues.dev In-Browser Terminal (see §6 step 4). Without it, the weekly inbound: 10080 setting means the env var might not arrive for up to seven days. Wait for the Notecard to confirm the sync. The new interval takes effect on the next wake after the env var is applied.

    b. Clear any partial window in progress. The summary window lives in RAM, and only a power-cycle or reset clears it. To start from a known-clean boundary without touching the hardware, set reset_state to 1 in Notehub (see §6) and force an immediate inbound sync ({"req":"hub.sync"}). On the next wake the firmware clears all accumulators and sets last_report_epoch = 0, and the window gets re-anchored when the next valid card.time response arrives. The reset is one-shot. The firmware silently skips later wakes that still read reset_state=1 (before the next inbound sync delivers the updated value). Once the first 1-hour summary has arrived, which tells you a complete clean window went by, you can leave reset_state=1 in Notehub or remove it. The window won't reset again.

    c. Empty-platform window. Put the empty load-cell platform (no hive body) on the load cell and leave it completely undisturbed. Wait for one complete 1-hour summary, then record weight_kg from that Note as platform_reading_kg.

    d. Known-mass window. Put a known reference mass (a 10 kg bag of flour or a calibrated test weight, for example) on the platform and leave it completely undisturbed for one full window. Record the resulting weight_kg as reported_weight_kg.

    e. Compute the corrected scale factor:

    new_hx711_calibration = old_calibration × (reported_weight_kg − platform_reading_kg) / known_weight_kg

    The HX711 library computes get_units() = raw_counts / scale, so raising the scale factor lowers the reported value, and lowering it does the opposite. If the reported net weight is too high, the ratio is above 1 and new_calibration goes up, which brings the output down. If it's too low, the ratio is below 1 and new_calibration goes down, which brings the output up.

    Example: old_calibration = 2280, platform_reading_kg = 0.3, and reported_weight_kg = 13.3 with a 10 kg reference. The net reported weight is 13.0 kg (30 % high), so new_calibration = 2280 × 13.0 / 10.0 = 2964. Set hx711_calibration = 2964 in Notehub and force an inbound sync. Then set reset_state = 1 and force a second inbound sync to throw out the current partial window, since it holds readings taken under the old calibration factor. Before you move on, run one more full-window known-mass test with the platform load undisturbed and confirm the result is within ±0.5 kg. The reset fires once. You can leave reset_state=1 in place or remove it, and you don't need to do anything else to prevent repeated resets.

  2. Platform tare (zero offset).

    a. Once scale-factor calibration checks out, remove the reference mass and leave only the empty stand platform, undisturbed, for one full summary window. Record weight_kg from that Note. That's the platform dead-load.

    b. Set hx711_zero_offset_kg in Notehub to that value and force an inbound sync. Then set reset_state = 1 and force a second inbound sync to start a clean verification window. From here on, weight_kg readings cover only the hive body and its contents, referenced to zero with the empty stand. Confirm that the first full-window empty-platform summary reports approximately 0.0 kg (typically within ±0.2 kg for this load cell class). The reset fires once. You can leave reset_state=1 in place or remove it, and later wakes won't repeat the reset.

    Important: hx711_zero_offset_kg only corrects the static dead-load. The firmware doesn't compensate for load-cell temperature drift, and alloy-steel shear-beam cells drift slightly with temperature. For seasonal outdoor deployments, re-check the offset once a season or after a big change in ambient temperature.

    Relative vs. absolute weight: If you skip the tare procedure, weight_kg includes the platform dead-load and doesn't represent true hive mass. The weight_delta field and the weight_drop alert are relative measurements, so they stay meaningful whether or not the tare offset is set.

  3. Restore the production interval. Set report_interval_hr back to 24 (or your target production value) in Notehub and force a final inbound sync. Then set reset_state = 1 and force one more inbound sync to start a clean first daily window. The firmware fires the reset once and ignores any reset_state=1 readings after that. You can leave reset_state=1 in Notehub or remove it before field deployment. Either is safe, and the device won't reset its window on the first weekly inbound sync.

  4. Breathe on the SHT31-D sensor and check that the temperature and humidity fields rise in the next summary Note.

  5. Speak clearly into the microphone and check that zcr_avg, rms_avg, and peak_avg show up in the summary. Audio is only captured once per summary window, so either watch the debug output on the Notecarrier CX debug jack (ST-LINK serial, see §7) or rely on the shortened 1-hour report_interval_hr bench run to confirm the values quickly. With DEBUG_SERIAL enabled in apiary_hive_monitor_helpers.h, [APP] Summary sent prints the sample count and all three audio feature values. Restore production defaults before field deployment.

  6. Alert pipeline validation. Two alert rules make reliable bench tests:

    • Temperature path (instant, no additional equipment). During indoor bench testing the SHT31-D reads ambient room temperature, typically 20–24 °C, which is already below the default temp_low_c threshold of 32 °C. So a temp_anomaly alert fires on the first wake cycle after commissioning without any configuration change. Use it to confirm the full alert path (host → Notecard → Notehub → route) works before you move on to field deployment. After that first alert, the 60-minute cooldown (ALERT_COOLDOWN_MIN) suppresses repeats, so reset the device or wait out the cooldown if you want a second confirmation.

    • Weight-drop path (physical mass removal required). The weight_drop rule compares the current weight to weight_first_kg, the first valid reading of the current summary window, not to the previous 15-minute sample. If the platform mass hasn't actually changed since the window started, lowering weight_alert_kg_drop to a small value and waiting won't fire an alert. To test this rule deterministically, let the unit finish at least one full wake cycle so weight_first_kg is anchored. Then physically remove a calibrated mass from the platform that exceeds the configured threshold (for example, take off a 2 kg test weight while weight_alert_kg_drop is at the production default of 2.0). A weight_drop alert should show up in Notehub within the next 15-minute sample cycle. Put the mass back and confirm later weight readings return to near the baseline before you call the test complete.

Using Mojo to validate power behavior. During bench commissioning, the Blues Mojo coulomb counter sits inline between the Sunny Buddy LOAD+ output and the Notecarrier CX +VBAT rail. Run a STEMMA QT / Qwiic cable from Mojo's Qwiic port to the Notecarrier CX Qwiic connector, and the Notecard can relay Mojo's cumulative mAh tally when you send card.power requests from the blues.dev In-Browser Terminal. Here's the expected current draw by phase:

PhaseFigureSource
Host + sensors active, weight + temp cycle (no audio)~15–30 mA, ~5–8 s/cycleWhole-device estimate
Host + sensors active, weight + temp + audio cycle~20–40 mA, ~6–9 s/cycleWhole-device estimate (audio adds ~5–30 mA × 0.75 seconds)
Notecard low-power idle (between sessions, host in STOP2)~8–20 µA, plus ~1–2 µA for the STM32L433 in STOP2Notecard datasheet; STM32L4 datasheet
Cellular session (BG95-S5 modem)~250 mA avg, with brief peaks up to ~2 A for a few ms on a 2G burstNotecard datasheet
Skylo NTN satellite session~250 mA avg (same magnitude as a cellular session)Notecard datasheet
Host in STOP2, Notecard low-power idle + Sunny Buddy quiescent~100–400 µA typicalWhole-device estimate

The published Notecard figures come from the Notecard for Skylo datasheet. The whole-device estimates include the Notecarrier CX regulator and Sunny Buddy quiescent draw, so validate them with Mojo on your own assembly.

On a unit that's sleeping correctly, Mojo shows a brief 5–8 second active spike every 15 minutes and a longer cellular spike once every 24 hours. If you see a continuous draw over 20 mA instead, the host isn't entering STOP2. Check the ATTN→D9 jumper on the header, and confirm the firmware was built with USB support set to None (usb=none). If there's no cellular spike in 25 hours, check the hub.set outbound cadence and confirm that the device has associated with a Notehub project.

Since the unit runs on solar, the shape of the trace matters more than the absolute mAh number. The bench measurement still earns its keep as a regression test. If a firmware change doubles the sleep-phase current, the Mojo trace shows it right away, before the unit ever goes out to a remote yard.

10. Troubleshooting

SymptomLikely CauseCheck
No Notes appear in Notehub after 48 hoursNotecard isn't associated with the project, or the first-boot config failedMake sure PRODUCT_UID is set correctly, and look in the Notehub console for any device events. Force a hub.sync from the terminal to trigger association.
Continuous temp_anomaly alerts indoorsSHT31-D reading room temperature, which is below the default temp_low_c = 32 °CThat's expected during bench testing, and the alerts confirm the alert path works. Ignore them or lower temp_low_c during commissioning. They'll stop once the unit is deployed in a warm hive.
Weight readings are negative or too highCalibration scale factor not set, or platform tare offset is wrongRun the known-weight calibration procedure in §9 step 1. Confirm that hx711_calibration and hx711_zero_offset_kg are set as Notehub environment variables.
Weight doesn't change between summaries, or only changes erraticallyLoad cell disconnected, or HX711 powered down before sleepMake sure all four load cell wires (E+, E-, A+, A-) are connected to the HX711. Check that the D5/D6 GPIO pins aren't shorted or held low continuously. Confirm the HX711 sleep command isn't being called too early.
Audio features always show -9999 in summariesMicrophone disconnected, amplifier unpowered, or MAX9814 output clipped/floatingCheck the A0 connection from the MAX9814 to the Notecarrier CX, and make sure the MAX9814 Vin and GND are connected to the 3.3 V rail. Speak clearly into the microphone during the audio sample window, which happens on the first wake of each summary window and shows up in the debug output if DEBUG_SERIAL is enabled.
Mojo shows a continuous draw over 20 mA with no 15-minute patternHost never sleeps, because the ATTN→D9 jumper is missing or the firmware was built with USB CDC enabledConfirm the jumper between ATTN and D9 on the Notecarrier CX header (§5) and that the build used USB support: None (usb=none, see §7). With the USB CDC stack enabled and no USB host attached, the host leaves STOP2 within a millisecond. Check the DEBUG_SERIAL output on the debug jack, where [APP] ATTN sleep failed means ATTN never reached D9.
Satellite (NTN) never transmits, even with a sync:true alertInitial cellular/WiFi sync never completed, card.transport not set to an ntn method, or antenna/sky-view issueThe device has to complete at least one successful cellular or WiFi sync (which registers templates and downloads ephemeris) before NTN is enabled, and card.transport must be wifi-cell-ntn (notecardConfigure() sets it on first boot). Bring the unit into cellular coverage and force a hub.sync from the In-Browser Terminal. Once that sync completes, alerts with sync:true fall back to satellite when cellular isn't available. Make sure the Skylo-certified MAIN antenna is mounted outdoors with a clear view of the sky (the southern sky in the northern hemisphere).
Device claims to Notehub but doesn't pull environment variablesInbound sync cadence is too long (10080 minutes = 1 week by default)During commissioning, force an immediate inbound sync by sending {"req":"hub.sync"} from the Blues In-Browser Terminal. The device pulls environment variable changes on the next scheduled inbound or after a manual sync. §6 step 4 covers the commissioning settings.

11. Limitations and Next Steps

This reference design covers a single hive with a single load cell, exposed PCB-style sensors, and a heuristic acoustic threshold. That's fine for a POC, but it isn't ready for an unattended multi-year orchard deployment yet. The list below lays out the limits that come with that scope. It starts with the Li-ion thermal limits that matter most for outdoor apiculture and ends with the production paths that turn this into a fleet-grade hive scale.

Simplified for the POC

Each of these was a deliberate call to keep the POC simple, from the Li-ion thermal limits down to the one-hive-per-device boundary. A production deployment will revisit them with a safer battery, a richer model, or another sensor.

Li-ion battery thermal limits: safety and reliability. Lithium-ion cells, the chemistry of the Adafruit #354 18650 pack specified in §4, must not be charged below 0 °C (lithium plating can cause an internal short) or above approximately 45 °C (faster cycle-life degradation and, at extremes, thermal runaway). The SparkFun Sunny Buddy (LT3652) doesn't use a battery-thermistor input in its default board configuration, so it doesn't gate charging on temperature. In practice, that means:

  • Freezing mornings: The solar panel will try to charge the battery at ambient temperature. In apiaries that see sub-zero nights in spring or autumn, the charger pushes current into a cold cell. At best that degrades capacity, and in severe cases it's a safety risk. A production deployment should use a charger with NTC thermistor supervision or add a simple low-temperature charge-inhibit circuit.
  • Sun-heated enclosures: A polycarbonate enclosure on a south-facing hive stand in direct sun can easily hit 50–60 °C inside on a summer afternoon, well above the safe charging ceiling. In production, use a metal enclosure with thermal mass and a sun shield or white enclosure finish, and check temperatures with a data logger before any long-term deployment.
  • Capacity in cold weather: Li-ion usable capacity drops to 60–80 % at 0 °C, and further below freezing. The 4400 mAh reserve calculations in §4 assume room-temperature performance, so scale the estimated reserve down for cold-climate apiaries.
  • Production alternatives: For year-round outdoor apiary deployment, consider a LiFePO₄ pack and charger/BMS combination rated specifically for your deployment climate. LiFePO₄ handles high temperatures better than Li-ion, but safe charging limits vary a lot with the specific chemistry, cell construction, and BMS design. Many packs still prohibit charging below 0 °C without an integrated heater or a low-temperature-rated BMS. Don't use chemistry-wide temperature numbers in place of the datasheet for the pack you plan to use. Pick a battery pack and charger whose rated charge and discharge temperature windows cover the full seasonal temperature swing at your deployment site, and verify those limits in the manufacturer's datasheet before you commit to a production build. For winter-dormant hives that don't need solar recharge, a primary lithium cell bank is another option.

Audio analysis is heuristic, not ML-based. Zero-crossing rate and RMS energy are established acoustic features in beehive research, but the firmware applies simple static thresholds instead of a learned colony baseline. The audio_anomaly alert means the colony's sound has measurably changed from a typical settled-colony signature, and it is not a diagnosis. The cause could be defensive arousal, post-swarm disruption, environmental noise (nearby equipment, traffic), or some other disturbance, and only a physical inspection can sort out which. A naturally more vocal colony (Carniolan vs. Italian strains, hot weather, nearby traffic) may fire false positives. A colony that's genuinely quieter than the default threshold may never fire an alert, even when conditions call for attention. You can tune this per hive with the audio_zcr_alert env var, but doing it well takes a few weeks of observation. More specific hypotheses about queenlessness, swarming pressure, or defensive state need richer acoustic features, a learned baseline for that colony, and physical verification before you can draw any conclusion.

Load cell calibration is manual; absolute weight requires a tare step. Both the hx711_calibration scale factor and the hx711_zero_offset_kg platform tare have to be set experimentally (§9 has the procedure). Without the tare step, the weight_kg field includes the platform dead-load and doesn't represent true hive mass. The relative fields (weight_delta and the weight_drop alert) stay valid whether or not you've calibrated. The firmware has no temperature compensation for the load cell, and alloy-steel shear-beam cells drift slightly with seasonal temperature swings, which can add a small systematic offset over the year.

Single load cell, single-end weighing. The design weighs the hive from one end, which is accurate as long as the load cell is centered under the stand. An uneven hive body (a tilted entrance board, or an added super on one side) can throw in a systematic reading offset. A proper hive scale uses 4 corner cells with a Wheatstone bridge, and this POC uses one cell to keep things simple.

Satellite (NTN) operation caveats. The same Notecard for Skylo runs the same firmware everywhere, but when it falls back to the satellite link, the NTN path behaves differently in ways you need to plan for. The device has to complete at least one successful Notehub sync over cellular or WiFi before NTN transmissions will work. Notecard needs registered templates, time, and location data to find satellites efficiently, so a unit deployed straight into a cellular dead zone won't transmit until someone brings it into terrestrial coverage for a moment. Over satellite, a sync:true alert gets priority for the next Skylo session, but finding a satellite and finishing the transmission takes several minutes, not seconds. Each Note has to fit within the NTN 256-byte maximum, which the compact templates here do. Each inbound env-var sync also uses ~50 bytes of the bundled 10 KB satellite allocation, which is why inbound defaults to weekly. For the satellite link to work, the MAIN antenna has to be outdoors with an unobstructed view of the sky (in the northern hemisphere, the southern sky toward the equator). Skylo coverage depends on region, so verify coverage for your deployment area (see satellite best practices).

No audio recording. The firmware only computes features and never stores or transmits raw audio. You can't diagnose a specific anomaly from the cloud alone, so it takes a follow-up physical inspection. The feature scores narrow down the likely cause, but they don't replace the beekeeper's judgment.

Mojo is bench-only in this POC. The firmware doesn't read the Mojo's LTC2959 coulomb counter over I2C. Mojo is only a bench instrument for validating power draw during development. Adding a batt_mah field to the daily summary would be straightforward.

Single hive per device. One Notecarrier CX manages one hive, so a yard with 50 hives needs 50 units. A reasonable production extension would be a multi-drop I2C bus with individually addressed sensors and a single Notecard handling the whole yard.

Production Next Steps

Once a yard has the basic hive scale running, these extensions turn it into a fleet-grade instrument. They're listed roughly from the accuracy gains you'd want first to the deeper analytics and fleet-update work.

Per-colony audio baseline learning records a rolling 30-day ZCR distribution for each hive and only alerts when a reading lands more than two standard deviations from that colony's own baseline, instead of using a fixed threshold.

A multi-cell weight platform with four corner cells in a full Wheatstone bridge delivers platform-grade accuracy and gets rid of tilt errors.

4-wire cable waterproofing pots the load cell cable exit and every external sensor penetration in marine-grade epoxy so they hold up for years outdoors.

A Varroa mite proxy is within reach. Some research groups have found spectral signatures in the 100–300 Hz band that correlate with high Varroa loads, and adding a narrow-band FFT bin to the audio features would surface that indicator with no extra hardware.

Outboard DFU through Notecard Outboard Firmware Update lets you ship new host firmware images to a whole yard fleet over cellular without a truck roll to each hive. That covers bug fixes, better audio scoring algorithms, new threshold logic, or support for more sensors. Notehub environment variables already handle operational thresholds and calibration values today, and ODFU covers the separate job of updating the compiled firmware logic itself.

12. Summary

The beekeeper who used to find out about a departed swarm three days after the fact now gets a daily weight-trend notification, plus an immediate alert the moment the hive loses 2 kg, wherever the colony happens to live in the orchard, meadow, or forest edge. Three sensors and a single Notecard for Skylo, with cellular, Skylo satellite, and WiFi on one module, turn the hive stand into a continuously monitored asset. It reaches cellular where there's a tower and the Skylo satellite network where there isn't, and there's nothing to swap. Sampling runs every 15 minutes, the summary goes out once a day, and threshold alerts skip the transmit timer entirely. Long-lived solar operation is realistic on the energy budget described in §4 and §11, but only after you work through the commissioning steps in §9: Mojo power validation, load-cell calibration, and a battery chemistry rated for the deployment climate. For a commercial beekeeper managing dozens of yards across a region, that's the difference between a minor nuisance and a significant economic loss, and it's the gap cellular-first IoT was built to close.

On This Page

  • 1. Project Overview
  • 2. System Architecture
  • 3. Technical Summary
  • 4. Hardware Requirements
  • 5. Wiring and Assembly
  • 6. Notehub Setup
  • 7. Firmware Design
    • Modules
    • Sensor reading strategy
    • Event payload design
    • Low-power strategy
    • Retry and error handling
    • Key code snippet 1: compact template definition
    • Key code snippet 2: two-pass streaming audio feature extraction
    • Key code snippet 3: sleeping until the Notecard raises ATTN
  • 8. Data Flow
  • 9. Validation and Testing
  • 10. Troubleshooting
  • 11. Limitations and Next Steps
    • Simplified for the POC
    • Production Next Steps
  • 12. Summary

Resources

  • GitHub
  • Request More Info
Can we improve this page? Send us feedback
© 2026 Blues Inc.
© 2026 Blues Inc.
AboutDocsAPI ReferenceTermsPrivacy