Add Pole-to-Pole Satellite Connectivity with Starnote for Iridium

Blues Developers
What’s New
Resources
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.io
Shop
Docs
Button IconHelp
Support DocsNotehub StatusVisit our Forum
Button IconSign In
What’s New
Resources
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.io
Shop
Docs
homechevron_rightBlogchevron_rightInterrupt-Driven IoT with the Notecard ATTN Pin

Interrupt-Driven IoT with the Notecard ATTN Pin

Interrupt-Driven IoT with the Notecard ATTN Pin banner

July 14, 2026

Unnecessary polling is where battery-powered IoT quietly bleeds power. Here's how Notecard's ATTN pin lets a host MCU remain in deep sleep at µA levels and wake only when something actually happens.

  • Low Power
  • Notecard
  • Firmware
Rob Lauer
Rob LauerSenior Director of Developer Relations
email

Picture a battery-powered device out in a remote field. It reads a sensor a few times a day, occasionally gets a command from the cloud, and otherwise does nothing. Plenty of devices like this are programmed to wake every few seconds, ask "is there anything for me?", find nothing, and go back to waiting. Multiply that across a fleet (and months in the field), and you've spent a surprising amount of battery producing the answer: "nope, still nothing!".

That polling loop is one of the quietest ways to drain a battery, and much of that waste is avoidable. The good news is the Blues Notecard has a pin built for exactly this: ATTN. Instead of waking on a timer to check, your host can wake only when there's actually something to do. This article covers how this functionality works and when to use it.

Event sources — an inbound Note, motion, or a timer — feed into a Notecard, which raises its ATTN pin to wake a Host MCU that is otherwise asleep.

Why Polling is the Hidden Power Drain

It's easy to assume the radio is where all your battery power goes. However, in a well-designed Notecard product, it usually isn't. Notecard itself idles at roughly 8–18 µA @ 5V depending on the model (Cellular, Satellite, LoRa, or WiFi), and the Low-Power Firmware Design guide is blunt about where the real draw lives: in most battery-powered designs, the host MCU, not Notecard, is the largest contributor to idle current.

So one of the most effective things you can do for battery life is keep the host in true deep sleep as much as possible (e.g. STM32 STOP/STANDBY, ESP32 deep sleep, Nordic nRF52 System OFF), drawing microamps or less. A polling host can sleep between checks, but every poll is still a wake, a little I/O, and a return to sleep. Those unnecessary wakeups drive up its average current even when there's nothing to report.

The fix is to flip the relationship. Instead of the host repeatedly asking Notecard for news, let Notecard tell the host when there's news to act on. That's exactly what ATTN is for.

Notecard's Hardware "Tap on the Shoulder"

ATTN is a dedicated output pin on Notecard that you configure through the card.attn API. Its job is to physically signal your host that an event of interest happened, so the host can sleep deeply the rest of the time. You can use it two ways:

  1. Interrupt-driven wake. Notecard fires the pin when an asynchronous event happens, and your host (already asleep in its own deep-sleep mode) wakes on that notification.
  2. Power-off sleep. Notecard drives the pin LOW for a set interval. If that pin is wired to the host's enable input, it cuts host power entirely until the pin goes HIGH again.

These map to two card.attn mechanisms: arm mode and sleep mode. They solve related problems very differently, and choosing between them is most of the design decision.

The arm/fire Cycle

When you arm ATTN, Notecard drives the pin LOW, and when a monitored event occurs (or an optional timeout elapses), the pin goes HIGH. That low-to-high transition is your wake signal: wire ATTN to a host GPIO and configure the MCU to wake on it. On some MCUs that's a rising-edge interrupt; on others it's a level-based deep-sleep wake source (more on that below). Either way, your host can stay asleep until Notecard has something worth waking up for.

The events you can arm on are what make this more interesting than a plain timer:

  • files — a Notefile has changed, usually in the form of an inbound Note (.qi) arriving from the cloud. This is your "the server has a command for you!" wake.
  • motion and motionchange — the onboard accelerometer has detected movement, or the motion state flipped between "moving" and "stopped."
  • location — the GPS module got a position fix.
  • env — an environment variable changed.
  • connected and signal — Notecard connected to the network, or received an inbound signal.
note

Once the pin fires, it stays HIGH until you re-arm it. Your host code follows a simple loop: wake up on the edge, do the work, re-arm the pin, then go back to sleep. However, be sure to not skip that re-arm step! If you do, the pin never fires again, which is the most common reason an interrupt-driven design works only once.

Wiring the ATTN pin: a Notecard connects to a Host MCU over one ATTN line, wired either to a GPIO to wake on interrupt or to EN to cut power. Below, the ATTN signal stays low while armed, steps high when it fires, and stays high until re-armed.

An Implementation Walkthrough

