Skip to content

Instantly share code, notes, and snippets.

@Tech500
Last active August 7, 2026 02:57
Show Gist options
  • Select an option

  • Save Tech500/26b9f16bd595f98c8c41618e758c92f0 to your computer and use it in GitHub Desktop.

Select an option

Save Tech500/26b9f16bd595f98c8c41618e758c92f0 to your computer and use it in GitHub Desktop.
NPPK2 Observations of SX1262 Channel Activity Detection + Wake on Radio + Deep Sleep: BME280 Node

Nordic PPK2 Power Observations — HSM IV Outside Node

Measurement conditions: USB CDC disabled on boot. WOR preamble detection via CAD (Channel Activity Detection, Interrupt) — the project's current method, superseding the earlier autoDutyCycle approach used in the original Hackster write-up. Values pulled from the PPK2 windowed Selection box, except Image 1 (power-on), which has no selection box and reflects the full 1-second WINDOW capture.

Story arc: Power-on → Active spike → Average (active + sleep) → Sleep duration → WOR wake (manually triggered) → Continuous duty-cycle stream.

Path: Images/New/ on Tech500/Heating-System-Monitor-IV (all 6 URLs verified live)
Click image to enlarge.

Source: EoRa-S3-900TB


Image 1 — EoRa-S3-900TB, Power-On

Image 1

Caption: EoRa-S3-900TB, power-on transient — 33.08 mA average, 91.08 mA max, over 1.000 s (33.08 mC charge). Full-window reading; no Selection box used.


Image 2 — EoRa-S3-900TB, Channel Activity Detection (CAD), Active Spike

Image 2

Caption: Active current spike, segment — 7.43 mA average, 14.23 mA max, over 11.22 ms (83.34 µC charge).


Image 3 — EoRa-S3-900TB, Average current of Deep Sleep (Active + Sleep segments of Duty Cycle)

Image 3

Caption: Deep Sleep, active+sleep duty cycle average — Selection: 38.19 µA average, 11.71 mA max, over 5.087 s (194.27 µC charge).


Image 4 — EoRa-S3-900TB, Sleep Duration of segment of Duty Cycle

Image 4

Caption: Sleep-duration segment — Selection: 21.93 µA average, 23.06 µA max, over 5.057 s (110.91 µC charge).


Image 5 — EoRa-S3-900TB, waking up from receiving wake on radio (WOR) and running sketch setup.

Image 5

Caption: LoRa WOR wake, manually triggered — 40.64 mA average, 105.44 mA max, 3.259 s (132.45 µC charge). EoRa-S3-900TB waking and running setup.

Image 6 — EoRa-S3-900TB, CAD Duty Cycle Stream (Continuous Spike Train)

Image 6

Caption: Continuous stream of duty cycle events over a 1-minute window — 37.19 µA average, 15.17 mA max, 2.23 mC charge (full WINDOW, no selection made). Illustrates cycle-to-cycle consistency of the CAD-based Interrupt, duty cycle; not intended as a new headline current figure, but as corroborating evidence for Image 3's Selection-box average.

Observations from this capture:

  • Peak spike amplitude was confirmed zoom-invariant — checked at 10ms, 100ms, and 1-minute scales, with each spike reading the same true peak regardless of view. This rules out chart downsampling as the source of amplitude variation between individual spikes.
  • The modest amplitude spread seen between spikes (~10–15 mA peak in this WINDOW view) is therefore a real characteristic, consistent with expected CAD detection-timing variance — how far into a CAD scan window the preamble happens to be detected can affect how much settle-time is captured before steady-state RX current is reached.
  • The µA-scale average was observed to vary continuously between a high of ~40 µA and a low of ~21 µA during live viewing — closely matching Image 3's Selection average (38.19 µA, active-adjacent) and Image 4's Sleep Portion average (21.93 µA, sleep floor). This is good corroboration that the individual snapshot captures (Images 3 and 4) are representative of the node's real operating range, not outliers.

Summary Table

# Description Avg Max Duration Charge
1 Power-on (full window) 33.08 mA 91.08 mA 1.000 s 33.08 mC
2 Active spike 7.43 mA 14.23 mA 11.22 ms 83.34 µC
3 Average (active + sleep, selection) 38.19 µA 11.71 mA 5.087 s 194.27 µC
4 Sleep duration (selection) 21.93 µA 23.06 µA 5.057 s 110.91 µC
5 WOR manually triggered 40.64 mA 105.44 mA 3.259 s 132.45 µC
6 CAD duty cycle stream (1-min window) 37.19 µA 15.17 mA 60.0 s 2.23 mC

