LowPower library for ItsyBitsy M0 Express not working

Dear Arduino-Team,

I would like to use the ItsyBitsy M0 Express board:

with the latest LowPower library from rocketscream:

When calling a standard function of the library:

LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);

I get an error that LowPower has no class powerDown:

exit status 1
'class LowPowerClass' has no member named 'powerDown'

The problem seems to be that ATSAMD21 and this quite known library are not compatible. Do you have any solution to this? Maybe another library?

Best and thank you,
Marco

The README at GitHub says it works with ATSAMD2. It could be that the problem is with the code you haven't bothered to post.

Please post your code and use code tags

Have you looked at the library's source code? Excerpt from LowPower.h:

 #elif defined (__arm__)

 #if defined (__SAMD21G18A__)
      void idle(idle_t idleMode);
      void standby();
 #else
 #error "Please ensure chosen MCU is ATSAMD21G18A."
 #endif

 #else

Also, there's an example specifically for SAMD21: "standbyExternalInterruptSAMD21.ino"

Doesn't seem like you've put much effort into this.

Hi Guys,

gfvalvo:
The README at GitHub says it works with ATSAMD2. It could be that the problem is with the code you haven't bothered to post.

Thank you a lot for your replies. My application is to input an external interrupt using a DS3231 Real Time Clock to Pin11 of the Adafruit Itsybitsy M0, which is equipped with an Atmel ATSAMD21 ARM processor. The interrupt calls an Interrupt Service routine, which records some sensor values. I have replaced the long code with the sensor values to print a string.

The code without the power saving function works fine, the DS3231 sends an interrupt each minute and I can also manually interrupt the MCU by connecting pin11 to ground.

However, if I start adding a low.power function (like the one that comes with the rocket scream library or the rtc.lib one), the MCU never comes back from sleep.

Best,
Marco

#include <Wire.h>
#include <LowPower.h>
#include <RtcDS3231.h>
volatile boolean alarm = 1;
RtcDS3231<TwoWire> Rtc2(Wire);

//pin definition
const byte interruptPin=11;


void setup()
{
  delay(5000); //delay to get the chip programmed
  Serial.begin(115200);
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);


Rtc2.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Rtc2.SetDateTime(compiled);
RtcDateTime now = Rtc2.GetDateTime();
Rtc2.Enable32kHzPin(false);
Rtc2.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth); 
      
    DS3231AlarmTwo alarm2(
            0,
            0,
            0, 
            DS3231AlarmTwoControl_OncePerMinute);
    Rtc2.SetAlarmTwo(alarm2);
    Rtc2.LatchAlarmsTriggeredFlags();  
 sensors.begin();  
}

void loop() {
  if (alarm == true) {
    handleAlarm();
  }
  LowPower.standby();
}

void handleAlarm() {
alarm = false;
Serial.print("We handle everything here");
Rtc2.LatchAlarmsTriggeredFlags();
}

void handleInterrupt() {
  alarm = true;
}

gfvalvo:
Have you looked at the library's source code? Excerpt from LowPower.h:

 #elif defined (__arm__)

#if defined (SAMD21G18A)
     void idle(idle_t idleMode);
     void standby();
#else
#error "Please ensure chosen MCU is ATSAMD21G18A."
#endif

#else




Also, there's an example specifically for SAMD21: "standbyExternalInterruptSAMD21.ino"

Doesn't seem like you've put much effort into this.

Dear gfvalvo,

Could you maybe have a look :)? I am already quite desperate since I have been trying to get the ItsyBitsy work with a low power library and an external interrupt that is provided by a DS3231 Real Time Clock. The code and the interrupt (each minute) works fine if i do not put any low power mode in the code. When I call the low power mode from either of one of these libraries:

  1. rocketscream:
    GitHub - rocketscream/Low-Power: Low Power Library for Arduino
  2. Arduino Low Power:
    Arduino Low Power - Arduino Reference
  3. RTCZero - Arduino Libraries

the MCU never comes back from sleep. Please have a look at my code below. The external interrupt calls an InterruptServiceRoutine that sets an alarm flag to true. The loop function then just sets the alarm flag to false and calls the handlealarm function. I have also tried to use CHANGE and LOW for the attach.Interrupt but the MCU still does not come back from sleep mode.
Where shall I call the sleep mode? I think the problem lies somewhere else besides the position of the sleep mode.

Please see my code below:

