Interrupts

Hi,

Im planning to use two interrupts to read pulses from a tachometer and a reed switch (wheelrortations).
This will generate max 225 interrupts/sec (200 tacho/25 wheel).

I wonder if anyone knows how the arduino handles both interrupts activated at the same time.

Thanks in advance.

I wonder if anyone knows how the arduino handles both interrupts activated at the same time.

No, it doesn’t. It is impossible to activate two interrupts at the same time. Interrupt processing is turned off while an interrupt is being processed. The second interrupt will be queued (one instance only) and processed when the first one ends.

Ok, thanks thats will work.

They will not be activated at the same time. One will always come before the other. Once an interrupt routine is activated it disables interrupts and the second one will be queued. Having said that you should keep interrupt routines as short as possible. Do not read the sensors inside the interrupt routine but set a global flag variable indicating that the main loop should read the sensor.

I know.
My only interrupt code is "counter++;"

I was a bit unclear, I ment the singnal to the pin.
It should be possible to get the signal at the same time to both pins and in that case I guess the arduino selects one as the first ?

It should be possible to get the signal at the same time to both pins

You aren't dealing with one signal. You are dealing with two signals. In the real world, nothing happens simultaneously.

And, so what if you miss one pulse from the tachometer. The difference between 4,000 rpm and 3,999 is not significant, is it?

Well PauS, dont you think I know how many singnals there are or did I express a problem with missing a pulse ?
Id be happy not to read this kind of totally unuseful comments.

Nick, thats really good info, thanks.
My question about interrupts is answered (you should read this PaulS) :

What is interrupt priority?

Since there are 25 interrupts (other than reset) it is possible that more than one interrupt event might occur at once, or at least, occur before the previous one is processed. Also an interrupt event might occur while interrupts are disabled.

The priority order is the sequence in which the processor checks for interrupt events. The higher up the list, the higher the priority. So, for example, an External Interrupt Request 0 (pin D2) would be serviced before External Interrupt Request 1 (pin D3).

Well PauS, dont you think I know how many singnals there are or did I express a problem with missing a pulse ?

"the signal" and "one of the signals" are two different things. You said one and seem to have meant the other. If you can't express yourself clearly, I don't see how you can then criticize people who seek clarification.

Your concern with interrupts happening while an interrupt is being processed, and therefore being ignored seems to indicate that you ARE concerned with missing a pulse.

PaulS,

the problem is that you answer questions that have never been asked.
And you are wrong in your assumption that I care if I miss a pulse, my question was how the arduin handles interrupts wich dont require you to discuss a specific solution.

And secondary, if you have that hard to understand the question, why do you answer ?
You could ask for more info instead of assuming things and giving useless answers.

And that is my last comment on this.

Someone on this topic, please guide me…
I understand that arduino mega cannot handle two interrupts the way I have set them up below;
I am trying to capture the RPM of two rotating parts and calculate a ratio to guide me with roto-molding.
Is there a way to attach and detach the interrupts to achieve this?
Presently, the code capture the first (fan_e) but ignore the second…
Help would be most welcome!
Alain (Newbe from Canada)


#include <LiquidCrystal.h>
LiquidCrystal lcd(3, 5, 9, 10, 11, 12);

volatile float time_e = 0;
volatile float time_e_last = 0;
volatile int rpm_e_array[4] = {0,0,0,0};

volatile float time_i = 0;
volatile float time_i_last = 0;
volatile int rpm_i_array[4] = {0,0,0,0};

volatile int rap = 0;

void setup()
{
//Digital Pin 2 and 21 Set As An Interrupt
attachInterrupt(0, fan_e_interrupt, FALLING);
attachInterrupt(2, fan_i_interrupt, FALLING);

// set up the LCD’s number of columns and rows:
lcd.begin(16, 2);

// Print a message to the LCD.
lcd.print(“RPM_e RPM_i Rap:”);

}

//Main Loop To Calculate RPM and Update LCD Display
void loop()
{
int rpm_e = 0;
int rpm_i = 0;
int rap = 0;

while(1){

//Slow Down The LCD Display Updates
delay(400);

//Clear The Bottom Row
lcd.setCursor(0, 1);
lcd.print(" ");

//Update The Rpm_e Count
lcd.setCursor(0, 1);
lcd.print(rpm_e);

//Update The Rpm_i Count
lcd.setCursor(6, 1);
lcd.print(rpm_i);

//Update The Rap Count
lcd.setCursor(12, 1);
lcd.print(rpm_e / (rpm_i - rpm_e));

//Update The RPM_e
if(time_e > 0)
{
//4 Sample Moving Average To Smooth Out The Data
rpm_e_array[0] = rpm_e_array[1];
rpm_e_array[1] = rpm_e_array[2];
rpm_e_array[2] = rpm_e_array[3];
rpm_e_array[3] = 60*(1000000/(time_e*2));
//Last 4 Average RPM Counts Eqauls…
rpm_e = (rpm_e_array[0] + rpm_e_array[1] + rpm_e_array[2] + rpm_e_array[3]) / 4;
}

//Update The RPM_i
if(time_i > 0)
{
//4 Sample Moving Average To Smooth Out The Data
rpm_i_array[0] = rpm_i_array[1];
rpm_i_array[1] = rpm_i_array[2];
rpm_i_array[2] = rpm_i_array[3];
rpm_i_array[3] = 60*(1000000/(time_i*2));
//Last 4 Average RPM Counts Eqauls…
rpm_i = (rpm_i_array[0] + rpm_i_array[1] + rpm_i_array[2] + rpm_i_array[3]) / 4;
}
}

}

//Capture The IR Break-Beam Interrupt
void fan_e_interrupt()
{
time_e = (micros() - time_e_last);
time_e_last = micros();
}

void fan_i_interrupt()
{
time_i = (micros() - time_i_last);
time_i_last = micros();
}

How to use this forum

Code tags, please.

My first reaction is that times on the Arduino are stored as unsigned long. Using float is going to cause a fairly lengthy delay because of the fact that floating point arithmetic is implemented in software.

I totally agree with Nick. You won't get any better resolution working with floats because micros() is already at max resolution for microseconds. Floats are WAY slow. If you can avoid them in an ISR, do it.

Also, how fast are your two parts rotating? I hope they're not rotating any faster than 150 rpm.

delay(400);

You're going to miss any double interrupts that happen during this delay. Your ISRs only save the last time an interrupt happened. That does give you a buffer of one interrupt, but you need to handle it before another interrupt happens or you'll miss it. If this is a problem, you could save timestamps in an array.

Quite right. I spotted the delay() call but didn't worry initially because the interrupt will still happen, however you are correct that the time recorded will be out if two interrupts happen before you process the first one.

I don't often volunteer to help people that add an infinite loop to an infinite loop. The loop() function is called in an infinite loop. Adding another infinite loop inside that function is quite often a sign of cluelessness. Remove that, and let loop() get called the way it is supposed to.