Introduction

UART stands for Universal Asynchronous Receiver/Transmitter. Unlike I²C and SPI, it isn't a protocol but physical circuitry found inside the microcontroller. It is used for communication between an Arduino board and a computer, or with other devices such as a GPS module or RFID module.

In this guide, learn about serial communication and various serial commands used in the Arduino IDE.

Complete this guide to understand the basics involved in serial communication.
    • There was a time when peripherals such as printers, modems, joystick controllers, and computer mice were accompanied with thick cables and huge connectors. These devices were using what is known as the RS-232 protocol and UART. This was the beginning of serial communication for many people. However, serial communication has been around for a far longer time, even since mainframe computers.

      What is serial communication? It involves the transfer of data as bits sent one at a time on a single wire. You can imagine it as being similar to a telephone call where both users can talk at the same time, and words are sent one at a time. 

      This is in contrast to parallel communication. While serial communication involves bits being sent one at a time on a single wire, parallel communication involves multiple bits sent on multiple wires.

    • Serial: A method of sending data that sends the data one bit at a time.UART: Acronym for Universal Asynchronous Receiver, Transmitter. This is a physical device that is used to send and receive data serially.RS232: A serial protocol that defines how to send and receive serial data. 

    • These days, the the Universal Serial Bus (USB) interface or port has mostly replaced it. However, UART is definitely not a thing of the past! Many electronic projects such as those involving the Arduino utilises UART.

      Unlike I²C and SPI, UART (Universal Asynchronous Receiver/Transmitter) isn't a protocol but physical circuitry found inside the microcontroller. It is used for communication between an Arduino board and a computer, or with other devices such as a GPS module or RFID module.

    • In this guide, we'll run you through the basics on serial UART communication, as well as some serial commands you can use in the Arduino IDE.

    • In many microcontrollers, as the one found on the Arduino Uno R3, the basic structure includes a CPU, ROM, RAM, I/O ports, timing circuitry, interrupts, a universal asynchronous receiver/transmitter, and an analog to digital converter or digital to analog converter.

    • As mentioned, UART is not a protocol, but circuitry within the microprocessor that is responsible for the transmitting and receiving of serial data. That is to say, it is responsible for the sending and receiving of bytes of data to and from the microcontroller.

    • Externally, you will be able to see 'RX' and 'TX' pins on the Arduino board. These pins are the interface of the hardware UART found on the ATmega328 microcontroller.

    • When the computer sends information to the Arduino, this is done through USB. 

      Then, this USB signal is converted into serial form and transmitted to the UART. The received data is then placed in a buffer, which is a memory storage used to temporarily hold data. 

    • Only three wires are needed for serial communication and they are:

      TX: The line for transmitting data
      RX: The line for receiving data
      GND: Common ground

    • As its name suggests, the transmission line is used to send data to the recipient device. Therefore, the sender device's TX line needs to be connected to the recipient device's RX line. 

    • In UART serial communication, both devices can send and receive data at the same time, which means it is capable of full-duplex communication

    • As noted in its name, UART transmits data asynchronously, which means there is no external clock line driving the bits. Without a clock signal used to synchronise the output of bits from the transmitting UART to the receiving UART, just how does it work?

      Instead, UART utilises a start and stop bit, as well as a data packet to be transferred. 

    • The start bit indicates the start of a data word, and is used to synchronise the transmitter and receiver. This is always 0.

      The stop bit indicates when the last data bit has been sent. Modern devices use a 1 stop bit.

      The data packet, usually 5 to 9 bits in length, is the information to be transferred. This information is in the form of binary data bits. In the diagram shown, the symbol '-' is encoded as the decimal number 45, which is 0101101 in binary.

      The parity bit is used for error-detection via a simple error-checking algorithm that is now rarely used. 

    • So when a receiving device detects a start bit, the incoming bits are read. But it needs to be read at a specific frequency that had been initially agreed upon by both devices. This frequency is known as baud rate, which is the measure of the speed of data transfer.

    • Commonly used baud rates when using the Arduino are 9600, 14400, 19200, or even 115200.

  1. void setup() {
      // Start serial communication for Uno R3
      Serial.begin(9600);
    
      //Start serial communication for Arduino Mega at Serial port 3
      //Serial3.begin(9600);
    }
    • Let's start with using serial UART in your sketches. Use the command, Serial.begin to start serial communication.

    • This command accepts one parameter, which is the baud rate. In this sketch, we've set it to be 9600.

    • The Little Bird Uno R3 has one serial port. However, some Arduino boards have more than one serial port! An example is the Arduino Mega, which has three UART devices and they can be used in your sketch as either Serial1, Serial2, or Serial3. In the sketch, we have commented out the code that begins serial communication at Serial3.

    • Once Serial.begin is called, incoming bytes are listened for and automatically stored into a buffer. The Little Bird Uno R3 reserves 64 bytes of buffer in each direction, and this data won't be lost as long as the buffer does not overflow.

    • Buffer overflow happens when the bytes are being received faster than they are being read.

  2. void setup() {
      Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
    }
    
    void loop() {
      // reply only when you receive data:
      if (Serial.available() > 0) {
        // Do something:
      }
    }
    • The next command we will look at is the Serial.available command. When placed in the main loop with an if statement, it will check to see if any data has been received and returns the number of bytes available for reading. Otherwise, if no bytes are available for reading, it returns 0 or 'false'.

    • This is data that is already arrived and stored in the serial receive buffer (which holds 64 bytes).

  3. int inByte = 0; // for incoming serial data
    
    void setup() {
      Serial.begin(9600); // opens serial port, sets data rate to 9600 bps
    }
    
    void loop() {
      // send data only when you receive data:
      if (Serial.available() > 0) {
        // read the incoming byte:
        inByte = Serial.read();
      }
    }
    • If there are more than zero bytes available in the buffer to be read, then the next thing to do is to read the data. This can be done by using the Serial.read command, which reads a byte from the buffer.

    • This command returns the first byte of incoming serial data available. If no data is available then it returns -1.

  4. Serial.readBytes(buffer, length);
    • To read more than one byte of data, the command, readBytes can be used to read multiple bytes of data.

      You must set a specified amount of bytes to be read.

    • This command returns the number of characters placed in the buffer. A 0 means no valid data was found.

    •  It is only after this specified amount of bytes have been read, does the function stop. To avoid needlessly stalling the program, as in the case that it continues to wait for data that never arrives, it is a good idea to use Serial.setTimeout.

    • By default, Serial.setTimeout is set to 1000 milliseconds. Otherwise, set its parameter to the desired duration in milliseconds.

  5.  Serial.readBytesUntil(character, buffer, length);
    • What if you didn't know how many bytes will be received?

      Instead of using Serial.readBytes, you can use the Serial.readBytesUntil command, which has the added argument 'character'. This function reads the data available, and stops when all the data is read, or when there is a time-out, or when a special character is received. 

  6. void setup() {
      // Start serial communication for Uno R3
      Serial.begin(9600);
    
      //Start serial communication for Arduino Mega at Serial port 3
      //Serial3.begin(9600);
    }
    
    void loop() {
      Serial.print("Hello World!");
      Serial.print("17");
      Serial.print("3.14159265359");
      Serial.print(25); // Outputs the ASCII string "25" to the serial port
      Serial.print(2.7345); // Outputs "2.73"
    }
    • Besides receiving data, the Arduino can also be used to send data to another device. This function prints data to the serial monitor as human-readable ASCII text -- even numbers and floats are printed using an ASCII character for each digit. 

  7. void setup() {
      // Start serial communication for Uno R3
      Serial.begin(9600);
    
      //Start serial communication for Arduino Mega at Serial port 3
      //Serial3.begin(9600);
    }
    
    void loop() {
      Serial.println("Hello World!");
      Serial.println("17");
      Serial.println("3.14159265359");
      Serial.println(25); // Outputs the ASCII string "25" to the serial port
      Serial.println(2.7345); // Outputs "2.73"
    }
    • If you uploaded the previous code to the Little Bird Uno R3, and then navigated to Tools > Serial Monitor. What do you see? It won't be very readable as the program loops through the strings again and again, on the same line with no spacing. 

    • To counter this program, use the Serial.println command, which automatically adds a new line and a return at the end of the text.

  8.   Serial.write(0x48);   // H   will write 0100 1000
      Serial.write(0x45);   // E   will write 0100 0101 
      Serial.write(0x4C);   // L   will write 0100 1100
      Serial.write(0x4C);   // L   will write 0100 1100
      Serial.write(0x4F);   // O   will write 0100 1111
    • Sometimes, you may want to write binary data to the serial port, instead of ASCII characters. To do so, use the Serial.write command. 

    • This writes binary data to the serial port, where data is sent as a byte or series of bytes. Upload to the code to the Little Bird Uno R3, and you should see 'HELLO' printed onto the serial monitor.