Time.now() in interrupt

This week I updated my OS from 1.2.1 to 1.5.2 and suddenly my processor crashed from time to time.

After investigation it seemed to be in an interrupt routine on the moment I got the current time.

void setup()
{
    .......
    pinMode(Drupteller, INPUT_PULLUP);
    attachInterrupt(Drupteller, tel, FALLING );
    .......
}

void tel()
{
    noInterrupts();
    if ((debounceCounter <= 0) && (digitalRead(Drupteller) == LOW))
    {
        daycounter++; 
        LastTime = Time.now();
        par.LastTime = LastTime ;
        debounceCounter = 10;
    }
    interrupts();
}

Before this worked well.

I putted a work around as:

void tel()
{
    noInterrupts();
    if ((debounceCounter <= 0) && (digitalRead(Drupteller) == LOW))
    {
        daycounter++; 
        LastTime = CurTime;
        par.LastTime = CurTime;
        debounceCounter = 10;
    }
    interrupts();
}


void loop()
{
    ............

	// Haal tijd
	CurTime = Time.now();
	
    ........

That worked fine.

Has someone knowledge of the Time object is no longer thread-save or what-so-ever?

Greets
Jean Paul

It’s not a good idea to have Time.now() inside an ISR (and has never been) since that call may (with SYSTEM_MODE(AUTOMATIC) and without SYSTEM_THREAD(ENABLED)) wait for Time.isValid() to become true when it isn’t already.
And that is a very, very bad idea especially when also having all interrupts disabled at the same time.

BTW, the resolution of Time.now() is merely one seconds so I doubt the time has to be captured inside the ISR for sake of precision. You could capture the millis() counter tho’

2 Likes