Author Topic: Compilation Error for Examples "Please ensure chosen MCU is a SAMD21"  (Read 272 times)

arf

  • NewMember
  • *
  • Posts: 11
I am trying to use the LowPower_LowPowerLab library and the RFM69_LowPowerLab library with my Moteino M0 but I am getting the compilation error "Please ensure the chosen MCU is a SAMD21" for the examples DeepSleep, DeepSleep_usingLowPowerLibrary, standbyExternalInteruptSAMD21, and idleWakePeriodic, etc

The M0 is a SAMD21 and I thought these libraries are made for Moteinos...

Jason

  • Jr. Member
  • **
  • Posts: 57
Hi Arf,

I was able to reproduce this error (extra white spaces removed and file path X'd out):
Code: [Select]
Arduino: 1.8.13 (Windows 10), Board: "Moteino M0, External 32.768Khz, TinyUSB, Off"
In file included from C:\XXXX\XXXX\XXXX\Arduino\libraries\RFM69_LowPowerLab\Examples\DeepSleep\DeepSleep.ino:8:0:

C:\XXXX\XXXX\XXXX\Arduino\libraries\LowPower_LowPowerLab/LowPower.h:161:6: error: #error "Please ensure chosen MCU is a SAMD21"
     #error "Please ensure chosen MCU is a SAMD21"
      ^~~~~
exit status 1
Error compiling for board Moteino M0.
This report would have more information with
"Show verbose output during compilation"
option enabled in File -> Preferences.
Turning on verbose output (as mentioned in the error above):
Code: [Select]
In file included from C:\XXXX\XXXX\XXXX\Arduino\libraries\RFM69_LowPowerLab\Examples\DeepSleep\DeepSleep.ino:8:0:
C:\XXXX\XXXX\XXXX\Arduino\libraries\LowPower_LowPowerLab/LowPower.h:161:6: error: #error "Please ensure chosen MCU is a SAMD21"
     #error "Please ensure chosen MCU is a SAMD21"
      ^~~~~
Notice after \DeepSleep.ino it has :8:0: that means the problem is in line 8 character 0 of the DeepSleep.ino file. This happens to be an include statement for the LowPower library. This corresponds to the next line in the reported error. It is in line 161 of LowPower.h

Code: [Select]
121		#if defined (__AVR__)
... Stuff to do with AVR ...
156 #elif defined (__arm__)
157 #if defined(__SAMD21__)
158 void idle(idle_t idleMode);
159 void standby();
160 #else
161 #error "Please ensure chosen MCU is a SAMD21"
162 #endif
163
164 #else
165
166 #error "Processor architecture is not supported."
167
168 #endif
As you can see this is where that error message is coming from.

As I looked into it more, why isn't __SAMD21__ defined? Who / how should it be defined? After looking into pre-processor directives (anything that starts with a # like #include or #define), I decided well why not just define it, so I did. Side note: I liked this write up https://www.deviceplus.com/arduino/arduino-preprocessor-directives-tutorial/ .

I added this to the top of the code on the deep sleep library.
Code: [Select]
#ifndef __SAMD21__
  #define __SAMD21__
#endif
and now that error goes away! However a new error comes in it's place:
Code: [Select]
C:\XXXX\XXXX\XXXX\XXXX\XXXX\arduino_modified_sketch_898042\DeepSleep.ino: In function 'void longSleep(uint32_t)':
DeepSleep:75:16: error: 'class LowPowerClass' has no member named 'powerDown'
       LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
What now!?

Going back to LowPower.h
Code: [Select]
		#if defined (__AVR__)
        // Some lines removed for clairity
void adcNoiseReduction(period_t period, adc_t adc, timer2_t timer2) __attribute__((optimize("-O1")));
void powerDown(period_t period, adc_t adc, bod_t bod) __attribute__((optimize("-O1")));
void powerSave(period_t period, adc_t adc, bod_t bod, timer2_t timer2) __attribute__((optimize("-O1")));
void powerStandby(period_t period, adc_t adc, bod_t bod) __attribute__((optimize("-O1")));
void powerExtStandby(period_t period, adc_t adc, bod_t bod, timer2_t timer2) __attribute__((optimize("-O1")));
void  longPowerDown(uint32_t sleepTime);
#elif defined (__arm__)
#if defined(__SAMD21__)
void idle(idle_t idleMode);
void standby();
#else
#error "Please ensure chosen MCU is a SAMD21"
#endif
#else
#error "Processor architecture is not supported."
#endif
Look at all those functions that are defined for AVR boards but not SAMD21 board. Clearly one cannot use the powerDown function if one is not using an AVR.

In conclusion: It looks like most examples under RFM69_LowPowerLab are not Moteino M0 friendly. See the attached screenshot and the gray note of the examples built for the M0.

Hope that helps,
Jason

Jason

  • Jr. Member
  • **
  • Posts: 57
If you are trying to deep sleep the Moteino M0 see the example sketch on the guide page.

https://lowpowerlab.com/guide/moteino/moteinom0/

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6620
  • Country: us
    • LowPowerLab
Looks like the newer versions of the SAMD cores no longer define __SAMD21__.
I patched the library to look for ARDUINO_SAMD_ZERO instead. Should support all arduino boards that have that #define ARDUINO_SAMD_ZERO in their board definitions.
Please get latest and retry. The idle and standby sleep modes for SAMD21 are supported.

arf

  • NewMember
  • *
  • Posts: 11
EDIT: made an edit in the last two paragraphs of this post.

Thanks for the quick responses!  Here's the results of my latest attempts with the updated library.  For all of this, I haven't modified the moteino m0.  Powering through the battery port.  In short, the examples in the  RFM69_LowPowerLab library doesn't compile for the reason Jason gave and  LowPower_LowPowerLab library compiles but don't produce power savings.  One of the examples in the moteino M0 guide seems to be working correctly, the other seems to have maybe higher than expected current.


The RFM69_LowPowerLab library examples DeepSleep and DeepSleep_usingLowPowerLibrary no longer give the SAMD21 error but now show the no member named 'powerDown' error that Jason documented.

The LowPower_LowPowerLab library example standbyExternalInterruptsSAMD21 now compiles!  But the sleep current is 15mA.  It was 17mA before sleeping.  The power had a weird pattern as shown in the attached picture.  Only code modified was deleting the "while(!" before the Serial start.

The LowPower_LowPowerLab library example idleWakePeriodic now compiles!  But looking at a power analyzer it doesn't seem to do anything.  I guess that's because the example code only looks for AVRs?

Code: [Select]
// **** INCLUDES *****
#include "LowPower.h"

void setup()
{
  delay(1000);
  // No setup is required for this library
}

void loop()
{
  // Enter idle state for 8 s with the rest of peripherals turned off
  // Each microcontroller comes with different number of peripherals
  // Comment off line of code where necessary


#if defined (__AVR_ATmega328P__) || defined (__AVR_ATmega168__)
  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF, TIMER1_OFF, TIMER0_OFF,
                SPI_OFF, USART0_OFF, TWI_OFF);
#elif defined __AVR_ATmega644P__ || defined (__AVR_ATmega1284P__)
  LowPower.idle(SLEEP_8S, ADC_OFF, TIMER2_OFF,
    TIMER1_OFF, TIMER0_OFF, SPI_OFF,
    USART1_OFF, USART0_OFF, TWI_OFF);
#endif
               
  // ATmega32U4
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER4_OFF, TIMER3_OFF, TIMER1_OFF,
  //      TIMER0_OFF, SPI_OFF, USART1_OFF, TWI_OFF, USB_OFF);

  // ATmega2560
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF,
  //      TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF, USART3_OFF,
  //      USART2_OFF, USART1_OFF, USART0_OFF, TWI_OFF);

  // ATmega256RFR2
  //LowPower.idle(SLEEP_8S, ADC_OFF, TIMER5_OFF, TIMER4_OFF, TIMER3_OFF,
  //      TIMER2_OFF, TIMER1_OFF, TIMER0_OFF, SPI_OFF,
  //      USART1_OFF, USART0_OFF, TWI_OFF);

  // Do something here
  // Example: Read sensor, data logging, data transmission.
}


