Use 2 different interrupt input..

I do this sketch to measure the time between two digital pulses arriving on pin 2. I have handled an interrupt for this purpose:

byte sensorInterrupt = 0;
volatile unsigned long delta_pulse = 300001;// start up value
extern unsigned long timer0_millis;

void setup () {

attachInterrupt (sensorInterrupt, pulse, FALLING); // Interrupt pulse
}

void loop () {

Serial.println (delta_pulse);

void pulse () {


   if ((timer0_millis)> (1000)) {// ignore if  receive impulses lower than 1 second..
   delta_pulse = timer0_millis;
   timer0_millis = 0; // change the value of the register
  
   
  
     }
}
}

Now I need to implement an additional measure using the other fisical interrupt input ( pin3) , in order to have two distinct measures of time ...

I can not understand how I can use 2 different timer i 2 different interrupt.

Any idea ?

Move the attachInterrupt out of setup(). Use detachInterrupt when you have your value.

There are a lot of good examples here.

http://www.gammon.com.au/forum/?id=11504

Adding a second interrupt would just be duplicating the functions, and changing some values to use Pin 3 instead of Pin 2 for the second interrupt.

Please put your code inside [ code ][ /code ] tags.

It took three fixes to get this code to compile:

  • "bytes" isn't a type, changed to "byte";
  • "Pulse" isn't defined, changed to "pulse"; and
  • It looks like the closing bracket of loop() is missing.

That makes me think you've never used this code, and that your actual sketch is something different. I'm happy to see that you're posting a minimal sketch to the forum, rather than a huge sketch. It's important, though, that the code you post compiles, and demonstrates the problem. I can't verify that the changes I made result in what you actually intended.

Can you test this code, get it to compile, and verify for us that it demonstrates the problem?

stoutfiles: Move the attachInterrupt out of setup().

Really? Move it to where? It's quite normal for it to be in setup().

aarg: Really? Move it to where? It's quite normal for it to be in setup().

In the loop of course, preferably inside a function call in loop(). If he's using two interrupts it makes no sense to attach in setup since he's going to have to detach it for the second interrupt.

stoutfiles: In the loop of course, preferably inside a function call in loop(). If he's using two interrupts it makes no sense to attach in setup since he's going to have to detach it for the second interrupt.

Why would you need two interrupt handlers just to measure consecutive pulses? ISRs can hold state information in static variables.

thanks.. :)

My code is working since 2 years.

The timer0_millis autoincrement every millisec and i reset this register when an interrupt occurs.

If i use another interrupt i cannot use this register because this is reserved in first interrupt routine.

What i can use instead of "timer0_millis".

thans, Fabrizio.

That’s the advantage of a free running timer. Any routine can use it.

tmd3: .. It took three fixes to get this code to compile:

  • "bytes" isn't a type, changed to "byte";
  • "Pulse" isn't defined, changed to "pulse"; and
  • It looks like the closing bracket of loop() is missing.

That makes me think you've never used this code, and that your actual sketch is something different.

..

Ho.. yes.. this is a google traslator auto- aggiustament :) Sorry.. now i have correct

aarg:
That’s the advantage of a free running timer. Any routine can use it.

Yes but i reset it every interrupt… a cannot use it for second interrupt event…

timer0_millis = 0; //

portalsole: Yes but i reset it every interrupt... a cannot use it for second interrupt event..

timer0_millis = 0; //

Exactly. Don't reset it. Use millis(), save timestamps instead of resetting. millis() can be safely called once from inside an ISR, but not repeatedly because it is not incrementing.

portalsole: Now I need to implement an additional measure using the other fisical interrupt input ( pin3) , in order to have two distinct measures of time ...

Your first measurement of time is from falling edge to falling edge of the signal (period). Is your second time measurement using the same signal to measure duty cycle, HIGH or LOW time? If so, then its possible to use just one interrupt that detects logic change to trigger the various measurements.

EXTERNAL INTERRUPTS ON THE ATmega168/328