#include <RTCZero.h> //library for setting the real time clock on the MCU board, can also be used for low power modes
RTCZero rtc; //object definition
#include <Wire.h> //library for I2C connection
#include <OneWire.h> //library for the temperature sensor
#include <LowPower.h> //rocketscream library
//#include <SoftwareWire.h>
#include <RtcDS3231.h> //RTC library clock that sets the RTC alarm and RTC time
#include <DallasTemperature.h> //DS18 digital temperature library
//#include <ArduinoLowPower.h>
#define _BV(b) (1UL << (b)) //required for the Rtc2 wire definition
RtcDS3231<TwoWire> Rtc2(Wire);
volatile boolean alarm = 1;

//setting of the internal MCU clock using the RTCzero library
const byte seconds = 0;
const byte minutes = 20;
const byte hours = 15;
const byte days = 21;
const byte months = 7;
const byte years = 19;
const byte interruptPin = 11;

void setup()
{
 delay(5000); //delay to get the chip programmed
 Serial.begin(115200);
 pinMode(interruptPin, INPUT_PULLUP);
 attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, CHANGE);
 
//Section for RTCzero library that sets the internal time of the MCU and puts the MCU to sleep via standbyMode();
 rtc.begin();
 rtc.setTime(hours, minutes, seconds);
 rtc.setDate(days, months, years);
 //rtc.setAlarmTime(00, 00, 10); //
 //rtc.enableAlarm(rtc.MATCH_HHMMSS);
 //rtc.attachInterrupt(ISR);
//extInterrupt(11); //creates an interrupt source on external pin


Rtc2.Begin();
RtcDateTime compiled = RtcDateTime(__DATE__, __TIME__);
Rtc2.SetDateTime(compiled);
RtcDateTime now = Rtc2.GetDateTime();
Rtc2.Enable32kHzPin(false);
Rtc2.SetSquareWavePin(DS3231SquareWavePin_ModeAlarmBoth); 

RtcDateTime alarmTime = now + 88; // into the future
   DS3231AlarmOne alarm1(
           alarmTime.Day(),
           alarmTime.Hour(),
           alarmTime.Minute(), 
           alarmTime.Second(),
           DS3231AlarmOneControl_HoursMinutesSecondsMatch);
 Rtc2.SetAlarmOne(alarm1);          
   DS3231AlarmTwo alarm2(
           0,
           0,
           0, 
           DS3231AlarmTwoControl_OncePerMinute);
   Rtc2.SetAlarmTwo(alarm2);
   Rtc2.LatchAlarmsTriggeredFlags();  
}

void loop() {
 if (alarm == true) {
   handleAlarm();
 }
// LowPower.standby();
}

void handleAlarm() {
 alarm = false;
 RtcDateTime timestamp = Rtc2.GetDateTime();
 Serial.print("time interrupt at: ");
 char time[10];
 sprintf(time, "%d:%d:%d",
         timestamp.Hour(),
         timestamp.Minute(),
         timestamp.Second()
        );
Serial.println(time);

   Rtc2.LatchAlarmsTriggeredFlags();
}

void handleInterrupt() {
 alarm = true;
}

It's been long time since I looked in to it, but I recall getting edge-triggered interrupts to work is tricky while the SAMD21 is sleeping. You need to have a clock enabled -- XOSC32K, I think. And then use that as the clock to the interrupt system.

You'll have to Google around. Start here: External interruption not being triggered with CHANGE, RISING or FALLING while on standby (sleep) mode. · Issue #142 · arduino/ArduinoCore-samd · GitHub

And, of course, the device datasheet.

gfvalvo:
It's been long time since I looked in to it, but I recall getting edge-triggered interrupts to work is tricky while the SAMD21 is sleeping. You need to have a clock enabled -- XOSC32K, I think. And then use that as the clock to the interrupt system.

You'll have to Google around. Start here: External interruption not being triggered with CHANGE, RISING or FALLING while on standby (sleep) mode. · Issue #142 · arduino/ArduinoCore-samd · GitHub

And, of course, the device datasheet.

Thank you a lot. I have come across this thread yesterday but I haven't checked it in detail. I will give it a try.

I tested my code with an Arduino UNO /Atmega328P and it worked perfectly using the rocketscream LowPower library. I guess it is as you say, have the XOSC32K clock enabled and use that for the interrupt.

Anyways, looking the datasheet, I am happy with the power consumption in any mode of the Atmega328P also. No need for an ATSAMD21, maybe later.

Best,
Marco