What is waking up my arduino from sleep?

I am using Arduino Mega 2560 in my project where I am trying to send the GPS location by one hour intervals using LoraWan radio. In those intervals I want to put the arduino to sleep to save energy. All the codes (getting GPS sentences, sending Lora radio messages, and putting the arduino to sleep and waking up with one hour intervals using RTC3231) work fine separately, however when I combine them, I find out that the Arduino is woken up not by the RTC alarm, but by something else, right after it goes to sleep.

Here is the simplified code, I removed all the code for the GPS and the radio, except those which are related with pin numbers (note : You can jump to the question at the end of my ppost if you like, because I have an idea about what is wrong with the code):

#include <Wire.h>
#include <RTClibExtended.h>
#include <LowPower.h>
#include <lmic.h>
#include <hal/hal.h>
#include <SPI.h>
#include <SoftwareSerial.h>
#include <TinyGPS.h>

RTC_DS3231 RTC;      //we are using the DS3231 RTC
TinyGPS gps;
SoftwareSerial ss(13, 12);

const lmic_pinmap lmic_pins = {
    .nss = 10,
    .rxtx = LMIC_UNUSED_PIN,
    .rst = 9,
    .dio = {2, 6, 7},

void wakeUp()        // here the interrupt is handled after wakeup
  Serial.println("wakeup working now"); //added for debugging

void setup() {
  //Initialize communication with the clock
  RTC.adjust(DateTime(__DATE__, __TIME__));   //set RTC date and time to COMPILE time
  //clear any pending alarms
  RTC.armAlarm(1, false);
  RTC.alarmInterrupt(1, false);
  RTC.armAlarm(2, false);
  RTC.alarmInterrupt(2, false);

void loop() {
RTC.setAlarm(ALM1_MATCH_HOURS, 38, 15, 0);   //set your wake-up time here
  RTC.alarmInterrupt(1, true);

  //On first loop we enter the sleep mode
    attachInterrupt(digitalPinToInterrupt(3), wakeUp, LOW);                       //use interrupt 0 (pin 2) and run function wakeUp when pin 2 gets LOW 
    Serial.println("going sleep now to wait for the 1.st alarm"); //added for debugging
    LowPower.powerDown(SLEEP_FOREVER, ADC_OFF, BOD_OFF);   //arduino enters sleep mode here
    detachInterrupt(1);                                    //execution resumes from here after wake-up

    //When exiting the sleep mode we clear the alarm
    RTC.armAlarm(1, false);
    RTC.alarmInterrupt(1, false);
    Serial.println("1. alarm woke up"); // added for debugging

The software serial in this code above is used for the GPS, which is the culprit fro waking up the arduino, because when I remove the cables from digital 13 and 12 (the pins I use for software serial), the arduino does not wake up.

Here is the monitor output showing that the wakeup function is not running:

"going sleep now to wait for the 1.st alarm

  1. alarm woke up
    going sleep now to wait for the 1.st alarm
  2. alarm woke up


My question is, how do I prevent those pins 13 and 12 (or any other pin in that sense) from interrupting my sleep?

If you are sleeping to save power, shouldn't you put the GPS in low-power standby before sleeping? Wouldn't that keep the GPS from sending data and waking up the CPU via the PinChange interrupt? If you want to keep the GPS runing, disable the pin change interrupt for the receive pin before going to sleep. That should stop the SoftwareSerial interrupts.

Are you using an Arduino UNO? If so, you can't use SPI (pins 10, 11, 12, and 13) when you are using 12 and 13 for SoftwareSerial.

Well, I will disconnect the power to GPS by a mosfet later on, because it does not seem to have a sleep mode. However it seems I will have to power the GPS before the arduino, at least 30 seconds on average, because it does take quite a long time before the GPS returns any values. (maybe I am using the wrong GPS (Quectel - L80), I don't know.)
Well, I need to turn the interrupts off at least for test now.

So, digital pin 13 according to Atmega datasheet corresponds to PCINT7 and PCMSK0.
From what I learned from the internet, I hope I am writing the correct code :

PCMSK0 &=0x00;

You only want to turn off Bit 7 in the PCMSK0 register:

  PCMSK0 &= 0x7F;  // PCINT7 off

Since the other interrupts are probably already off it wouldn't make a difference.

A way to turn off ALL pin change interrupts is to store a copy of PCICR and set it to 0. Then restore it when you wake up. This will work as long as you are not using a Pin Change Interrupt to wake up the processor!

    byte savedPCICR = PCICR;
    PCICR = 0;  // Disable all pin change interrupts
    PCICR = savedPCICR;  // Restore any pin change interrupts that were disabled.

Great! Thanks

it does take quite a long time before the GPS returns any values. (maybe I am using the wrong GPS (Quectel - L80), I don't know.)

As far as I know, all GPS units behave that way.

Satellites move, so the GPS unit needs to be on all the time to maintain the fix.

As far as I know, all GPS units behave that way.
Satellites move, so the GPS unit needs to be on all the time to maintain the fix.

The GPS stores the satellite ephemeris data which arrives every 30 seconds. If the GPS has been off for less than a few hours it can do a Hot Start which can get a fix in under a few seconds.

Each GPS will typically have a specification for Time To First Fix (TTFF) for various conditions. For this GPS (with the 'EASY' feature enabled) they are:
Cold Start: 15 seconds
Warm Start: 5 seconds
Hot Start: 1 Second
The 'EASY' feature can predict the satellite's current position from three day old data.
This GPS does have a STANDBY mode (1 mA) but it appears you are using the BACKUP mode (remove power except battery power to the clock and NVRAM). That draws only 0.7 microamps from the 3.3V backup battery.

Mine takes much much longer than those numbers to get a fix. I will try to find out why.

Thank you for bringing that document to my attention (questel pdf). It mentions the correct way - tough rather complicated - of powering the V_bckp (back-up) while removing it from Vcc(main power). I hadn't noticed.

It is interesting that these subject are not discussed in forums and elsewhere even tough almost everybody seems to be using GPSs in their projects.

Mine takes much much longer than those numbers to get a fix. I will try to find out why.

That is usually because manufacturers make exaggerated claims, which I have found to be the case for all three of the GPS modules I use.

I don't use your module, but most come with battery or supercap that needs to be charged to maintain the satellite ephemeris (the data table that helps to predict where the satellites should be in the sky), while the GPS receiver is off or sleeping.

If the battery/supercap is depleted, the GPS unit has to do a cold start, which can take up to 15 minutes, despite what the manufacturer claims. Make sure your module is wired such that that backup battery/cap is kept charged. If it is a not a rechargeable battery, it may need to be replaced.

From the Wikipedia link in reply #6:

Cold or Factory: The receiver is missing, or has inaccurate estimates of, its position, velocity, the time, or the visibility of any of the GPS satellites. As such, the receiver must systematically search for all possible satellites. After acquiring a satellite signal, the receiver can begin to obtain approximate information on all the other satellites, called the almanac. This almanac is transmitted repeatedly over 12.5 minutes. Almanac data can be received from any of the GPS satellites and is considered valid for up to 180 days. Manufacturers typically claim the factory TTFF to be 15 minutes.

Hmm, that explains why I think. The one I have is not a standalone module, it is placed on a shield, and does not contain a battery (or a supercap in that sense) And yes it does take 15 minutes or so for first results.