Skip to content

Heartbeat

Trenston Ricks edited this page Jun 2, 2026 · 1 revision

Heartbeat

Heartbeat is a two-mode transmission pattern for sensor nodes. A node can send small heartbeat packets most wake cycles, then send a full data packet every Nth wake cycle. This reduces radio traffic and power use in battery deployments.

Purpose

Use heartbeat when a deployment needs regular "still alive" updates but does not need a full sensor payload every wake cycle.

Normal work still runs on schedule. Heartbeat cycles only send a smaller status packet.

Heartbeat Packet

  • Packet type.
  • Device ID from the manager name and instance.
  • Battery voltage, rounded to 2 decimal places.
  • Optional UTC and local timestamps when a Hypnos instance is provided.
  • Optional custom fields added before transmission.

Wake Cycle Behavior

On each wake cycle, getHeartbeatFlag() decides whether to run normal work or send a heartbeat. It uses currentInterval to count cycles and normalWorkInterval to decide when full work should run.

If normalWorkInterval is 4, the pattern is:

Cycle: 1   2   3   4   1   2   3   4
Work:  HB  HB  HB  NW  HB  HB  HB  NW

HB means heartbeat. NW means normal work.

Configuration State

currentInterval

Tracks how many cycles have elapsed since the last normal work transmission. It starts at 0, so the first cycle always runs normal work. It increments on heartbeat cycles and resets to 1 on normal work cycles.

normalWorkInterval

Defines how many cycles occur between normal work transmissions. If it is set to 1 or less, getHeartbeatFlag() always returns false and every cycle runs normal work.

Sketch Setup

  • Create the Heartbeat object after the Manager and Hypnos objects, because those are passed into the Heartbeat constructor.
  • Pass a LoRa object to the constructor only when heartbeat packets should transmit over LoRa.
  • Pass normalWorkInterval to control how often full normal work runs.
  • LoRa is optional. Without a LoRa instance, transmit() and transmitCustom() return false gracefully.

Future implementations can expand heartbeat transmission beyond LoRa.

API Reference

getHeartbeatFlag()

Returns false for normal work or true for heartbeat.

If normalWorkInterval <= 1, heartbeat is disabled. If currentInterval is 0 or has reached normalWorkInterval, the counter resets and normal work runs. Otherwise, the counter increments and heartbeat runs.

makeHeartbeat()

Builds the heartbeat payload for a heartbeat cycle. Call this once before transmit().

createDoc()

Builds the JSON document stored in heartbeatDoc.

addData(module, dataName, data)

Adds a string value under a module key in heartbeatDoc. It creates the module object when needed and logs a warning if the 300-byte document is full.

getDoc()

Returns a reference to heartbeatDoc so code can inspect or modify the JSON before sending.

transmit(destinationAddress)

Sends heartbeatDoc over LoRa using Loom_LoRa::send(). Returns false if no LoRa instance was provided.

transmitCustom(destinationAddress, document)

Sends an arbitrary JSON document instead of heartbeatDoc. This is useful when code needs heartbeat scheduling but a custom payload.

Clone this wiki locally