Autonomo pulseIn and RTCZero

there is some problem using both funcions?. I’m trying to use RTCZero for wakeup the samd21 and read data from a sensor using pulseIn, but the processor never wakeup. if only use RTCZero the processor wakeup and sleep as I specs…

Can you make sure that you have version 1.5.0 of the RTCZero library. There was a issue with earlier versions which could interfere with other code which relies on interrupts.

i have the version 1.5.0 of RTCZero. I’m trying to make successive alarms every hour to get data from a sensor and sleep between measures. the alarms are changed using time.h library to get the time of the next alarm, It’s possible to use RTCZero to make a timer to wakeup the autonomo from sleep and at the same time get the date and time from it without using time.h library?

here is a short code of what I want

#include <RTCZero.h>

RTCZero rtc;

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

/* Change these values to set the current initial date */
const uint8_t day = 15;
const uint8_t month = 6;
const uint8_t year = 15;

void setup()
{
Serial.begin(9600);
rtc.begin(); // initialize RTC 24H format. The dual option is H12

// Set the time
rtc.setHours(hours);
rtc.setMinutes(minutes);
rtc.setSeconds(seconds);

// Set the date
rtc.setDay(day);
rtc.setMonth(month);
rtc.setYear(year);

// Set the alarm at the 12 second mark
rtc.setAlarmSeconds(50);

// Match only seconds (Periodic alarm every minute)
rtc.enableAlarm(RTCZero::MATCH_SS);

// Attach ISR
rtc.attachInterrupt(RTC_ISR);

// Set LED pin as output
pinMode(13, OUTPUT);

// Set sleep mode
SCB->SCR |= SCB_SCR_SLEEPDEEP_Msk;

// Sleep sketch startup delay
delay(5000);

}

void RTC_ISR()
{
// Blink LED
digitalWrite(13, HIGH);
Serial.println(“RTC Alarm”);
// Print date…
Serial.print(rtc.getDay());
Serial.print("/");
Serial.print(rtc.getMonth());
Serial.print("/");
Serial.print(rtc.getYear());
Serial.print("\t");

// …and time
Serial.print(rtc.getHours());
Serial.print(":");
Serial.print(rtc.getMinutes());
Serial.print(":");
Serial.print(rtc.getSeconds());

SerialUSB.println();
//rtc.setAlarmSeconds(10);

// Match only seconds (Periodic alarm every minute)
rtc.enableAlarm(RTCZero::MATCH_SS);

delay(1000);
digitalWrite(13, LOW);
}

void loop()
{
// Disable USB
USB->DEVICE.CTRLA.reg &= ~USB_CTRLA_ENABLE;

//Enter sleep mode
__WFI();

// …Sleep

// Enable USB
USB->DEVICE.CTRLA.reg |= USB_CTRLA_ENABLE;

delay(500);

// Stay awake for two seconds
delay(2000);
}

There are few possible issues here.

Are you using Serial (with an external component attached to connect to the PC) in order to avoid the issues with using SerialUSB when entering sleep mode?

Also, you shouldn’t attempt to execute any real code in the ISR. The SAMD processors do support multiple nested interrupts, however, the priority levels have to be tightly controlled. Actions such as sending data to a Sercom/UART, may rely on an interrupt to know when the data has been sent. That interrupt may be blocked if a higher priority (such as the RTC_ISR) is currently running.

A better pattern is to simply set a flag (use volatile to be safe) in the ISR. Then in the main loop check the status of that flag and execute the additional code if required.

i have a FTDI232 connected directly to D0 and D1 and a terminal reading the data over FTDI. I am using the microusb to upload new code. So yes I have and external component connected to the autonomo.

Trying another code to get successive sleep and interrupts (actually only two in this code)…:

#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()
{
Serial.begin(9600);
delay(5000);
pinMode(LED_BUILTIN, OUTPUT);
digitalWrite(LED_BUILTIN, LOW);

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()
{
rtc.standbyMode(); // Sleep until next alarm match
}

void alarmMatch()
{
Serial.println(1);
digitalWrite(LED_BUILTIN, HIGH);

Serial.println(2);
delay(1000);
Serial.println(3);
digitalWrite(LED_BUILTIN, LOW);
Serial.println(4);
rtc.setAlarmTime(17, 00, 50);
rtc.enableAlarm(rtc.MATCH_HHMMSS);
}

I found that the last number the terminal show is “2” so, the delay() function is freezing mi code. I comment the delay line and all works just fine.

there is a better delay() function or at least a function that don’t freeze my code?

Don’t execute any of the real functionality in the ISR, that will always cause you problems. In this case the built-in delay() method is waiting for a counter to reach a certain value (now + 1000). That counter uses a timer which drives an interrupt which increases that value. If that interrupt is blocked (as will normally be the case if an ISR is currently running), then the counter is not incremented and delay() will never return.

Here is the pattern I was referring to:

volatile bool rtc_flag = false;

void setup()
{
    // Do setup
}

void RTC_ISR() 
{
    rtc_flag = true;
}

void loop()
{
    if (rtc_flag) {

        rtc_flag = false;

        // Do interrupt stuff
    }

    // Do regular stuff
}