Using millis() or micros() in an ISR

Hi all,

I'm trying to take the time every time an interrupt occurs and find the duration of time that has passed between two interrupts. To accomplish this, I am using millis() in the ISR. I am testing my sketch by asking the Arduino to output the time taken by millis() at every interrupt, to which I keep getting 0s returned on the serial monitor. Intrigued, I tried using micros() to which I kept getting 500s returned on the serial monitor.

Does anyone have any idea as to why the time taken at the ISR's execution is not changing at all? I understand that at the ISR's execution, the clock is kind of frozen and you can't use delay() and such, but I just want to take the time at the execution of the ISR.

My current sketch is attached below. Timer0 is prescaled by 256 and external interrupts on pin 2 are enabled. The interrupts are coming from a square wave generator with 1Hz frequency and 5.0 Vp-p.

Thanks friends!

OP’s code where folks can see it and he might actually get a response.

// Thy Le 
// 7-24-2018 
// Ithaca, NY

//pin definitions

volatile unsigned long pulseWidth;
volatile unsigned long currentTime;
volatile unsigned long pastTime;
volatile int countNum;

volatile int ledPin = 13;

////////////////////////////////////////////////////////
ISR(INT0_vect){
   digitalWrite(ledPin, HIGH);
  countNum++;
  currentTime = micros();
  //pulseWidth = currentTime - pastTime;
  //pastTime = currentTime;
  //toggle LED at the end of Interrupt
 
  
  //Serial.println(countNum);
  Serial.println(currentTime);
  digitalWrite(ledPin, LOW);
 }
/////////////////////////////////////////////////////////    



////////////////////////////////////////////////////////

void setup() {
  Serial.begin(115200); //baud rate
  pinMode(ledPin, OUTPUT);
  // Enable External Interrupt Request 0 on pin 2
  sei();
  EIMSK |= (1 << INT0);
  EICRA |= (1 << ISC01);
  EICRA |= (1 << ISC11);
  //attachInterrupt(digitalPinToInterrupt(2), countBounce, RISING);
  //Reset TCCR0A
  //Set TCCR0B to 256 prescaler
  TCCR0B |= (1 << CS02);
  TCCR0B |= (0 << CS01);
  TCCR0B |= (0 << CS00);
  // Start the program
  Serial.println("Start");
 
}

void loop() {
 
}

OP’s picture is a picture of text. The same text I juts copied for him in a useful way. Why do people post pictures of text? What thought process leads one to think that is remotely useful?

Serial prints in an ISR?

OP: Don't use Serial.print inside an ISR. That's dangerous. Get your time and print it in loop.

PS. AWOL ninja posted me.

Serial does print in ISR.

To AWOL:

I attached the wrong file and I have since updated the attachment. The sketch is now in my posting. Why do people post pictures of text? Because they make mistakes and post the wrong file.

Now if you're not going to say anything useful other than rhetorical questions, I would suggest that you leave the post.

To Delta_G:

I've used Serial print inside an ISR many times, even in a program that analyzes pulse height and pulse width from a nuclear experiment. That's not the problem. I've tried taking Serial print out of the ISR and nothing changes :slight_smile:

To AWOL:

I attached the wrong file and I have since updated the attachment. The sketch is now in my posting. Why do people post pictures of text? Because they make mistakes and post the wrong file.

Now if you're not going to say anything useful other than rhetorical questions, I would suggest that you leave the post.

Tish-tish.

Literacy levels and comprehension skills aren't what they used to be.

You got it - I'm out.

tle3:
Serial does SOMETIMES print in ISR.

FTFY.

Since you seem to know more about it than any of us I'll leave you to figure it out then.

@tle3: thank you for your report to moderator.

Now: re-read this thread, but this time, carefully.

