I have been toying with an idea using two interrupts as entry points to a timing section. If one of the interrupts starts the ISR, can the the other input be used as an ordinary input to end the timing? Since interrupts are ignored in the ISR, I don’t know if this would work.
- Tell us more about what you are wanting to do.
It is not clear what you have in mind, but as a general rule, an ISR should always be as short and fast as possible.
Yes.
a7
Option 1: use polling, no interrupt needed.
Option 2: let one ISR start a timer in main loop, let the other ISR stop this timer...
You should not build the timer in the ISR!
The timing section will be bi-directional, so either interrupt could start the timing. To end timing, the input at the other end would end it, but at that point it couldn’t be an interrupt.
I may have to abandon this concept as I would like to send text to an LCD display, but that would probably be ignored within the ISR.
- As mentioned, ISRs must be kept short.
Get in, set a flag, get out. - Back in loop, when the flag is set deal with it . . .
Why not ?
Interrupt A sets a flag ‘running’
Loop manages the timer
Interrupt B clears the ‘running’ flag
|
|
Loop sees the flag has been cleared, displays the timer.
Interrupt cannot be interrupted, BUT if interrupt is running and conditions for another interrupt happens, it is marked and the another interrapt is executed after the first one ends.
You can read current value of pin assigned to interrupt anytime.
If possible, it would be better to just set flag (or get timestamp) in the first interrupt and end, then let the other interrupt to set another flag/get another timestamp and resolve as much as possible in the loop.
(But short interrupt is a really strong recomendation, not hard rule. In my program the MCU spend 90% inside interrupt and just 10% in the loop and everything works just fine. But I know exactly, what I do…)
I think you have a misunderstanding of how interrupts work. You cannot wait inside the ISR for your timing to expire.
Please explain in more detail what you really want to do.
Tell us more: what is the signal source, and what should be counted and displayed, and how?
of course it can, but why bother? how accurate (sec, msec, usec, nsec) do you need to detect an event and how much other processing is being done when an event occurs that you need to interrupt that processing?
Why do you think that?
here's code i wrote for a "speed trap" on a model RR.
it captures the state of 2 IR-sensors that are a known distance apart and then executes a state machine that recognizes specific events in each state.
initially it recognizes an IR event from either input, captures a time stamp and once "triggered", waits for an event from the other sensor. In the Trig state it moves a dot across the 7-segment display to indicate that it is timing the train but after 30 sec will reset. (someone may have triggered it by moving their hand across a sensor).
it computes and displays the speed after the 2nd sensor is triggered but needs to Wait for all the remaining cars to pass before reseting
monitoring the IR-sensors and processing events is not time consuming and doesn't require interrupts
void
trap (void)
{
static byte dots;
// check inputs, return Nsensor if none active
for (unsigned n = 0; n < Nsensor; n++) {
sensorSt [n] = 0;
for (unsigned i = 0; i < 2; i++)
sensorSt [n] |= ! digitalRead (PinSensor [i][n]);
#if 0
if (sensorSt [n])
Serial.println (n);
#endif
}
// ---------------------------
switch (state) {
case Idle: // check for trains entering trap
if (sensorSt [0] || sensorSt [1]) {
pinExit = sensorSt [0] ? 1 : 0;
msec0 = msecLst = msec;
state = Trig;
cntTrig = 4 * 30; // 4 * # seconds
dots = 2;
Serial.println (" Trig");
}
break;
case Trig: // check for train exiting
if (sensorSt [pinExit]) {
dispSpd (msec - msec0);
state = Wait;
Serial.println (" Wait");
}
else if (msec - msecLst >= TrigPeriod) { // timer
msecLst = msec;
if (pinExit)
dots = 1 == dots ? 8 : dots / 2;
else
dots = 8 == dots ? 1 : dots * 2;
seg7segs (dots, SEGMENT_DEC);
if (! --cntTrig) {
seg7off ();
state = Idle;
Serial.println (" Idle - timeout");
}
}
break;
case Wait:
if (sensorSt [0] || sensorSt [1])
msecLst = msec;
else if (msec - msecLst >= WaitPeriod) { // timer
state = Idle;
seg7off ();
Serial.println (" Idle");
}
}
}
This may be what I need, or close to it.
I think that because the literature says a print command is an interrupt. It also says that after an interrupt, other interrupts are ignored.
Accuracy is not critical. I would be happy within a half second in most cases. Faster moving objects would require closer timing, but again, not critical.
This in early stages of development. The sensor has not been chosen. For now, I am assuming INPUT_PULLUP with grounds from the unknown sensors. I wish to send messages to an LCD at stages.
- Nothing detected
- Detected from right (or left)
- Time elapsed or speed.
- Just a heads up, sending a message to an LCD is blocking, take this into consideration when you write your sketch.
What do you mean by “blocking”?