Battery Chemistry Considerations

Self-discharge rate is one of the biggest levers on real-world battery life for a low-draw, multi-year outdoor deployment — at these µA-scale currents, the battery's own internal leakage can rival or exceed the node's active power draw over time.

Chemistry Typical Self-Discharge Cold-Temp Performance Rechargeable Notes
LiPo (Li-ion polymer) — current choice ~2–3%/month Degrades below ~0°C; capacity drops noticeably in freezing conditions Yes Good energy density, widely available, but needs protection circuitry and isn't ideal for an unheated outdoor enclosure through winter
LiFePO4 (LFP) ~1–3%/month Better cold tolerance than standard LiPo (usable to roughly -20°C) Yes Lower energy density (more physical volume for same mAh), but longer cycle life and better thermal/safety margin — a strong candidate for the outdoor node
Li-SOCl2 (Lithium Thionyl Chloride, primary) <1% per year Excellent — rated to -40°C in many parts No (primary/disposable) Very low self-discharge makes it well-suited to multi-year, low-duty-cycle deployments like this one; tradeoff is you replace rather than recharge the cell
NiMH (standard) ~20–30%/month Moderate; capacity drops in cold Yes Self-discharge alone would likely dominate your battery-life budget at these current levels — not a good fit here
NiMH (low self-discharge, e.g. Eneloop-style) ~0.1–1%/month Better than standard NiMH Yes Viable, but still generally lower energy density than LiPo/LFP for the same size
Alkaline (primary) ~2–3% per year Poor below freezing — voltage sags significantly No Low self-discharge, but cold-weather voltage sag is a real risk for an outdoor node through winter

For this project specifically: given the outside node sits in a Stevenson screen exposed to real seasonal temperature swings, the two standouts are:

  • LiFePO4 — if you want to stay rechargeable, this trades a bit of energy density for meaningfully better cold-weather behavior and self-discharge than standard LiPo, without changing your overall power budget much.
  • Li-SOCl2 primary cell — if you're willing to give up rechargeability, the near-negligible self-discharge (<1%/year) means the CAD-based ~38.19 µA draw would dominate the battery-life calculation almost entirely, with self-discharge becoming a rounding error rather than a meaningful derating factor. Given your CAD-based numbers already put theoretical life in the 8–9 year range, a Li-SOCl2 primary cell could realistically make self-discharge nearly irrelevant to the final field-life number.

