Serial & interrupt: annoying problem introduced in Arduino 1.0

Hello,

This simple program doesn't work if the speed of the serial for debugging is lower than 115200. The card seems to hang, even the few works "doLI" are not written in the console.

I use a Seedunio Mega:

const byte LIpinI = 2;

void setup()
{
  Serial2.begin(115200);
  pinMode (LIpinI, INPUT);
  attachInterrupt(0, doLI, RISING);
  Serial2.println("------------ START LI ------------");
}

void doLI()
{
  detachInterrupt(0);
  Serial2.println("doLI"); // this line is nerver seen
}

void loop()
{
  Serial2.println(pulseIn(LIpinI, HIGH)); // it works very slowly !
}

I saw this remark which seems to explain the reason.

http://forums.adafruit.com/viewtopic.php?f=25&t=32234

Under Arduino, yes, Serial inside an interrupt runs into problems on Arduino 1.0+. Due to the circular buffer used to implement the Serial streams, the method used to write to it, and the relative interrupt priorities, a serial write to a full buffer will wait until the buffer has space before releasing. Unfortunately, since the Serial interrupts take lower priority than the user pin interrupts, the buffer is never emptied, so the Serial write method hangs indefinitely. It's a really annoying problem, and one newly introduced in 1.0 (They made the choice to make not losing data a higher priority.)

Is there a way to avoid this behaviour?

I can't debug code, because it's hanging very quickly, even with few debugging information sent in the Serial2.

Thanks.

void doLI()
{
detachInterrupt(0);
Serial2.println("doLI"); // this line is nerver seen
}

Why do you say it will never been seen, it will if that ISR function is called. And as serial outputs use interrupts they cannot be used inside a ISR.

Lefty

I mean that this line is not seen in the console if the speed of Serial2 is lower than 115200.

115200 = I will see the line
9600 or higher = I don't see the line (with my console app at the same speed!)

syrinx:
I mean that this line is not seen in the console if the speed of Serial2 is lower than 115200.

115200 = I will see the line
9600 or higher = I don't see the line (with my console app at the same speed!)

Possibly because the data gets sent out quick enough before the ISR has disabled all interrupts? Bottom line is that you should not be doing serial commands inside a ISR function, ever, stop doing that.

Lefty

I didn't know, I'm used to do that during 1 year!

Thank you for the help.

I don't understand why it was working previously?

syrinx:
I didn't know, I'm used to do that during 1 year!

Thank you for the help.

I don't understand why it was working previously?

Because starting with IDE 1.0 the serial library started using fully buffered interrupt driven serial outputs, so as interrupts are disabled globally once inside a ISR no other interrupts can function so trying to send serial just stops all code from proceeding. It was never a good idea to use serial output commands even in the older versions as it meant that all other interrupts were disabled for too long a period, but it's essential to not use serial coommands now.

Lefty

OK. It's clear now.

Thanks a lot!