These two mechanisms lead to two different paths: Path 1 keeps the host powered and wakes it on an event (arm mode) while Path 2 cuts the host's power entirely between wakes (sleep mode).

Path 1: Interrupt-Driven Wake (arm mode)

Use this when a device mostly sleeps but must react promptly to an event, like a command arriving from the cloud. The host powers itself down into its own deep-sleep mode and wakes on the ATTN change.

Wire ATTN to a host GPIO

Connect Notecard's ATTN pin to an interrupt-capable GPIO on your host. That's the only connection this path needs as the host keeps its own power and manages its own sleep mode.

Configure Notecard

Associate Notecard with your Notehub project and set a sync mode. For inbound events, sync mode matters more than people expect. In periodic mode, Notecard only pulls inbound data on its inbound schedule, so a files interrupt on an inbound Note can't fire until the next inbound sync. If you need a command to reach the device as fast as possible, use continuous mode with sync set to true:

{
  "req": "hub.set",
  "product": "com.your-company.your-name:your_project",
  "mode": "continuous",
  "outbound": 30,
  "sync": true
}
note

That responsiveness isn't free: a continuously-connected radio draws far more than one that wakes on a schedule. So weigh the whole power budget, not just the host. Sleeping the host is a big win when the device is mostly idle, but if you switch to continuous mode purely to catch fast inbound commands, the added radio draw can outweigh what you saved by sleeping the host.

Arm the pin

Next, tell Notecard to watch a specified inbound Notefile and fire ATTN when it changes:

{
  "req": "card.attn",
  "mode": "arm,files",
  "files": ["data.qi"]
}

FYI you can arm on more than one trigger at once. An asset tracker, for example, might want to wake on either an inbound command or physical movement:

{
  "req": "card.attn",
  "mode": "arm,files,motion",
  "files": ["data.qi"]
}

The arm mode also accepts an optional seconds timeout. If no monitored event occurs within that window, the pin fires anyway, giving you a periodic fallback so the host still checks in during a long quiet stretch.

Sleep, Wake, and Re-Arm on the Host

The host firmware side is relatively straightforward. Point the MCU's wake source at the ATTN pin, then drop into deep sleep:

// NOTE: The deep-sleep entry itself is MCU-specific!
attachInterrupt(digitalPinToInterrupt(ATTN_PIN), onAttn, RISING);
// ... enter STOP / deep sleep here ...

When ATTN fires, the host wakes, works out what happened, acts on it, and re-arms before going back to sleep. Since you were watching a Notefile, that "what happened" step is usually a note.get request against data.qi to read whatever the cloud sent. Then you send another card.attn/mode:arm request and go back to sleep. That's the whole loop.

How you "drop into deep sleep" (and what you can assume when you wake) varies by host MCU. Two things change from chip to chip: how you arm the pin as a wake source, and whether your RAM survives the nap:

Host MCUDeepest practical modeRAM retained on wake?Arming ATTN as a wake source
STM32L4 (e.g. Blues Swan, Cygnet)STOP, via LowPower.deepSleep()YesAny EXTI-capable GPIO. LowPower.attachInterruptWakeup(pin, cb, RISING, DEEP_SLEEP_MODE). shutdown() goes lower but reboots.
ESP32 / ESP32-S3Deep sleep, via esp_deep_sleep_start()No, but RTC memory persistsesp_sleep_enable_ext0_wakeup(gpio, 1) on an RTC-capable GPIO (level-triggered), or ext1 for several.
Nordic nRF52System OFFNo, but RAM sections are retainableGPIO SENSE (a latched, level-based port event). System ON idle keeps all RAM.
warning

This ESP32 detail often trips people up: a plain attachInterrupt() does not wake the chip from deep sleep. You have to register ATTN as an RTC wakeup source before you sleep, and the pin has to be one of the RTC-capable GPIOs. This works precisely because ATTN stays HIGH after it fires.

It's important to note that the "RAM retained" column determines how you write your firmware to safely recover from sleep mode. On STM32 STOP, execution resumes on the line right after your sleep call with your variables intact, so the wake handler stays tiny. On ESP32 deep sleep or nRF52 System OFF, a wake is almost like a reboot: setup() runs from the top and ordinary globals are gone. You can still carry state across the gap, but you have to be deliberate about it, using ESP32 RTC slow memory (RTC_NOINIT_ATTR), an nRF52 retained-RAM region, an RTC backup register, or flash.

That storage doesn't have to be on the MCU, though! Notecard can hold it for you if write the state to a local-only .dbx database Notefile with note.add, then read it back on the next boot with note.get. A .dbx file never syncs, so it costs no cellular data. (The base64 payload helper in Path 2 below does the same job, but it's tied to card.attn sleep mode, where a LOW ATTN pin gates the host's power off, so it belongs there, not here where the host sleeps itself.)

