Arduino Serial Interrupts
Asked Answered
B

3

5

I am working on an Arduino Mega 2560 project. At a Windows 7 PC I am using the Arduino1.0 IDE. I need to establish a serial Bluetooth communication with a baud rate of 115200. I need to receive an interrupt when data is available at RX. Every piece of code I have seen use “polling”, which is placing a condition of Serial.available inside Arduino’s loop. How can I replace this approach at Arduino’s loop for an Interrupt and its Service Routine? It seems that attachInterrupt() does not provides for this purpose. I depend on an Interrupt to awake the Arduino from sleep mode.

I have developed this simple code that is supposed to turn on a LED connected to the pin 13.

    #include <avr/interrupt.h> 
    #include <avr/io.h> 
    void setup()
    {
       pinMode(13, OUTPUT);     //Set pin 13 as output

       UBRR0H = 0;//(BAUD_PRESCALE >> 8); // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 
       UBRR0L = 8; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
       UCSR0C |= (1 << UCSZ00) | (1 << UCSZ10); // Use 8-bit character sizes 
       UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);   // Turn on the transmission, reception, and Receive interrupt      
    }

    void loop()
    {
      //Do nothing
    }

    ISR(USART0_RXC_vect)
    {    
      digitalWrite(13, HIGH);   // Turn the LED on          
    }

The problem is that the subroutine is never served.

Bathulda answered 18/4, 2012 at 1:32 Comment(1)
What does your question have to do with bluetooth? Seems like you are just asking how to use a regular UART with interrupts?Pic
B
7

Finally I have found my problem. I changed the interruption vector "USART0_RXC_vect" by USART0_RX_vect. Also I added interrupts(); to enable the global interrupt and it is working very well.

The code is:

#include <avr/interrupt.h> 
#include <avr/io.h> 
void setup()
{
   pinMode(13, OUTPUT); 

   UBRR0H = 0; // Load upper 8-bits of the baud rate value into the high byte of the UBRR register 
   UBRR0L = 8; // Load lower 8-bits of the baud rate value into the low byte of the UBRR register 
   UCSR0C |= (1 << UCSZ00) | (1 << UCSZ10); // Use 8-bit character sizes 
   UCSR0B |= (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);   // Turn on the transmission, reception, and Receive interrupt      
   interrupts();
}

void loop()
{

}

ISR(USART0_RX_vect)
{  
  digitalWrite(13, HIGH);   // set the LED on
  delay(1000);              // wait for a second
}

Thanks for the replies!!!!

Bathulda answered 19/4, 2012 at 2:54 Comment(2)
What? You are in absolutely no way allowed to call delay inside an interrupt handler. Interrupt handlers should do as little as possible and as fast as possible, and most certainly not have dependencies on whether or not other interrupts are enabled and priorities between them.Comeback
Of course you are allowed to delay in an interrupt handler! It's not like it breaks the device or anything. Yes, it's not good practice, and yeah, if you were doing production code and devices that are actually important, it would actually even matter. There's nothing preventing anyone to define an interrupt handler that either makes the whole system wait for seconds or days even, or heck, just straight up locks the system. All that said, I agree that it's not a good place to put non-time critical code in an interrupt handler.Curtice
E
2

Did you try that code and it didn’t work? I think the problem is that you haven’t turned on interrupts. You could try calling sei(); or interrupts(); in your setup function.

Eructate answered 18/4, 2012 at 14:25 Comment(0)
S
-1

Just after UBRR0L = 8 instead of this:

 UCSR0C |= (1 << UCSZ00) | (1 << UCSZ01);

change to this:

 UCSR0C |= (1 << UCSZ00) | (1 << UCSZ10);
Sutphin answered 26/1, 2019 at 18:13 Comment(1)
Hi Abdelhalim, welcome to SO. Maybe also consider explaining the idea behind the code? It would improve your answer a lot, I guess. Thanks anyway for your contribution :-)Declination

© 2022 - 2024 — McMap. All rights reserved.