Interrupt handler - Serial.print doesn't seem to work.

All --

I'm using an Uno board and working on a sketch that in cycles a device on and off in (roughly) 1 min on and 1 min off cycles for a period of 8 hours. The device will output a fail signal if it detects a problem, and I have the sketch set up to uses an external interrupt on Pin 2 (int 0) to go to a loop that turns the device off, lights a "Fail" LED and does a Serial.print with a fail status and the time of failure.

The interrupt does call the handler, the pin changes seem to work, and it "halts" (via the "while(1);" loop), but I can't seem to get the fail message to the serial port.

Has anyone run into this before?

The code for that portion is posted below:

void failHold() {
detachInterrupt(0);
Serial.println("FAIL");
Serial.print("Fail detected at "); Serial.print(millis()/1000, DEC); Serial.println("S. Correct problem and RESET.");
Serial.println("");
digitalWrite(ampKeyPin, LOW); // unkey the amplifier
digitalWrite(txKeyPin, LOW); // unkey the transmitter
digitalWrite(keyLEDPin, LOW); // clear the Key LED
digitalWrite(failLEDPin, HIGH); // set FAIL indicator
while(1){};
}

Thanks in advance!

-- Jason

Are you calling failHold() from an interrupt routine? That's really bad news, interrupt routines should complete and return ASAP (certainly shouldn't be calling into a library routine). While you are in an interrupt routine you are blocking other interrupts from running, such as the ones that are sending out bytes to the serial hardware....

You should be setting a flag in the interrupt routine for situations like this that loop() checks everytime through and call the failHold() from inside loop().

Hi Mark,

Yes...as far as I can tell the best way to do it is through an interrupt because I need it to immediately shut down the two devices.

Calling failHold() from inside the loop when the fail pin goes low would I believe allow the devices under test to keep running even after a failure is detected.

Currently loop() is using delay(mS) to establish the on and off periods, but by using a "check and see" approach to the timing, I can have it cycle through error checking, and keep a running clock on the monitor.

Thanks Mark - you've confirmed my suspicions about the serial port.

R/
Jason

By all means shutdown the devices in the interrupt routine if that's just toggling some of the pins, but hand over the Serial prints to loop()....

Hi Mark,

Is there any way to control where in loop() execution resumes?

R/
Jason

It sounds like you might want to consider restructuring your code to avoid the use of delays - might not need interrupts at all in that scenario.

void failHold() { 

...
 Serial.println("FAIL");
 Serial.print("Fail detected at "); Serial.print(millis()/1000, DEC); Serial.println("S. Correct problem and RESET.");  
 Serial.println("");
...
 while(1){};
}

This will definitely fail. In version 1.0 of the IDE serial sends are done by an interrupt routine (not this one). However you never leave this one.

Is there any way to control where in loop() execution resumes?

No. Interrupts resume from the instruction that was interrupted.

As wildbill says, restructure to use timing tests rather than delays.

Thanks wildbill, Nick and Mark.

It's apparent what I must now do. I think it will give me better control and while a little less efficient, timing isn't critical so I think it will work out just fine.

Thanks again!