Are you struggling with efficient Arduino UART management between two Arduino boards or Arduino with other devices (like FPGA, DSP etc)? When working on serial communication and ensuring the reliable transmission can be challenge, specially dealing with real time data or debugging complex system design.
In this guide we will learn UART communication on Arduino using both Arduino built-in library and register level code, it provide detailed insights, debugging and efficient code examples. Whether we are working on simple projects or advance project like Bluetooth, GSM or IoT application etc, this article will will teach us with the knowledge to achieve efficient communication.
What is Arduino UART
“UART” stands for Universal Asynchronous receiver-transmitter. It is a block of circuitry responsible for implementing serial communication. Essentially, the UART acts as an intermediary between parallel and serial interfaces.
The hardware for UART can be a circuit integrated into the microcontroller or a dedicated IC, Almost all microcontrollers have dedicated UART hardware built into their architecture. The main reason for integrating the UART hardware into microcontrollers is that it is a serial communication and requires only two wires for communication. For example, the Arduino Uno is based on ATmega328/P and has just a single UART, while the Arduino Mega built on an ATmega2560 has four UARTs.
Start Bit
Start-bit is also known as a synchronization bit that is placed before the actual data.
Data Bits
The data bits include the real data being conveyed from the sender to the receiver. The data frame length could be between 5 & 8. If the parity bit is not used the data frame length could be 9-bit long.
PARITY Bit
Parity describes the evenness or oddness of a number. The parity bit is a way for the receiving UART to tell if any data has changed during transmission. If the parity bit is a 0 (even parity), the 1 bits in the data frame should total an even number. If the parity bit is a 1 (odd parity), the 1 bits in the data frame should total an odd number. When the parity bit matches the data, the UART knows that the transmission was free of errors.
Stop Bit
The Stop Bit is placed at the end of the data packet. Usually, this bit is 2-bits lengthy but frequently on bit only utilized. In order to stop the broadcast.
UART Interfacing
The following figure shows the UART interface of 2 microcontrollers. The UART communication can be done using three signals Tx, Rx, and GND.
Arduino UART with Arduino Library
Now we start implementing UART in Arduino Uno with Arduino Library, In this Library first, we initialize the UART by following a line of code in the Arduino void setup() function, because it only needs to initialize once
Serial.begin(9600);
The above line of code means initializing UART with a baud rate of 9600. Now we will code in the void loop() function to run repeatedly
if(Serial.available())
{
RX_data = Serial.read();
}
The above code snippet is used to read the UART/ Serial port, we use the IF condition because when any data is available on the UART/Serial port then read the port otherwise ignore it to save resources.
if(RX_data == '1')
{
Serial.println("ucbeginner");
}
else if(RX_data == '2')
{
Serial.println("Hello world");
}
For Serial communication, we need 2 Arduino Uno boards, but with only 1 board we can perform this task, use Arduino Serial Monitor and click on tool > Serial Monitor, Serial Monitor acts just like another Device that is connected to the Arduino Uno board on the UART/serial interface.
In the above code snippet when Arduino Uno receives “1” from the Serial monitor it will transmit the text “ucbeginner“ to the serial monitor and we can see this text on Serial Monitor when it receives 2 then it will transmit “ Hello world ”.
Arduino UART Code with Arduino library
int RX_data=0;
void setup() {
Serial.begin(9600);
}
void loop() {
if(Serial.available())
{
RX_data = Serial.read();
}
if(RX_data == '1')
{
Serial.println("ucbeginner");
}
else if(RX_data == '2')
{
Serial.println("Hello world");
}
delay(1000);
}
Output
UART signal analysis using Logic analyzer
Arduino Code
void setup() {
Serial.begin(9600);
}
void loop() {
Serial.println("ucbeginner");
}
What shows up on the UART logic analyzer screen
To see on your PC/Laptop please download the Logic analyzer data (.kvdat) file.
Arduino UART without Arduino Library/Register level code
We have performed the task “Arduino UART with Arduino library” but learning is not sufficient, For deep learning we will do this task using Registers of Atmega328/P, bypassing the Arduino Uno board, we have to study the datasheet of Atmega328/P.
First, we set the baud rate using the formula (See Page no. 146 of Datasheet).
The baud rate is defined to be the transfer rate in bits per second (bps)
BAUD Baud rate (in bits per second, bps)
fOSC System oscillator clock frequency
UBRRn Contents of the UBRRnH and UBRRnL registers, (0-4095)
#define FOSC 16000000UL// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
Make a function named “USART_Init” and paste the following code in it (See Page no. 149 of Datasheet).
void USART_Init(unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8);
UBRR0L = (unsigned char)ubrr;
Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
}
Call this function in void setup() with parameter “MYUBRR”
USART_Init(MYUBRR);
This function works just like “Serial.begin(9600);”
Make a function named “USART_Transmit” and paste the following code in it (See Page no. 150 of Datasheet).
void USART_Transmit(unsigned char data)
{
/* Wait for empty transmit buffer */
while (!(UCSRnA & (1<<UDREn)))
;
/* Put data into buffer, sends the data */
UDRn = data;
}
Call this function to transmit data on UART/ serial of Atmega328/P, It can only transmit only 1 byte. For transmitting “ucbeginner” write the following code.
USART_Transmit('u');
USART_Transmit('c');
USART_Transmit('b');
USART_Transmit('e');
USART_Transmit('g');
USART_Transmit('i');
USART_Transmit('n');
USART_Transmit('n');
USART_Transmit('e');
USART_Transmit('r');
USART_Transmit('\n');
This work is just like serial.println(“ucbeginner”);
Make a function named “USART_Receive” and paste the following code in it (See Page no. 152 of Datasheet).
unsigned char USART_Receive(void)
{
/* Wait for data to be received */
while (!(UCSRnA & (1<<RXCn)))
;
/* Get and return received data from buffer */
return UDRn;
}
Write the following code then Atmega328/P can receive data on UART/serial.
if(UCSR0A & (1<<RXC0)) //it is eqavilant to if(Serial.available)
{x=USART_Receive();}
The line if(UCSR0A & (1<<RXC0)) it is equivalent to if(Serial.available)
This register-level code works 100% the same as the above portion (Arduino UART with Arduino Library).
Code For Arduino UART using Registers Atmega328/P
#define FOSC 16000000UL// Clock Speed
#define BAUD 9600
#define MYUBRR FOSC/16/BAUD-1
void USART_Init(unsigned int ubrr);
void USART_Transmit(unsigned char data);
unsigned char USART_Receive(void);
void setup() {
USART_Init(MYUBRR);
}
void loop() {
unsigned char x;
if(UCSR0A & (1<<RXC0)) //it is eqavilant to if(Serial.available)
{x=USART_Receive();}
if(x == '1')
{
USART_Transmit('u');
USART_Transmit('c');
USART_Transmit('b');
USART_Transmit('e');
USART_Transmit('g');
USART_Transmit('i');
USART_Transmit('n');
USART_Transmit('n');
USART_Transmit('e');
USART_Transmit('r');
USART_Transmit('\n');
}
else if(x == '2')
{
USART_Transmit('H');
USART_Transmit('e');
USART_Transmit('l');
USART_Transmit('l');
USART_Transmit('o');
USART_Transmit(' ');
USART_Transmit('w');
USART_Transmit('o');
USART_Transmit('r');
USART_Transmit('l');
USART_Transmit('d');
USART_Transmit('\n');
}
}
void USART_Init(unsigned int ubrr)
{
/*Set baud rate */
UBRR0H = (unsigned char)(ubrr>>8); // 0000 0000
UBRR0L = (unsigned char)ubrr; // 0110 1000
//Enable receiver and transmitter */
UCSR0B = (1<<RXEN0)|(1<<TXEN0);
/* Set frame format: 8data, 2stop bit */
UCSR0C = (1<<USBS0)|(3<<UCSZ00);
//UCSR0C =0x00;
}
unsigned char USART_Receive(void)
{
/* Wait for data to be received */
while (!(UCSR0A & (1<<RXC0)));
/* Get and return received data from buffer */
return UDR0;
}
void USART_Transmit(unsigned char data)
{
/* Wait for empty transmit buffer */
while (!(UCSR0A & (1<<UDRE0)));
/* Put data into buffer, sends the data */
UDR0 = data;
}
Output
The output is the same as above ” Figure 3: Output of Arduino UART using Arduino Library“
Conclusion
UART is circuitry that is used to implement serial communication. Arduino Uno has only 1 UART port, we can use this port for serial communication in two ways one is using Arduino serial library and the other is we can use Registers of atmega328/P, for better learning use this 2nd method, then you can implement serial communication using UART port of any other microcontroller.
Nice program, I want to learn more
Thanks, Keep visiting for further posts
I am a beginner.
Then keep visiting this blog for further learning.
Am working on ATMEGA328
good job
nice ideas
Thanks.
I coulԀ not refrain from commenting. Very weⅼl written!
Thanks.
What a brilliant read buddy. Thank you But I am experiencing issue with your rss feed. Unable to subscribe. So anybody experiencing same RSS problem? Anybody who can assist kindly reply. Thanks!