Dragos Iosub
Published

GO GREEN! Battery Powered ARM0 SAMD21G IoT

SAMD21G - xyz-mIoT [w. GSM, NB IoT or LTE CATM1] ~35-37uA in SLEEP mode - run your device for years using LiPO, LiION or Lithium batteries.

IntermediateProtip1 hour270
GO GREEN! Battery Powered ARM0 SAMD21G IoT

Things used in this project

Story

Read more

Schematics

powering circuit

basig hardware patches for optimized low power

Code

standard RTC sleep for SAMD21G, adapted for xyz-mIoT / SAMD21G current consumption measurements in R

C/C++
* a. test without Serial and Serial1 software modules loaded
* b. test with Serial and Serial1 software modules loaded - remove comments on lines 52 and 53

Dependencies: SAMD21G RTC library inside "xyz-mIoT shields RTCC and WDT Arduino classes" package, from: https://itbrainpower.net/downloads.php#xyz-mIoT
/* standard RTC sleep for SAMD21G, adapted for xyz-mIoT / SAMD21G current consumption measurements in RUN / SLEEP modes  
 *  
 * a. test without Serial and Serial1 software modules loaded
 * b. test with Serial and Serial1 software modules loaded - remove comments on lines 52 and 53
 * 
 * 
 * Dragos Iosub, Bucharest 2020.
 * https://itbrainpower.net 
 */
 
  /*
  Sleep RTC Alarm for Arduino Zero

  Demonstrates the use an alarm to wake up an Arduino zero from Standby mode

  This example code is in the public domain

  http://arduino.cc/en/Tutorial/SleepRTCAlarm

  created by Arturo Guadalupi
  17 Nov 2015
  modified 
  01 Mar 2016
  
  NOTE:
  If you use this sketch with a MKR1000 you will see no output on the serial monitor.
  This happens because the USB clock is stopped so it the USB connection is stopped too.
  **To see again the USB port you have to double tap on the reset button!**
*/

#include <RTCZero.h>

/* Create an rtc object */
RTCZero rtc;

/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 00;
const byte hours = 17;

/* Change these values to set the current initial date */
const byte day = 17;
const byte month = 11;
const byte year = 15;

void setup()
{
  delay(5000);
  pinMode(LED_BUILTIN, OUTPUT);
  digitalWrite(LED_BUILTIN, LOW);
  
  //Serial.begin(9600);
  //Serial1.begin(9600);
  
  rtc.begin();

  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);

  rtc.setAlarmTime(17, 00, 10);
  rtc.enableAlarm(rtc.MATCH_HHMMSS);

  rtc.attachInterrupt(alarmMatch);

  rtc.standbyMode();
}

void loop()
{
  //blink once, show me MCU is in RUN mode
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);

  delay(5000);								// intended for current consumption in RUN mode

  //blink twice, show me the MCU will enter SLEEP mode
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  delay(500);
  digitalWrite(LED_BUILTIN, HIGH);
  delay(500);
  digitalWrite(LED_BUILTIN, LOW);
  

  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);
  
  rtc.standbyMode();    					// Sleep until next alarm match, now you may sample the sleep current
}

void alarmMatch()
{
  digitalWrite(LED_BUILTIN, HIGH);
}

optimized_SAMD21G_SLEEP_RTCC_IN_INTERRUPT_0831c.ino