Path 2: Power-Off Sleep (sleep mode)

Use this path for the lowest possible power draw, or for a purely periodic device. Instead of the host sleeping itself, Notecard drives the ATTN pin LOW for a set interval and cuts the host's power outright, then restores it when the interval ends.

This is the pattern from the Putting a Host to Sleep Between Sensor Readings sample app.

Wire ATTN to the host's EN pin

Connect ATTN to the host's enable (EN) pin instead of a GPIO. When Notecard pulls ATTN LOW, the host loses power, and when it goes HIGH again the host boots back up. If you're prototyping on a Notecarrier F, you can skip the jumper wire and set the FEATHER_EN DIP switch to the N_ATTN position, which routes ATTN to the Feather host's enable pin for you.

Put the Host to Sleep

The host asks Notecard to power it down with a request like this:

{
  "req": "card.attn",
  "mode": "sleep",
  "seconds": 3600
}

Because the host loses power and reboots on wake, any state you care about has to survive the outage. Notecard can hold it as a base64 payload (one option among MCU flash and external storage), and the note-arduino library wraps the encoding in convenience helpers:

void loop()
{
  globalState.cycles++;

  // Hand our state to Notecard and power down for an hour.
  NotePayloadDesc payload = {0};
  NotePayloadAddSegment(&payload, globalSegmentID, &globalState, sizeof(globalState));
  NotePayloadSaveAndSleep(&payload, 3600, NULL);
}

On the next boot, the host gets its state back with {"req":"card.attn","start":true} (or the NotePayloadRetrieveAfterSleep helper) and picks up where it left off. Since every cycle is a cold start, that restore runs on every wake.

Current draw over time. A polling host shows many repeated spikes and a large shaded energy area; an interrupt-driven host stays near zero and draws a single spike only when an event wakes it, for far less total energy.

Summary

Interrupt-driven wake through ATTN earns its keep when a device's real work is sparse and hard to predict, like a control valve waiting on a command, a tracker that only matters when it moves, or a sensor whose alarm line trips a Notecard AUX GPIO the moment a threshold is crossed. For strictly periodic work, like an hourly sensor reading, sleep mode's timer is simpler and lower-power.

To see the full pattern end to end, the Putting a Host to Sleep Between Sensor Readings sample has complete host firmware for the full sleep mode path, and the card.attn API reference documents every trigger available to you.

Grab a Blues Starter Kit, wire up that pin, and put a current meter on your host. The numbers tend to be convincing!

Happy hacking! 💙

Frequently Asked Questions

What is the Notecard ATTN pin?

ATTN is a dedicated output pin on Notecard that can physically signal a host microcontroller when something happens, such as an inbound Note arriving, a Notefile changing, motion being detected, or a timer elapsing. Wired to a host GPIO or enable pin, it lets the host stay in deep sleep and wake only on a real event instead of polling on a timer.

What events can wake a host through the ATTN pin?

Depending on the Notecard model, ATTN can fire on inbound Notes or Notefile changes, accelerometer motion, a change in motion state, a GPS position fix, an environment variable update, a successful cellular connection, an inbound signal, an AUX GPIO change, USB power events, and an elapsed timer. Notecard for LoRa supports a subset of these triggers.

What is the difference between card.attn arm mode and sleep mode?

In arm mode Notecard signals a host that manages its own sleep state, so whether execution and RAM survive a wake depends on that state (STM32 STOP keeps RAM; ESP32 deep sleep and nRF52 System OFF reset the host). In sleep mode Notecard holds the ATTN pin LOW for a set time; if you've wired ATTN to the host's enable or regulator input, that cuts host power entirely, so the host reboots on wake and must restore any state it needs from MCU flash, RTC-backed memory, or Notecard itself.

Do I need continuous mode to wake on an inbound Note?

For near-real-time inbound delivery, effectively yes. In periodic mode Notecard only pulls inbound data on its inbound sync schedule, so a file-based ATTN interrupt only fires after that sync. Continuous mode delivers inbound Notes sooner at the cost of higher radio power, so the right choice depends on how quickly you need to react.

In This Article

  • Why Polling is the Hidden Power Drain
  • Notecard's Hardware "Tap on the Shoulder"
    • The arm/fire Cycle
  • An Implementation Walkthrough
    • Path 1: Interrupt-Driven Wake (arm mode)
    • Path 2: Power-Off Sleep (sleep mode)
  • Summary
  • Frequently Asked Questions

Blues Developer News

The latest IoT news for developers, delivered right to your inbox.

Comments

Join the conversation for this article on our Community Forum

Blues Developer Newsletter

The latest IoT news for developers, delivered right to your inbox.

© 2026 Blues Inc.
© 2026 Blues Inc.
TermsPrivacy