Arduino MKR1010 - RTC skipr seconds when polling every second

The flag (a bool variable would work quite nicely) is used to signal from the ISR to the non-ISR main code (your loop() function) that an event has occurred. In this case, the event would be the 1s interrupt from the RTC. The flag needs to be declared 'volatile' because it is accessed by both the ISR and non-ISR code.

Doing it this way keeps the ISR nice and short and prevents you from doing operations in the ISR that you shouldn't be doing ... time-consuming calculations, Serial prints, etc.

Hi @Nikosant03

In the code below, I modified the RTCZero library's SimpleRTCAlarm example to trigger RTC to read the epoch time every second.

The alarm is actually initialised to trigger every minute, the minimum for the SAMD21 RTC peripheral, however each time it's triggered the next alarm time is incremented by 1 second, causing it to override the standard behaviour and thereby trigger every second instead.

The code also incorporates @gfvalvo suggestion, by only setting a volatile interrupt flag in the RTC alarm callback function. This keeps the code within the callback to a minimum, allowing the loop() function in the main body of the sketch to do all the work.

Here's the code:

/*
  Simple RTC Alarm for Arduino Zero and MKR1000

  Demonstrates how to set an RTC alarm for the Arduino Zero and MKR1000

  This example code is in the public domain

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

  created by Arturo Guadalupi <a.guadalupi@arduino.cc>
  25 Sept 2015
  
  modified
  21 Oct 2015
*/

#include <RTCZero.h>

/* Create an rtc object */
RTCZero rtc;

volatile bool rtcAlarm = false;                 // Define the RTC alarm interrupt flag

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

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

void setup()
{
  SerialUSB.begin(115200);                      // Initialise the native USB port
  while(!SerialUSB);                            // Wait for the console to open...

  rtc.begin(); // initialize RTC 24H format

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

  rtc.setAlarmTime(16, 0, 1);                   // Set the RTC alarm to trigger 1 second after intitalisation
  rtc.enableAlarm(rtc.MATCH_SS);                // Set alarm to trigger every minute, (this will be overridden)
  
  rtc.attachInterrupt(alarmMatch);
}

void loop()
{
  static unsigned long count = 1;               // Initialise the counter
  
  if (rtcAlarm)                                 // Check if RTC alarm has occured
  {
    rtcAlarm = false;                           // Reset the RTC alarm interrupt flag
    byte seconds = rtc.getAlarmSeconds();       // Get the current RTC alarm time
    seconds = (seconds + 1) % 60;               // Advance the next alarm time by 1 second
    rtc.setAlarmSeconds(seconds);               // Set the current RTC alarm time with 1 second added
    SerialUSB.print(F("Epoch time "));          // Display the results...
    SerialUSB.print(count++);
    SerialUSB.print(F(" : "));
    SerialUSB.println(rtc.getEpoch());
  }
}

void alarmMatch()
{
  rtcAlarm = true;                               // Set the RTC alarm interrupt flag
}

Now that the RTC itself is essentially calling the epoch time, it doesn't miss a beat.

Here's the output:

Epoch time 1 : 1443196802
Epoch time 2 : 1443196803
Epoch time 3 : 1443196804
Epoch time 4 : 1443196805
Epoch time 5 : 1443196806
Epoch time 6 : 1443196807
Epoch time 7 : 1443196808
Epoch time 8 : 1443196809
Epoch time 9 : 1443196810
Epoch time 10 : 1443196811
Epoch time 11 : 1443196812
Epoch time 12 : 1443196813

@MartinL @gfvalvo That's super clear now, thank you both!!