... or are you measuring two separate signals?

aarg: Why would you need two interrupt handlers just to measure consecutive pulses? ISRs can hold state information in static variables.

He just said he wants to measure a signal on Pin 2, and a signal on Pin 3. He needs two interrupt handlers, 0 and 1.

aarg: ... or are you measuring two separate signals?

Yes.. two separate signal.. the first is count pulse related to a water flow.. the new related to a future power measurament.

aarg: Exactly. Don't reset it. Use millis(), save timestamps instead of resetting.

I try to understand.. sorry but i'm newbie in arduino enviroment..

...something like this is correct ? :

void pulse () {

   old_pulse = last_pulse;
   last_pulse = timer0_millis;

   delta_pulse = (last_pulse - old_pulse);

  
     }

In this manner i can use two different interrupt routine with different variables but the same timer0_millis register...

But the question is..: with this approach I have to handle the timer0_millis overflow ?.

thank in advance, Fabrizio.

Forget timer0_millis

Use the millis() function.

As long as you use subtraction to find your intervals, rollover isn’t an issue.

10 - 4,294,967,286 == 20. Just like it should.

What is the difference between timer0_millis and function millis () ?

timer0_millis appare as a variable declared in this manner : extern unsigned long timer0_millis;

I do not understand why timer0_millis is auto-increment... is the effect of as it was declared ?

if i declared another variable "timer1_millis" in this manner : extern unsigned long timer1_millis; i can have another variable auto-increment indipendent from timer0_millis ?

This information can help me to understand my code.. ( i have copy some parte of this code in internet ).

Thanks, Fabrizio.

portalsole: What is the difference between timer0_millis and function millis () ?

timer0_millis is a variable, and millis() is a function. They're both defined in the file wiring.c. timer0_millis gets its value in the interrupt service routine (ISR) for Timer0. That ISR is also in wiring.c. millis() returns the value of timer0_millis. wiring.c is in this folder: ../hardware/arduino/avr/cores/arduino/ where .. is the folder containing the Arduino IDE.

timer0_millis is an unsigned long, and it's four bytes long. The processor has to read four memory locations to fetch its value. When you read timer0_millis directly, there's a chance that a timer interrupt will occur while timer0_millis is being read. That will change the value of timer0_millis, and there's a chance that the result will be garbled. millis() manages the interrupt enable bit in the processor status register to ensure that no interrupts occur while timer0_millis is being read.

You can manage interrupts yourself, by disabling them with noInterrupts() or cli() before reading timer0_millis, and re-enabling them with interrupts() or sei() afterward. But, with the availability of millis(), there doesn't seem to be much of a reason to go to the effort, or take the risk. If you forget to manage interrupts, and misoperations result, the code will be very difficult to troubleshoot.

Another good reason to avoid using timer0_millis is this: once your sketch has access to timer0_millis, it can write a value to it - as your sketch does. That may appear to be convenient, but it's troublesome. It's not so bad in a simple sketch, but, in a more complicated program, several processes may need to fetch the current time independently. If one process modifies the value of the current time, all the others will get inconsistent results. You're dealing that problem right now. Again, if trouble occurs, and you don't have the relevant issue in focus, it will be very hard to troubleshoot. In the long term, I think you'll be happier saving the time when you need to know it, and watching the difference between the current time and the saved value to see how long it's been since a particular event occurred. And, as others in this thread have noted, that will make a second timer unnecessary,

if i declared another variable "timer1_millis" in this manner ... i can have another variable auto-increment indipendent from timer0_millis ?

No. Your sketch doesn't define timer0_millis, or determine how it's managed. That requires a definition of timer0_millis, and an ISR, both found in wiring.c. The "extern" statement only tells your sketch to use the variable timer0_millis as it's defined elsewhere. If you want another "autoincrement" variable based on timer2, you'll have to write that code yourself. It's not clear what benefit you'll get from that, though, because the current time is always available using millis().