Go Down

Topic: Lowest consumption issue (Read 6711 times) previous topic - next topic

jmsalomr

Hi,

Removing the pin initialization, in my case gives me just 17 uA in both sleep() and deepSleep() modes. No differences between them. Good numbers!

Best regards.

Gormd

Hej jmsalomr

Sounds like you are having some funn with Sigfox - my I ask what you are going to do in the agriculture area?

I have actually had some practice with the MKRFOX1200 now - in the field it works nicely, but connected to the computer for compiling from the Arduiono IDE - it really has its own life :-)

Would be nice to hear your experience with the SiPy and Sigfox comparing to MKRFOX1200:-)

Best regards

sslupsky

Hi Gormd,  I read with interest your suggestions regarding attaching the interrupt.  Indeed, when I do this the board reset and sleep function are reliable.  I was also able to achieve a reliable sleep() and reset if I instantiated an RTCZero object and invoked the begin() method.  I am wondering if you have any thoughts on this?

Code: [Select]

RTCZero rtc;

setup() {
  rtc.begin(false);
}



I took a dive into the ArduinoLowPower code and (the RTCZero library on which it depends) and it appears to me that the attachment of the interrupt is handled by the sleep() method?  See the attached code snippets from ArduinoLowPower.cpp.  It is odd to me that this doesn't appear to be working.  The ArduinoLowPower class instantiates an RTCZero object in the private section.  So, it is my understanding, attaching an interrupt as you described would require instantiating another RTC object?  Shouldn't there be a compiler error if you attempt to use attachInterrupt on a private object?

Code: [Select]

class ArduinoLowPowerClass {
public:
void idle(void);
void idle(uint32_t millis);
void idle(int millis) {
idle((uint32_t)millis);
}

void sleep(void);
void sleep(uint32_t millis);
void sleep(int millis) {
sleep((uint32_t)millis);
}

void deepSleep(void);
void deepSleep(uint32_t millis);
void deepSleep(int millis) {
deepSleep((uint32_t)millis);
}

void attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode);

#ifdef BOARD_HAS_COMPANION_CHIP
void companionLowPowerCallback(onOffFuncPtr callback) {
companionSleepCB = callback;
}
void companionSleep() {
companionSleepCB(true);
}
void companionWakeup() {
companionSleepCB(false);
}
#endif

#ifdef ARDUINO_ARCH_NRF52
void enableWakeupFrom(wakeup_reason peripheral, uint32_t pin = 0xFF, uint32_t event = 0xFF, uint32_t option = 0xFF);
wakeup_reason wakeupReason();
#endif

private:
void setAlarmIn(uint32_t millis);
#ifdef ARDUINO_ARCH_SAMD
RTCZero rtc;
#endif
#ifdef BOARD_HAS_COMPANION_CHIP
void (*companionSleepCB)(bool);
#endif
};


Code: [Select]

void ArduinoLowPowerClass::idle(uint32_t millis) {
setAlarmIn(millis);
idle();
}

void ArduinoLowPowerClass::setAlarmIn(uint32_t millis) {

if (!rtc.isConfigured()) {
attachInterruptWakeup(RTC_ALARM_WAKEUP, NULL, 0);
}

uint32_t now = rtc.getEpoch();
rtc.setAlarmEpoch(now + millis/1000);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
}

void ArduinoLowPowerClass::attachInterruptWakeup(uint32_t pin, voidFuncPtr callback, uint32_t mode) {

if (pin > PINS_COUNT) {
// check for external wakeup sources
// RTC library should call this API to enable the alarm subsystem
switch (pin) {
case RTC_ALARM_WAKEUP:
rtc.begin(false);
rtc.attachInterrupt(callback);
/*case UART_WAKEUP:*/
}
return;
}

EExt_Interrupts in = g_APinDescription[pin].ulExtInt;
if (in == NOT_AN_INTERRUPT || in == EXTERNAL_INT_NMI)
    return;

//pinMode(pin, INPUT_PULLUP);
attachInterrupt(pin, callback, mode);

// enable EIC clock
GCLK->CLKCTRL.bit.CLKEN = 0; //disable GCLK module
while (GCLK->STATUS.bit.SYNCBUSY);

GCLK->CLKCTRL.reg = (uint16_t) (GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN_GCLK6 | GCLK_CLKCTRL_ID( GCM_EIC )) ;  //EIC clock switched on GCLK6
while (GCLK->STATUS.bit.SYNCBUSY);

GCLK->GENCTRL.reg = (GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSCULP32K | GCLK_GENCTRL_ID(6));  //source for GCLK6 is OSCULP32K
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);

GCLK->GENCTRL.bit.RUNSTDBY = 1;  //GCLK6 run standby
while (GCLK->STATUS.reg & GCLK_STATUS_SYNCBUSY);

// Enable wakeup capability on pin in case being used during sleep
EIC->WAKEUP.reg |= (1 << in);

/* Errata: Make sure that the Flash does not power all the way down
      * when in sleep mode. */

NVMCTRL->CTRLB.bit.SLEEPPRM = NVMCTRL_CTRLB_SLEEPPRM_DISABLED_Val;
}



Finally, have you by chance tried the same on a MKRWAN1300?  I cannot seem to get the MKRWAN1300 below 1.16mA.  I have removed the pin initialization from wiring.c and used the method suggested here to attach the interrupt.  Still 1.16mA.  I am trying to ascertain if the current is being used by the SAMD or the Murata LoRa module but its difficult to tell.

Thank you and kind regards,

sslupsky

Hi jmsalomr,

Would it be possible for you to post your sketch that achieved the 17uA ?

Thank you,

sslupsky

For anyone following this thread, there is a hardware problem with the MKRWAN1300 that prevents it from achieving a sleep current below 1.15mA.  There will be a board revision to 2.0 that will correct the problem.

pierrot10

#20
Dec 11, 2018, 10:37 pm Last Edit: Dec 11, 2018, 10:40 pm by pierrot10
Dear all
Thank for this convrsation. I have a similar problem but I am still testing Arduino Low Power, but apparently this
Code: [Select]
sw.digitalWrite(wakeup_led,LOW);
LowPower.sleep(5000);
sw.digitalWrite(wakeup_led,HIGH);

goes to sleep because the led turn for 5 second.

But after free day, I see no difference. The battery goes from 4.2V to 3.7V in less than 3 days.
Without the lowpower, it goes down in 3 days as well . Not good.

I was expected to see a better difference.

My circuit is a bt different than yours. I am using Adafruit Feather MO adalogger with a AMD21 (ARM). I am not ueing sigfox but LoRa

Does some one has an experience with Adafruit Feather MO adalaoger and a RFM95 LoRa module radio in sleep mode, eight with AdruinoLowPower, or may be Sleepdog library from Adafruit?

I am going to investigate a bit more about  wiring.c, but someone can tell exactely what does it and for what it's usefull? What impact if I remove it as well?

Many thanks for any support and help.
Il ne suffit pas de tout savoir, la persévérance, c'est déjà presque tout!
You can not know everything, perseverance, it is almost everything!

iverona

Hello @philgeek et al.,

this thread was really useful to get as low consumption as possible! I have a simple alarm created with the mkrfox1200, battery powered and using a reed switch.

Following the tips here now I'm able to get 128.7uA while on deepSleep mode. While transmitting, it's around 380-400uA for 5 seconds. For some reason it's a bit higher than what you got, but I think it's more than enough. The only modification I made to the vanilla Arduino framework has been, as said above, the changes on wiring.c

I'll monitor how long the battery lasts. For anyone interested, code of my app is here:
https://github.com/iverona/StorageRoomAlarm/blob/master/src/main.cpp

Go Up