USART interrupt on Arduino Uno

Hi,

I have look at a ton of post on incoming data interrupts which are handled with AVR libraries. From what I have understand, Arduino Uno won’t work with those libraries. So, what can I do?

The main goal of the project is to keep the arduino on a low consumption mode until some data arrives. Thanks for any help you can provide me.

Oh, the data will come from a HC-05 bluetooth module

EDIT: I found it uses a ATmega328P microcontroller so with will work with AVR libraries.

Here is the code I used. The problem is that UCSZ10 appears as not declared.

#include <avr/interrupt.h> 
#include <avr/io.h> 

#define USART_BAUDRATE 9600
void setup()
{
   pinMode(13, OUTPUT); 

   UBRR0L = USART_BAUDRATE & 0xff;
   UBRR0H = USART_BAUDRATE >> 8;
   UCSR0C |= (1 << UCSZ00) | (1 << USBS0); // 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_RXC)
{  
  digitalWrite(13, HIGH);   // set the LED on
  UDR0 = 1;
  delay(1000);              // wait for a second
}

I adapted the coded to what I found on the microcontroller datasheet. Tomorrow gonna test it. Still, any help would be appreciated :smiley:

luisda2994:
Hi,

I have look at a ton of post on incoming data interrupts which are handled with AVR libraries. From what I have understand, Arduino Uno won’t work with those libraries. So, what can I do?

The main goal of the project is to keep the arduino on a low consumption mode until some data arrives. Thanks for any help you can provide me.

Oh, the data will come from a HC-05 bluetooth module

EDIT: I found it uses a ATmega328P microcontroller so with will work with AVR libraries.

Here is the code I used. The problem is that UCSZ10 appears as not declared.

#include <avr/interrupt.h> 

#include <avr/io.h>

#define USART_BAUDRATE 9600
void setup()
{
  pinMode(13, OUTPUT);

UBRR0L = USART_BAUDRATE & 0xff;
  UBRR0H = USART_BAUDRATE >> 8;
  UCSR0C |= (1 << UCSZ00) | (1 << USBS0); // 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_RXC)

  digitalWrite(13, HIGH);  // set the LED on
  UDR0 = 1;
  delay(1000);              // wait for a second
}




I adapted the coded to what I found on the microcontroller datasheet. Tomorrow gonna test it. Still, any help would be appreciated :D

look though HardwareSerial.h, HardwareSerial.cpp, HardwareSerial_private.h in
Arduino\hardware\arduino\avr\cores\arduino

The Arduino environment has support for Interrupt driven TX and RX with 63byte buffers.

Chuck.

chucktodd:
look though HardwareSerial.h, HardwareSerial.cpp, HardwareSerial_private.h in
Arduino\hardware\arduino\avr\cores\arduino

Thanks for the information. I did it and ended somehow understanding that. Right now I’m try to use those libraries but the compiler keeps telling me I’m not initializing correctly the object of the class. My ignorance is big. Could you please help me a bit with the code? Thanks.

This is what I’ve done until now. I really don’t know how to create an object for HardwareSerial. Also, the Tx and Rx pins would be the 0 and 1 pins on the Arduino Uno?

#include <HardwareSerial.cpp> 

#define BAUD 9600
#define FOSC 16000000
#define MYUBRR FOSC/16/BAUD-1


void setup()
{
  HardwareSerial HW(0,(uint8_t)103,0,(uint8_t)152,6,0);
   pinMode(12, OUTPUT); 
   digitalWrite(12, HIGH);

}

void loop()
{

}

ISR(USART_RXC_vect)
{  
  digitalWrite(12, LOW);   // set the LED on
  delay(1000);              // wait for a second
}

luisda2994:
Thanks for the information. I did it and ended somehow understanding that. Right now I’m try to use those libraries but the compiler keeps telling me I’m not initializing correctly the object of the class. My ignorance is big. Could you please help me a bit with the code? Thanks.

This is what I’ve done until now. I really don’t know how to create an object for HardwareSerial. Also, the Tx and Rx pins would be the 0 and 1 pins on the Arduino Uno?

#include <HardwareSerial.cpp> 

#define BAUD 9600
#define FOSC 16000000
#define MYUBRR FOSC/16/BAUD-1

void setup()
{
 HardwareSerial HW(0,(uint8_t)103,0,(uint8_t)152,6,0);
  pinMode(12, OUTPUT);
  digitalWrite(12, HIGH);

}

void loop()
{

}

ISR(USART_RXC_vect)
{  
 digitalWrite(12, LOW);   // set the LED on
 delay(1000);              // wait for a second
}

the Arduino environment creates an object Serial which is a HardwareSerial class configured for UART0.
You don’t instantiate HardwareSerial Objects. Just use the pre-Existing ones.

void setup(){
  Serial.begin(9600); 
}

If you want to overwrite the Interrupt Handler you will have to modify the HardwareSerial.cpp code.

Just edit it and recompile.

but DON’T use Delay() inside the ISR code. The Arduino environment is not ReEntrant!

What are you trying to accomplish?

Chuck.

chucktodd:
If you want to overwrite the Interrupt Handler you will have to modify the HardwareSerial.cpp code.

Do I need to modify it?

chucktodd:
What are you trying to accomplish?

I'm connecting a bluetooth module HC-05. The goal is to trigger the interrupt whenever I send something from an android app to the arduino, so the latter sends back data previously collected.

I have acomplished that by polling and using SoftwareSerial.h. Since now I'll use HardwareSerial I guess the Tx and Rx pins are the 0 and 1, right? And so, I'd have to power the arduino from an external battery and not from an USB cable, otherwise those pins would be used by the powering PC...

luisda2994:
Do I need to modify it?

I'm connecting a bluetooth module HC-05. The goal is to trigger the interrupt whenever I send something from an android app to the arduino, so the latter sends back data previously collected.

I have acomplished that by polling and using SoftwareSerial.h. Since now I'll use HardwareSerial I guess the Tx and Rx pins are the 0 and 1, right? And so, I'd have to power the arduino from an external battery and not from an USB cable, otherwise those pins would be used by the powering PC...

Question:
Is your Arduino going in to sleep mode?
Why can't you check Serial.available() to so see if a message is pending?
If you truly need Interrupt driven response speed (2uS) just connect digital pin 2 to pin 0 (RX)

volatile static bool triggered;
void ISR(){
  detachInterrupt(0);// else interrupt would trigger for every bit of RS232 Transmision
  triggered=true;
  // other fast simple response code here, no library calls, no delay(), 
  }
void setup(){
pinMode(2,INPUT);
attachInterrupt(0,ISR,FALLING); // execute ISR() whenever data appears on Serial port
}

void loop(){
  if(triggered){
    // do somthing, can use library Calls, anything, even send data out the Serial port!
    triggered = false; // reset flag
    attachInterrupt(0,ISR,FALLING); // enable interrupt for next serial activity
  }  
}

Why not use Serial.available()?

void loop(){
  if(Serial.available()) { // there is data in the Serial buffer
   uint8_t ch = Serial.read();
   if(ch=='?'){ // I have decided that a question mark is a command to request data
     Serial.println("Ok, Here is the data I am returning, YES, I will Divorce YOU!");
     }
   }
}

Chuck.

1 Like

chucktodd:
Question:
Is your Arduino going in to sleep mode?

Yes, that's the idea. I need to extend the life of the battery. And I hope that will help.

chucktodd:
Why can't you check Serial.available() to so see if a message is pending?
If you truly need Interrupt driven response speed (2uS) just connect digital pin 2 to pin 0 (RX)

volatile static bool triggered;

void ISR(){
 detachInterrupt(0);// else interrupt would trigger for every bit of RS232 Transmision
 triggered=true;
 // other fast simple response code here, no library calls, no delay(),
 }
void setup(){
pinMode(2,INPUT);
attachInterrupt(0,ISR,FALLING); // execute ISR() whenever data appears on Serial port
}

void loop(){
 if(triggered){
   // do somthing, can use library Calls, anything, even send data out the Serial port!
   triggered = false; // reset flag
   attachInterrupt(0,ISR,FALLING); // enable interrupt for next serial activity
 }  
}

I guess that with this code the Arduino can enter into sleep mode, right? However if I decided to use this, will it be enough to assign Rx as pin 2??

SoftwareSerial USART(2, 3);

chucktodd:
Why not use Serial.available()?

Again, a continuos verification would consume a loooot more energy, right?

luisda2994:
Yes, that's the idea. I need to extend the life of the battery. And I hope that will help.

I guess that with this code the Arduino can enter into sleep mode, right? However if I decided to use this, will it be enough to assign Rx as pin 2??

SoftwareSerial USART(2, 3);

Nope, the Serial object already defines the USART RX interrupt. When you also Connect Pin 2 to Pin 0 you can use the Hardware Interrupt function of pin 2 for your wakeup signal.
If you enable interrupt on Pin 2 (attachInterrupt(0,ISR,LOW):wink: an then go to sleep. Any activity on The UART (pin0 ) will cause the CPU to wakeup.

The reason to use Pin 2 is because hardware Int.0 can wake the processor from sleep, Activity on pin0 will not.

To effectively use sleep modes you need to read and understand The Atmel datasheet for the processor
Search for Atmel-8271 This is 660page reference manual for the processor.

Chuck.
Again, a continuos verification would consume a loooot more energy, right?
[/quote]

chucktodd:
Nope, the Serial object already defines the USART RX interrupt. When you also Connect Pin 2 to Pin 0 you can use the Hardware Interrupt function of pin 2 for your wakeup signal.
If you enable interrupt on Pin 2 (attachInterrupt(0,ISR,LOW):wink: an then go to sleep. Any activity on The UART (pin0 ) will cause the CPU to wakeup.

Ok, gonna read about that and if anything happens I'll let you know. Thanks for your help

Hey man,

I used the RX to pin2 method and it worked perfectly. Now it only executes codes if I produce an interrupt. Again, thank you.

Now, I need to make it sleeep, BUT I'm moving to Arduino Nano because of size. Gonna try to read the microcontroller datasheet

I'll let you know if anything happens

1 Like