Serial and Timer Interrupt Simultaneously

Hi, I am currently writing code where the Arduino receives data serially and uses a timer that interrupts to execute code for performing a separate action. I had the individual components working, but found that both these components could not operate simultaneously. Looking up possible solutions, I saw that the problem might occur when the data is being received serially.

My question then is if it is possible to have a separate timer interrupt while also receiving data serially? If so, what resources can I check up on to solve this problem?

Thank you

You really should post your code to get a specific recommendation. Getting a timer interrupt and a serial interrupt to get along is not a real problem unless you are doing something like spending too much time inside your timer interrupt ISR function.

The standard arduino code uses timer0 interrupts to allow delay() and millis() functions to work and don't interfere with normal serial date.

Lefty

Sorry for the lack of code. Here is what I’ve been using to just test if receiving data serially works with a timer interrupt.
My real timer2 interrupt has slightly more lines of code, but it mainly consists of utilizing SPI to talk with a DAC.
I’ve omitted the SPI initialization code since I cannot even get this to work.

Also, the data received serially is coming from another Arduino that simply calls Serial.println() and delays for about 50 micro seconds before sending another byte.

Here is my setup()

void setup() {
  /* Timer2 configuration */
  // enable mode compare/match mode A 
  TIMSK2 = 1 << OCIE2A;

  // timer2 counts up to 200 and then interrupt is called
  OCR2A = 200;

  // set timer2 clock source as internal I/O clock 
  ASSR &= ~(1 << AS2);

  // set CTC mode
  TCCR2A = 1 << WGM21;

  // set timer2 to operate at 1/64 I/O clock speed
  TCCR2B = 1 << CS22;

  // enable global interrupts
  sei();

  // set serial communication baud rate and clear buffer
  // give time for Arduino to initialize
  Serial.begin(19200);
  Serial.flush();
  delay(10);
}

My simple loop() for testing

void loop() {
  while(Serial.available() > 0) {
     freq =  Serial.read();
  }
}

And finally my timer interrupt

ISR(TIMER2_COMPA_vect) {
  Serial.println(freq, DEC);

}

Thank you.

When an ISR is executed, interrupt processing is disabled for that ISR. This will prevent you from sending serial data within the ISR.

You can get around this by re-enabling interrupts within your ISR yourself, but you want to be extremely careful about doing so. In your example, doing so would be unnecessary. What you should do is set a global flag in the ISR, and in your loop() function, monitor that flag and issue the println when it’s set (then unset). The global will have to be declared volatile for it to work properly.

jraskell, I believe I understand what you mean, but let me check one more thing since I realized I showed a bad example of what I'm trying to do.

In the case that my ISR does nothing but send data out on the SPI port (no use of Serial functions), would this interfere with reading data on the serial port?

When an ISR is executed, interrupt processing is disabled for that ISR.

Wrong. Interrupts are globally disabled when an interrupt service routine is entered.

This will prevent you from sending serial data within the ISR.

Wrong. Sending does not require interrupts to be enabled.

You can get around this by re-enabling interrupts within your ISR yourself

This is very bad advice.

What you should do is set a global flag in the ISR, and in your loop() function, monitor that flag and issue the println when it's set (then unset). The global will have to be declared volatile for it to work properly.

[u]This is VERY GOOD ADVICE.[/u]

[quote author=Coding Badly link=topic=51484.msg367637#msg367637 date=1297193741]

When an ISR is executed, interrupt processing is disabled for that ISR.

Wrong. Interrupts are globally disabled when an interrupt service routine is entered.

[/quote]

That is what I was trying to say.