Arduino UART: Insights, Logs & Arduino Code [Lib & Register Level]

Last updated on November 1st, 2023

UART is the most common protocol used for full-duplex serial communication, it converts parallel bytes from the CPU into serial bits for transmission, and vice versa. UART is the most commonly used Serial Communication technique, It is being used in many applications like Bluetooth Modules, GSM Wireless Communication Systems, etc.

arduino uart
Arduino UART

What is 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.

Arduino UART
Arduino UART

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

UART signal Analysis using Logic analyzer
UART signal Analysis using Logic analyzer

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

Figure 4: Equations for Calculating Baud Rate Register Setting

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.

10 Comments

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

Leave a Reply

Your email address will not be published. Required fields are marked *