Robust Arduino Serial Protocol for string

Last updated on October 3rd, 2023

For Arduino boards Serial communications provide us an easy and flexible way to interact with other Arduino boards and other devices, the most common is UART (Universal Asynchronous receiver-transmitter) uses serial communication.

In Arduino we can transmit any bytes on UART by using one line of code that is “Serial.println(“ ”);” And can receive by using one line of code “Serial.read();”, but we can not get the multiple bytes string by this simple code so we need serial protocol algorithm to do this.

Why do we need an algorithm for Serial Protocol?

We can receive data in the form of bytes one by one using serial.read():, for multiple bytes (e.g. Hello world) we have to develop a proper algorithm to receive all/11 bytes of Hello world. In the figure below, if we use simple Arduino code to receive Hello world we can only get the last byte ‘d’  because Arduino doesn’t read all bytes from UART at once, Arduino will read next lines sequentially after reading byte of UART and then read next of byte of UART at next iteration of a void loop function.

we have to develop an algorithm for the serial protocol for proper communication and receiving the whole string (e.g. Hello world).

Arduino Serial protocol
Figure 1: Arduino Serial protocol

Algorithm for Arduino Serial protocol

For serial protocol first, we create the following variables and define the length for receive buffer(e.g. length_RX_buf  is 50 ), this length is must greater than the length of receive string.

#define length_RX_buf 50

char RX_buf[length_RX_buf];
unsigned int Count_for_RX_BYTE = 0;
unsigned int Total_byte_of_RX = 0;
unsigned char RX = 0;
boolean RX_buf_complete = false;

For initiating serial communication of Arduino write the following line of code in void setup()

Serial.begin(9600);

Now we have to write the code which checks that any data is coming from serial or not by using the following line of code

If(Serial.available())

Then read the data of serial and copy the received first byte into RX then copy byte in RX into RX_buf at index zero, and increase the value of Count_for_RX_BYTE to store next receive byte on index 1, and make RX_buf_complete flag false, because now receiving string is not complete yet.

RX = Serial.read();   
RX_buf[Count_for_RX_BYTE] = RX;                       
Count_for_RX_BYTE++;
RX_buf_complete = false;

Now check the last and second last byte of RX_buf that these bytes are line feed (0x0A) and carriage return (0x0D) respectively or not, after each byte, if it is true then hardcode the ‘\0’ at the end of the string to indicate string is now complete, and make RX_buf_complete flag true.

if(RX_buf[Count_for_RX_BYTE-1] == 0x0A )
   {
     if(RX_buf[Count_for_RX_BYTE-2] == 0x0D )
       {               
          RX_buf[Count_for_RX_BYTE]='\0';               
          RX_buf_complete = true;
          Total_byte_of_RX = Count_for_RX_BYTE;               
          Count_for_RX_BYTE = 0;               
        }
   }

For the next string, we have to clear the RX_buf, so define the following function and call it where you want to clear the RX_buf.

void clear_RX_buf(void)
{
    for(int i = 0;  i < length_RX_buf; i++)
      {  
          RX_buf[i]=' ';              
      }    
      RX_buf[0] = '\0';    
      Total_byte_of_RX = 0;
}

Total code:

#define length_RX_buf 50

char RX_buf[length_RX_buf];
unsigned int Count_for_RX_BYTE = 0;
unsigned int Total_byte_of_RX = 0;
unsigned char RX = 0;
boolean RX_buf_complete = false;

void clear_RX_buf(void);

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

void loop()
  {
            if (Serial.available()) 
                {  
                   RX = Serial.read();   
                   RX_buf[Count_for_RX_BYTE] = RX;                       
                   Count_for_RX_BYTE++;
                   RX_buf_complete = false;
                               
                   if(RX_buf[Count_for_RX_BYTE-1] == 0x0A )
                     {
                       if(RX_buf[Count_for_RX_BYTE-2] == 0x0D )
                         {               
                              RX_buf[Count_for_RX_BYTE]='\0';               
                              RX_buf_complete = true;
                              Total_byte_of_RX = Count_for_RX_BYTE;               
                              Count_for_RX_BYTE = 0;               
                          }
                      }                                 
               }
               
  }



void clear_RX_buf(void)
{
    for(int i = 0;  i < length_RX_buf; i++)
      {  
          RX_buf[i]=' ';              
      }    
      RX_buf[0] = '\0';    
      Total_byte_of_RX = 0;
}

Conclusion

Serial communication is a very easy and flexible way to communicate the device with each other, in Arduino we can receive and transmit data using Serial on the UART port, for receiving the multiple bytes/ array we need to develop an algorithm because UART receives bytes one by one. By algorithm for Arduino serial (UART) protocol, we can easily get the string of any length.

Leave a Reply

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