With the https://lowpowerlab.com/guide/moteino/moteinom0/ example called Deep Sleep which seems to be for external interrupts, I get 1.4mA.  EDIT:  I forgot to uncomment the line defining the radio.  I get 100uA now, which is a somewhat higher than expected, right?


With the https://lowpowerlab.com/guide/moteino/moteinom0/ example called periodic sleep using RTCZero I get 11uA sleep if I add lines to sleep the radio and flash.  Of note, the sleeping period appears to consistently be just under 4 seconds instead of 3 seconds. 


Appreciate all the help!  It's a great product Felix
« Last Edit: June 20, 2021, 12:32:04 AM by arf »

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6620
  • Country: us
    • LowPowerLab
I would add that the LowPower library and examples only deal with the SAMD21 processor sleep. Any other devices will also have to be put to sleep to achieve minimum sleep current.
If a bug is found a PR is always welcome. I see changes in the Arduino core can sometimes cause cascading issues in libraries that are otherwise untouched.

arf

  • NewMember
  • *
  • Posts: 11
Hi Felix - Does that mean the results I got were to be expected?  Love your product, but want to make sure I am using it right.

Felix

  • Administrator
  • Hero Member
  • *****
  • Posts: 6620
  • Country: us
    • LowPowerLab
You should be getting MCU sleep of under ~10uA in standby sleep.