Sleep mode. the attn pin and the starter kit

Hi all,

Some more noob questions here, please go easy on me:

I have the starter kit ( Cell+WiFi Quickstart - Blues Developers ) , and I’m trying to get my head around low power mode and whether it works with the hardware I’ve got.

I’m reading this guide here but I am confused

J *req = NoteNewRequest("card.attn");
JAddStringToObject(req, "mode", "sleep");
JAddNumberToObject(req, "seconds", 3600);

NoteRequest(req);

If I make this request what happens? Does something in my firmware have to respond to the attn pin going LOW?

When this request is received, the Notecard pulls the ATTN pin LOW , and the host can respond by placing itself into a sleep or low power mode

Or is there some magic here?

I was also following this code:

But trying that code I don’t see any sleeping? Also I cam confused as to what the ATTN_INPUT_PIN would need to be set to on the Swan if that’s the case.

I’ve also read that it only works in “battery” mode, not sure if that’s just me misunderstanding or not.

Any guidance would be greatly appreciated :slight_smile:

I think I missed this comment too

/ 1. Wire the Notecard’s ATTN pin output to a GPIO input on your MCU, and
// change the definition below to reflect the proper GPIO pin. On the
// Notecard Development Kit with an nRF53840 Feather, this would mean placing
// a jumper wire between the pin marked “5” and the pin marked “ATTN”.

Presumably “5” is on the feather, but I see a5/d5 not just 5. ( I’m assuming d for digital? )

Okay I am getting a better understanding of this now.

Jumpercable from N_ATTN → D_5 workers, and the example does what you’d expect it to do.

So the only bit that’s confusing me now is why when I am using LowPower.sleep() the board isn’t actually sleeping. I am assuming I shouldn’t see code within the arduino loop being executed and that LowPower.sleep should be blocking until the interrupt occurs?

Is this specific to the swan, or is this to do with it not having a battery attached?

Okay, after much head scratching it appears LowPower.sleep() works, but LowPower.deepSleep() does not.

here’s some very scrappy horrible code that may/may not help someone in future.

// Copyright 2019 Blues Inc.  All rights reserved.
//
// Use of this source code is governed by licenses granted by the
// copyright holder including that found in the LICENSE file.
//
// This example shows the simplest possible method demonstrating how a device
// might poll a Notefile used as an "inbound queue", using it to receive
// messages sent to the device from the service. The message gets into the
// service by use of the Notehub's HTTP/HTTPS inbound request capability.
//
// In order to use this example,
// 1. Wire the Notecard's ATTN pin output to a GPIO input on your MCU, and
//    change the definition below to reflect the proper GPIO pin. On the
//    Notecard Development Kit with an nRF53840 Feather, this would mean placing
//    a jumper wire between the pin marked "5" and the pin marked "ATTN".
// 2. Get the device up and running the code below, successfully connecting to
//    the servie
// 3. Use the "Devices" view on notehub.io to determine the DeviceUID of the
//    device, which is a unique string that looks like "dev:000000000000000"
// 4. Use the "Settings / Project" view on notehub.io to determine the App UID
//    of your project, a unique string that looks like
//    "app:00000000-0000-0000-0000-000000000000"
// 5. At the command line of your PC, send an HTTP message to the service
//    such as:
//    curl -L 'http://api.notefile.net/req?project="app:00000000-0000-0000-0000-000000000000"&device="dev:000000000000000"' -d '{"req":"note.add","file":"my-inbound.qi","body":{"my-request-type":"my-request"}}'

#include <Notecard.h>

#include "STM32LowPower.h"
#define ATTN_INPUT_PIN 5 // Any digital GPIO pin on your board
Notecard notecard;

// Set to true whenever ATTN interrupt occurs
static bool attnInterruptOccurred;
static bool high;
static bool sleepRan;

// Forwards
void attnISR(void);
void attnArm();

    HardwareSerial stlinkSerial(PIN_VCP_RX, PIN_VCP_TX);
// One-time Arduino initialization
void setup()
{
    pinMode(LED_BUILTIN, OUTPUT);
    LowPower.begin();
    stlinkSerial.begin(115200);
    stlinkSerial.println("Hub controller started");
    notecard.setDebugOutputStream(stlinkSerial);
    notecard.begin();

    // Configure the productUID, and instruct the Notecard to stay connected to
    // the service
    J *req = notecard.newRequest("hub.set");
    JAddStringToObject(req, "product", "my_fake_product_id");
    JAddStringToObject(req, "mode", "continuous");
    JAddBoolToObject(req, "sync", true);
    notecard.sendRequest(req);

    // Disarm ATTN To clear any previous state before rearming
    req = notecard.newRequest("card.attn");
    JAddStringToObject(req, "mode", "disarm,-files");
    notecard.sendRequest(req);

    // Configure ATTN to wait for a specific list of files
    // Attach an interrupt pin
    pinMode(ATTN_INPUT_PIN, INPUT);
    //attachInterrupt(digitalPinToInterrupt(ATTN_INPUT_PIN), attnISR, RISING);
    LowPower.attachInterruptWakeup(digitalPinToInterrupt(ATTN_INPUT_PIN), attnISR, RISING, SLEEP_MODE);
    // Arm the interrupt, so that we are notified whenever ATTN rises
    attnArm();
    sleepRan = false;
}

// In the Arduino main loop which is called repeatedly, add outbound data every
// 15 seconds
void loop()
{
    // If the interrupt hasn't occurred, exit
    if (!attnInterruptOccurred && sleepRan)
    {
        stlinkSerial.println("No interrupt yet");
        if (high) {
            digitalWrite(LED_BUILTIN, HIGH);
            high = false;
        } else {
            digitalWrite(LED_BUILTIN, LOW);
            high = true;
        }
         delay(1000);
        return;
    }
    else {
        stlinkSerial.println("Doing work");
        if (high) {
            digitalWrite(LED_BUILTIN, HIGH);
            high = false;
        } else {
            digitalWrite(LED_BUILTIN, LOW);
            high = true;
        }
    }

    // Re-arm the interrupt
    attnArm();
    stlinkSerial.println("Going to sleep");
    stlinkSerial.flush();
    sleepRan = true;
    LowPower.sleep();

    delay(1000);
}

// Interrupt Service Routine for ATTN_INPUT_PIN transitions rising from LOW
// to HIGH
void attnISR()
{
    stlinkSerial.println("interupt occured");
    attnInterruptOccurred = true;
}

// Re-arm the interrupt
void attnArm()
{
    // Make sure that we pick up the next RISING edge of the interrupt
    attnInterruptOccurred = false;

    // Set the ATTN pin low, and wait for the earlier of file modification or
    // a timeout
    J *req = notecard.newRequest("card.attn");
    JAddStringToObject(req, "mode", "sleep");
    JAddNumberToObject(req, "seconds", 20);
    bool response = notecard.sendRequest(req);
    if (!response) {
        stlinkSerial.println("Unable to set attn request");
    }

    delay(1000);
}