Thanks to @PJ_Glasso and @msfujino for your replies and suggestions. I broke down my project to the basics and tried putting the board to sleep and waking it up using a push button. Using @PJ_Glasso’s Xiao Grove Expansion code, I created this basic version, and it works! I haven’t tested the current consumption in sleep mode yet, but the serial monitor output and disconnection during sleep suggest that the device successfully enters and exits sleep mode. Also, if you have time, please review my code and let me know if there are any problems or mistakes. It would be really helpful. Below is the code I used:
#include <Arduino.h>
#include <Adafruit_TinyUSB.h> // For USB serial support, version: 1.7.0
// Pin definitions
#define BUTTON_PIN 2 // Pushbutton connected to D2 (other side to GND)
// Interrupt Service Routine (ISR) for button press
volatile bool buttonPressed = false; // Flag to track button press
void buttonISR() {
buttonPressed = true; // Set flag on falling edge
}
// Function to blink a specific LED
void blinkLED(uint8_t ledPin, int times, int delayMs) {
for (int i = 0; i < times; i++) {
digitalWrite(ledPin, LOW); // On (active-low)
delay(delayMs);
digitalWrite(ledPin, HIGH); // Off
delay(delayMs);
}
}
// Setup function
void setup() {
// Initialize LEDs
pinMode(LED_RED, OUTPUT);
pinMode(LED_BLUE, OUTPUT);
digitalWrite(LED_RED, HIGH); // Off (active-low)
digitalWrite(LED_BLUE, HIGH); // Off (active-low)
// Initialize serial for debugging
Serial.begin(9600);
// Wait for serial connection (up to 5 seconds)
unsigned long startTime = millis();
while (!Serial && millis() - startTime < 5000) {
delay(10);
}
Serial.println("Program started. Hold button (D2 to GND) for 3 seconds to sleep.");
// Configure button pin with pull-up resistor
pinMode(BUTTON_PIN, INPUT_PULLUP); // HIGH when not pressed, LOW when pressed
// Attach interrupt for button press (falling edge to detect press)
attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonISR, FALLING);
// Indicate wake-up with 3 blue LED blinks
Serial.println("Device awake (reset from sleep or power-on).");
blinkLED(LED_BLUE, 3, 200); // Blink blue LED 3 times
}
// Loop function
void loop() {
// Blink red LED to indicate device is awake
digitalWrite(LED_RED, LOW); // On (active-low)
delay(500);
digitalWrite(LED_RED, HIGH); // Off
delay(500);
// Check for button press via ISR
if (buttonPressed) {
buttonPressed = false; // Clear ISR flag
// Check if button is held for 3 seconds
unsigned long pressStart = millis();
while (digitalRead(BUTTON_PIN) == LOW && millis() - pressStart < 3000) {
// Wait until button is released or 3 seconds pass
delay(10);
}
if (millis() - pressStart >= 3000 && digitalRead(BUTTON_PIN) == LOW) {
// Button held for 3 seconds
Serial.println("Button held for 3 seconds. Going to deep sleep...");
// Blink red LED 3 times before sleep
blinkLED(LED_RED, 3, 200);
// Turn off both LEDs
digitalWrite(LED_RED, HIGH);
digitalWrite(LED_BLUE, HIGH);
// Configure button pin for wake-up (sense low in system OFF mode)
uint32_t pin = BUTTON_PIN;
pin = g_ADigitalPinMap[pin]; // Map Arduino pin to nRF pin
nrf_gpio_cfg_sense_input(pin, NRF_GPIO_PIN_PULLUP, NRF_GPIO_PIN_SENSE_LOW);
delay(100); // Ensure settings are applied
// Enter system OFF mode (deep sleep)
sd_power_system_off();
NRF_POWER->SYSTEMOFF = 1;
// Code will not reach here until woken up (resets to setup)
Serial.println("Woken up from deep sleep!");
}
}
// Enter low-power mode during idle (system ON)
sd_power_mode_set(NRF_POWER_MODE_LOWPWR);
sd_power_dcdc_mode_set(NRF_POWER_DCDC_ENABLE);
__WFE(); // Wait for event
__WFI(); // Wait for interrupt
sd_app_evt_wait(); // SoftDevice low-power wait
}