C/C++
SAMD21G optimized SLEEP software w. Serial and Serial1 activated for xyz-mIoT by itbrainpower.net shields - version 0831c / 2020.02.29
Dependencies:
- patched SAMD21G RTCC library from https://itbrainpower.net/downloads#xyz-mIoT
- xyz-mIoT LowPower library from https://itbrainpower.net/downloads#xyz-mIoT
/*
  SAMD21G optimized SLEEP software w. Serial and Serial1 activated for xyz-mIoT by itbrainpower.net shields.
  version 0831c / 2020.02.29
  
  RTCC [w. wake at each 30secs - see reloadRTCC() function] and D7 as interrupt on LOW level detection wake up!
  
  Serial and Serial1 load/unload procedures for low power mode!
  Crystal 32.768kHz precision oscillator [XOSC32K] was mentained for SLEEP.

  WARNING: 
	- use RTCC library from https://itbrainpower.net/downloads#xyz-mIoT
	- disconnect USB from shield. Else, even not enabled, the consumption will be highier w. minimum 400uA 
	- debug messages are provided via Serial1 --> connect 3.3V UART - USB adapter to xyz-mIoT shield RX0, TX1 and GND pads!!
	
  Dependencies: 
	- patched SAMD21G RTCC library from https://itbrainpower.net/downloads#xyz-mIoT
	- xyz-mIoT LowPower library from https://itbrainpower.net/downloads#xyz-mIoT


  SLEEP consumption ~ 34-37uA powered bw. 3.3-4.1V* via LiPO pads* [Vbat and GND]. This should cover scenarios as powering from:
		- LiPO, LiION rechargeable batteries [charging mechanism is mentained]
		- Lithium primary batteries
  
  itbrainpower.net invests significant time in design phase of our IoT products and in associated software and support resources.
  Support us by purchasing our IOT modems, IOT shields and sensors from here https://itbrainpower.net/order	
  
  Enjoy!
 
  Dragos Iosub, Bucharest 2020.
  https://itbrainpower.net 
 
 */

#include <xyz-mIoT_LowPower.h>

#include <RTCZero.h> 

RTCZero rtc;

#define contactIN   7 							//digital port used for wake up (...and having embedded weak pullup resistor, see docs) 

#define RTCINT      1
#define GPIOINT     2

/* Change these values to set the current initial time */
const byte seconds = 0;
const byte minutes = 00;
const byte hours = 17;

/* Change these values to set the current initial date */
const byte day = 17;
const byte month = 11;
const byte year = 15;

int interruptMode = 0;


void setup()
{
  delay(5000); 									//do not remove this, else you may not be able to program the shield!!!!!
  
  interruptMode = 0;

  xyzmIoTLowPower.begin();  
  
  xyzmIoTLowPower.ledBLINK(500,1);
  
  //SerialUSB.begin(115200);
  xyzmIoTLowPower.loadSerial();					//modem UART
  xyzmIoTLowPower.loadSerial1();				//external UART
  
  Serial1.println("test LPR");

  rtc.begin();

  rtc.attachInterrupt(RTCCalarmEvent);  
  
  initWakePin();    
  xyzHibernate();
}

void loop()
{
  //SerialUSB.begin(115200);
  xyzmIoTLowPower.loadSerial();					//modem UART
  xyzmIoTLowPower.loadSerial1();				//external UART

  switch(interruptMode)
  {
     case(RTCINT):
        Serial1.println("RTC interrupt");
        
        xyzmIoTLowPower.ledBLINK(500,1);
     break;
     case(GPIOINT):
        Serial1.println("GPIO interrupt");
        
        xyzmIoTLowPower.ledBLINK(100,2);    
     break;
     default:       //never here
     break;
  }

  delay(2000);

  xyzmIoTLowPower.ledBLINK(100,4);    
  
  xyzHibernate();  
}


void reloadRTCC()
{
  rtc.setTime(hours, minutes, seconds);
  rtc.setDate(day, month, year);

  rtc.setAlarmTime(17, 00, 30);
  rtc.enableAlarm(rtc.MATCH_HHMMSS);
}


void RTCCalarmEvent() 						//this is RTCC interrupt routine
{
  interruptMode = RTCINT;
}

void initWakePin()
{
  pinMode(contactIN, INPUT);                //default, D7 have a weak pullup embedded (10Mohms) - read xyz-mIoT documentation
  attachInterrupt(contactIN, digitalINalarmEvent, LOW);
}


void digitalINalarmEvent()					//this is GPIO interrupt routine
{
  interruptMode = GPIOINT;
}


void xyzHibernate(void)
{
  interruptMode = 0;
  reloadRTCC();
  xyzmIoTLowPower.xyzSleep();
}

Credits

Dragos Iosub

Dragos Iosub

23 projects • 4 followers
Electronics & software, electronics & software, ...

Comments