(I do so hope you're not one of those nuclear physicists with access to dangerous fissionable materials)

ea

My current sketch is attached below. Timer0 is prescaled by 256

//Set TCCR0B to 256 prescaler
  TCCR0B |= (1 << CS02);
  TCCR0B |= (0 << CS01);
  TCCR0B |= (0 << CS00);

This code does not do that. The bitshifted 0’s do not clear the default Timer0 prescaler of 64. The result is bits set in CS00:CS02 which is an external clock source setting.

To clear a bit, you use &= and not(!) For example

TCCR0B &= ~(1 << CS01);

More simple is to use

TCCR0B = 0;
TCCR0B = 1<< CS02;

By changing the prescaler from 64 to 256 , the millis() and micros() values reported from the timer will be off by a factor of 4.

hey were supposed to help OP feel better

They made me feel so good I decided to try address his problem :slight_smile:

cattledog:
They made me feel so good I decided to try address his problem :slight_smile:

They were on another thread I think.

tle3:
To AWOL:
I attached the wrong file and I have since updated the attachment. The sketch is now in my posting. Why do people post pictures of text? Because they make mistakes and post the wrong file.

Now if you're not going to say anything useful other than rhetorical questions, I would suggest that you leave the post.

It would be great if we had an icon we could click to hide a user from showing up on our individual screens.

larryd:
It would be great if we had an icon we could click to hide a user from showing up on our individual screens.

I'm sorry you feel that way :frowning:

AWOL:
I'm sorry you feel that way :frowning:

The post was for hiding user @tle3 from my screen, but you knew that :wink:

  TCCR0B |= (1 << CS02);
  TCCR0B |= (0 << CS01);
  TCCR0B |= (0 << CS00);

Note: You can’t clear a bit by OR’ing it with zero. If CS01 or CS00 are set, they will remain set. This might produce a prescale significantly different than you wanted.

Note: The micros() timer depends on Timer0. If you muck with the rate of Timer0 you can’t expect micros() to return a time in microseconds.

Note: ‘ledPin’ should be ‘const’ and not ‘volatile’.

I wrote a version that doesn’t muck directly with hardware registers and doesn’t try to display output in an ISR. It appears to work as desired:

volatile boolean NewInterval = false;
volatile unsigned long Interval;

const byte LEDPin = 13;
const byte SignalPin = 2;

void setup()
{
  Serial.begin(115200); //baud rate
  pinMode(LEDPin, OUTPUT);
  pinMode(SignalPin, INPUT_PULLUP);  // Just tapping a wire on Ground.
  attachInterrupt(digitalPinToInterrupt(2), GetTimeISR, FALLING);
  Serial.println("Start");
}


void GetTimeISR(void)
{
  static unsigned long previousTime;
  digitalWrite(LEDPin, HIGH);
  unsigned long currentTime = micros();


  Interval = currentTime - previousTime;
  previousTime = currentTime;
  NewInterval = true;
}


void loop()
{
  if (NewInterval)
  {
    unsigned long interval;
    // Get copies of any volatiles larger than a byte
    noInterrupts();
    interval = Interval;
    NewInterval = false;  // Ready for next interval
    interrupts();
    
    Serial.println(interval);
    digitalWrite(LEDPin, LOW);
  }
}

larryd:
It would be great if we had an icon we could click to hide a user from showing up on our individual screens.

+1. That way when on of them shows himself to have his knickers in a knot we could move on to people who actually want and appreciate help.

Delta_G:
+1. That way when on of them shows himself to have his knickers in a knot we could move on to people who actually want and appreciate help.

{cough} her {cough}

AWOL:
{cough} her {cough}

In English, male pronouns are used as gender neutral when the gender isn't readily apparent. I know that there is a group that wants to convince people that they have to write fifteen possible pronouns for everyone, but I don't go with that. I just call everyone him and hope that the code questions are more important to them than the language issues. If it isn't then I think we can safely assume that there is really no use in trying to do to much for them if they're not really thinking about the code. There are other forums to get your knickers in a knot over pronouns.

Would it be better if I had referred to OP as "it"

AWOL:
{cough} her {cough}

{cough} they {cough}

Their?