Arduino Serial Interrupts

21,730

Solution 1

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!!!!

Solution 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.

Share:
21,730
beb_lm
Author by

beb_lm

Updated on January 27, 2020

Comments

  • beb_lm
    beb_lm over 4 years

    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.

  • Romain Valeri
    Romain Valeri over 5 years
    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 :-)
  • hlovdal
    hlovdal over 4 years
    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.
  • Jani Kärkkäinen
    Jani Kärkkäinen almost 3 years
    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.