Worth weighing against your maintenance model — a primary cell means a physical swap eventually, while LiPo/LFP means periodic recharge access (relevant given the node's outdoor mounting).


Battery Life Calculation — CAD Duty Cycle + Event Driven WOR Wake

Overview

The HSM IV outside node has two separate power components:

  1. Background CAD/WOR listening current
  2. Event-driven WOR wake energy

The battery-life calculation must include both.

The important distinction:

The CAD duty-cycle measurement does not include a full ESP32-S3 wake and setup() execution. A WOR wake event only occurs when an actual blower OFF event is transmitted.


1. CAD/WOR Listening Duty Cycle

The SX1262 remains available for wake detection using:

  • Channel Activity Detection (CAD)
  • Interrupt wake
  • ESP32-S3 deep sleep between CAD checks

Measured PPK2 value:

CAD duty-cycle average = 38.19 µA

This measurement already includes:

  • CAD active periods
  • SX1262 sleep periods
  • ESP32-S3 deep sleep intervals

This represents the normal waiting state of the node.


2. WOR Event Wake Energy

A WOR wake occurs only when the blower OFF transmitter sends a valid WOR preamble.

The wake sequence includes:

  1. SX1262 detects preamble
  2. DIO1 interrupt wakes ESP32-S3
  3. ESP32-S3 boots
  4. Arduino framework starts
  5. setup() executes
  6. Sensors initialize
  7. ESP-NOW message is transmitted
  8. Node returns to sleep

Measured WOR Wake Event

PPK2 Image 5:

Average current = 40.64 mA
Duration        = 3.259 seconds

Charge Per WOR Event

Formula:

Charge = Current × Time

Calculation:

Charge = 40.64 mA × (3.259 seconds / 3600)

       = 0.0368 mAh per event

Each complete blower-triggered WOR wake consumes approximately:

0.0368 mAh/event

Example Calculation — 17 Blower OFF Events Per Day

Measured field activity:

Blower OFF events = 17 per day

Daily WOR Wake Consumption

0.0368 mAh/event × 17 events/day

= 0.6256 mAh/day

Convert daily event consumption to average current:

0.6256 mAh/day ÷ 24 hours

= 0.0261 mA

= 26.1 µA

Total Average Current

Add the background CAD duty-cycle current:

CAD standby current     = 38.19 µA
WOR event contribution  = 26.10 µA

Total average current:

38.19 + 26.10

= 64.29 µA

Battery Life Example — 3000 mAh Battery

Formula:

Battery Life (hours) = Battery Capacity / Average Current

Calculation:

Battery Life = 3000 mAh / 0.06429 mA

             = 46,664 hours

             = 1,944 days

             ≈ 5.3 years

This is the theoretical battery life assuming:

  • 3000 mAh usable capacity
  • no battery self-discharge
  • no temperature losses
  • no regulator losses

Event Rate Dependency

The actual battery life depends on HVAC activity.

The calculation model is:

Average Current =
    CAD standby current
    +
    (WOR wake charge × blower events/day ÷ 24 hours)

Examples:

Blower OFF Events/Day Average Current
0 38.19 µA
1 ~39.7 µA
10 ~53.5 µA
17 ~64.3 µA
25 ~76.5 µA
50 ~114.8 µA

Important Methodology Note

The earlier battery estimate using only 38.19 µA represented the maximum theoretical life of the node while waiting for a wake event.

The real-world value is lower because blower activity causes complete ESP32-S3 wake cycles.

The final battery-life estimate should therefore always include:

  • measured CAD standby current
  • measured WOR wake charge
  • actual blower event frequency

This makes the battery estimate representative of the real HSM IV operating environment.


Summary

The HSM IV outside node battery life is not determined only by the low-power CAD listening current.

The actual field life is a combination of:

  • SX1262 CAD/WOR duty-cycle consumption
  • ESP32-S3 deep sleep current
  • complete WOR wake and setup() execution
  • number of blower OFF events per day

Using measured PPK2 values:

  • CAD duty-cycle current: 38.19 µA
  • WOR wake energy: 0.0368 mAh/event
  • Example activity: 17 events/day

The calculated average current is:

64.29 µA

For a 3000 mAh battery:

≈ 5.3 years theoretical life

Actual field life will depend on battery chemistry, temperature, self-discharge, and HVAC operating conditions.


** Derate for real-world losses.** Theoretical figures assume 100% usable capacity and zero self-discharge, which never holds in practice. Typical derating factors for a 3000mAh LiPo:

Factor Typical Loss
LiPo self-discharge (~2–3%/month) 15–25% over multi-year life
Voltage regulator/LDO quiescent draw 5–15%
Cold-weather capacity reduction (outdoor node) 10–20% seasonal
Cell aging / capacity fade over years 10–20% by year 2–3
Safety margin (don't run cells to 0%) ~10% reserved

Applying a combined 40–55% derating range to the theoretical figure gives a realistic 46–67 month estimate — consistent with the range already published in the Hackster write-up.


Acknowledgements

This project was the result of a collaborative engineering effort involving both hands-on experimentation and AI-assisted development. Each AI assistant contributed in different ways throughout the project.

  • Claude – Lead AI for all aspects of the project. Helped maintain technical focus, reviewed the evolving documentation for clarity and consistency, and provided extensive assistance in coding, organizing, and refining the final Markdown document.

  • Google Gemini – Provided valuable guidance during the migration to ESP32 Arduino Core 3.3.10, helping identify and avoid legacy code patterns from earlier ESP32 core releases. Gemini also contributed to development discussions involving SX1262 Channel Activity Detection (CAD), Wake-on-Radio (WOR), and ESP32-S3 Deep Sleep integration.

  • ChatGPT – Assisted throughout firmware development, debugging, architecture discussions, RadioLib integration, power optimization, Nordic PPK2 measurement interpretation, battery-life analysis, and technical review of the final documentation.

  • GitHub Copilot – Assisted with firmware implementation, code completion, and day-to-day development within the programming environment.

  • Jan Gromeš – Special thanks for the outstanding RadioLib library!

The successful implementation of an ESP32-S3 Deep Sleeping Wake-on-Radio node using the SX1262 and RadioLib was made possible through this collaborative process. While the hardware design, firmware integration, measurements, testing, and final engineering decisions were performed by the author, the insights provided by each AI assistant significantly accelerated development and helped improve the quality and accuracy of the final project.


"Project not possible without everyone's help."

Note: Two-WOR-trigger timing capture excluded — suspected variance from manual push-button hold time made the measurement unreliable. Five images kept the narrative focused on a single clean duty-cycle story.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment