Rocketstream library problem to power down module that uses LoRaWAN, atmega 328p

Hi, I have the problem them if the module is powered down, it is not coming back. The code is a bit too long, I'm attaching the related parts.

If I define the interrupt in the setup and do not power down, the module successfully sends data in each 1 min after notified by RTC.

const byte interruptPin=3;
...

void setup(){
pinMode(interruptPin, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
}

void loop() {
  if (alarm == true) {
   digitalWrite(5, LOW);
    os_runloop_once();
  }
}

...
void handleInterrupt() {
  alarm = true;
}

When I try the power down as stated in the library examples (after removing attaching interrupt from setup and using in the loop():

void loop() {
  if (alarm == true) {
   // handleAlarm();
   digitalWrite(5, LOW);
    os_runloop_once();
  }
  attachInterrupt(digitalPinToInterrupt(3), handleInterrupt, FALLING);
  LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);
  detachInterrupt(digitalPinToInterrupt(3)); 
}

...

void handleInterrupt() {
  alarm = true;
}

simply stalls any execution, besides the Serial is not working as well.

Any ideas are appreciated, thank you :slight_smile:

is alarm declared as volatile ?
Maybe create a minimal but complete sketch which highlights the problem, and post that.

6v6gt:
is alarm declared as volatile ?
Maybe create a minimal but complete sketch which highlights the problem, and post that.

Tanks for your answer, yes the alarm is volatile. I am pasting all the code trimmed to focus on the problem:
I change the interrupt attachments from setup and loop to check if one configuration is working, you can check the code in accordance with my above code.
Thanks!

#include <lmic.h>
#include <hal/hal.h>
//#include <credentials.h>

#include <Wire.h>
#include <SPI.h>

#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;

const byte interruptPin=3;


static osjob_t sendjob;

// Schedule TX every this many seconds (might become longer due to duty
// cycle limitations).
const unsigned TX_INTERVAL = 40;

// Pin mapping Dragino Shield
const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 9,
    .dio = {2, 6, 7},
};
void onEvent (ev_t ev) {
    if (ev == EV_TXCOMPLETE) {
        //Serial.println(F("EV_TXCOMPLETE (includes waiting for RX windows)"));
        // Schedule next transmission
        os_setTimedCallback(&sendjob, os_getTime()+sec2osticks(TX_INTERVAL), do_send);
    }
}

void do_send(osjob_t* j){
    // Payload to send (uplink)
    //static uint8_t message[] = "fuck";
    alarm = false;
  digitalWrite(5, HIGH);
  delay(2000);
  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);
//PH
for(int i=0;i<10;i++) 
 { 
 buf[i]=analogRead(pH_Pin);
 delay(30);
 }
 for(int i=0;i<9;i++)
 {
 for(int j=i+1;j<10;j++)
 {
 if(buf[i]>buf[j])
 {
 temp=buf[i];
 buf[i]=buf[j];
 buf[j]=temp;
 }
 }
 }
 avgValue=0;
 for(int i=2;i<8;i++)
 avgValue+=buf[i];
 float pHVol=(float)avgValue*3.3/1024;
 phValue = pH_calibration_slope*pHVol+pH_calibration_offset;

//EC
sensors.requestTemperatures();// Send the command to get temperatures
Temperature=sensors.getTempCByIndex(0); //Stores Value in Variable
 

//************Estimates Resistance of Liquid ****************//
digitalWrite(ECPower,HIGH);
raw= analogRead(ECPin);
raw= analogRead(ECPin);// This is not a mistake, First reading will be low beause if charged a capacitor
digitalWrite(ECPower,LOW);
 

//Serial.println(phValue);
 
    Rtc2.LatchAlarmsTriggeredFlags();
    delay(100);

    uint8_t message[7];
    
}

void setup() {
    delay(5000); //delay to get the chip programmed
    pinMode(5, OUTPUT); // MOSFET Switch
    Serial.begin(115200);
    
    //Serial.println(F("Starting..."));
    
  

    pinMode(ECPin,INPUT);
  pinMode(ECPower,OUTPUT);//Setting pin for sourcing current
  pinMode(interruptPin, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(interruptPin), handleInterrupt, FALLING);
  
//Section for RTCzero library that sets the internal time of the MCU and puts the MCU to sleep via standbyMode();

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();  
    sensors.begin();  
 

    // Start job
    do_send(&sendjob);
}

void loop() {
  if (alarm == true) {
   // handleAlarm();
   digitalWrite(5, LOW);
    os_runloop_once();
  }
//  attachInterrupt(digitalPinToInterrupt(3), handleInterrupt, FALLING);
//LowPower.powerDown(SLEEP_8S, ADC_OFF, BOD_OFF);
//  detachInterrupt(digitalPinToInterrupt(3)); 
}

void handleInterrupt() {
  alarm = true;
}

That is somewhat heavy weight for a minimal example.

I would start by getting rid of the RocketScream library and using basic AVR commands to do the same thing. See Gammon Forum : Electronics : Microprocessors : Power saving techniques for microprocessors

Some Nanos with a "non-optiboot" boot loader had problems with low power code. What are you using ?

6v6gt:
That is somewhat heavy weight for a minimal example.

I would start by getting rid of the RocketScream library and using basic AVR commands to do the same thing. See Gammon Forum : Electronics : Microprocessors : Power saving techniques for microprocessors

Some Nanos with a "non-optiboot" boot loader had problems with low power code. What are you using ?

Sorry for the long code, I am using an original arduino UNO and already took a deep dive in the library :frowning: