Basic functions related to Serial Communication in Arduino

Let’s see some basic functions related to serial communication that are frequently used in Arduino IDE.

Arduino UART Functions

a)  Serial.begin(baud_rate)

  • baud_rate : The baud rate that will be used for serial communication. Can be 4800, 9600, 14400, 19200, etc.
  • This function is used to define the baud rate that will be used for serial communication. For communicating with specific devices, the device baud rate needs to be used.

e.g.

Serial.begin(9600); //defines 9600 baud rate for communication.

 

b)  Serial.available()

  • This function is used to get the number of bytes available for reading from the serial port. It gives the number of bytes of data that has arrived and is stored in the serial receive buffer.

e.g.

if(Serial.available())  //If data available at serial port, take action.

 

c)  Serial.print(value)

  • value : character, string, number to be printed.
  • This function is used to print data to a serial port in a form that is human readable (character, strings, numbers).

e.g.

Serial.print(“Hi 1234”);  //Prints Hi 1234 on the serial monitor.

 

d)  Serial.println(value)

  • value : character, string, number to be printed.
  • This function is used to print data to a serial port in a form that is human readable (character, strings, numbers) followed by a carriage return (\r) and a new line character (\n).

 

e)  Serial.read()

  • This function returns a character that was received on the Rx pin of Arduino.

e.g.

char read_byte;   
read_byte = Serial.read();  //Byte of data read is stored in read_byte.

 

f)  Serial.write(value), Serial.write(string), Serial.write(buff, length)

  • value : value to be sent as a single byte.
  • string : string to be sent as a series of bytes.
  • buff : array of data to be sent as bytes.
  • length :  number of bytes to be sent.
  • This function writes data in binary form to the serial port.  Data is sent in form of bytes or series of bytes.

e.g.

Serial.write(100);
Serial.write(“Hello”);

 

Arduino UART Serial Communication Code

Print data received through serial communication on to the serial monitor of Arduino

/* Print data received through serial communication on to the serial monitor of Arduino */

/* Setup is run once at the start (Power-On or Reset) of sketch */
void setup()
{
  Serial.begin(9600); /* opens serial port, sets data rate to 9600 bps */
}

/* Loop runs over and over after the startup function */
void loop()
{
  char data = 0;
  
  if(Serial.available()>0) /* If data available at serial port, enter if loop */
  {
    data = Serial.read(); /* Read data present at serial port */
    Serial.println("Data Received is : "); /* Print string with \r\n */
    Serial.write(data); /* Print data received */
  }  
}

 

Arduino SPI Functions

a)  SPISettings(speedMax, dataOrder, dataMode)

  • speedMax : Maximum speed of communication.
  • dataOrder : MSBFIRST or LSBFIRST.
  • dataMode : SPI_MODE0, SPI_MODE1, SPI_MODE2 or SPI_MODE3.
  • This function is used to configure the SPI port for your SPI device.

e.g.

SPISettings(10000000, MSBFIRST, SPI_MODE0);   /*Configures SPI port for 10MHz maximum speed in SPI mode0 with MSB first data format.*/

 

b)  SPI.beginTransaction(settings)

  • settings : The settings for SPI communication. Define an object of class SPISettings and use it as this parameter.
  • Initializes SPI bus with the defined SPISettings.

e.g.

SPI.beginTransaction(SPISettings(10000000, MSBFIRST, SPI_MODE0);

OR

SPISettings newSettings(10000000, MSBFIRST, SPI_MODE0);
SPI.beginTransaction(newSettings);

 

c)  SPI.endTransaction()

  • This function is used to stop using the SPI bus.

 

d)  SPI.begin()

  • This function initializes the SPI bus by setting SCK, MOSI, and SS to outputs, pulling SCK and MOSI low and SS high.

 

e)  SPI.end()

  • This function disables the SPI bus without changing the pin modes.

 

f)  SPI.transfer(value)

  • value : The byte to be sent out over the bus.
  • SPI transfer is based on a simultaneous send and receive.
  • As it is a simultaneous send and receive, whenever we send a byte of data, we receive a byte of data as well.

e.g.

char received_val;
received_val = SPI.transfer(‘A’);

 

Arduino SPI Configuration as a master Code

Configure SPI settings for Arduino as a master device communication and transfer data to the slave device

/* Configure device as SPI master and send character H to the slave device at an interval of 1 second */
/* Pin 4 of Arduino is used as chip select pin for the slave device */


#include <SPI.h>
const int slavePin = 4; /* Pin used as chip select pin for the Slave device */

/* Setup is run once at the start (Power-On or Reset) of sketch */
void setup()
{
  pinMode(slavePin, OUTPUT); /* Configure slavePin as an output pin */
  SPI.begin(); /* Initialize SPI */
}

/* Loop runs over and over after the startup function */
void loop()
{
  SPI.beginTransaction(SPISettings (4000000, MSBFIRST, SPI_MODE0)); /* Configure SPI port for 4MHz maximum speed in SPI mode0 with MSB first data format */
  digitalWrite(slavePin, LOW); /* Chip Select pin low to initialize communication with slave */
  SPI.transfer('H'); /* Transfer data */
  digitalWrite(slavePin, HIGH); /* Chip Select pin high to end communication with slave */
  SPI.endTransaction();
  delay(1000);
}

Note : SPI settings are chosen based on settings of slave device. The slave we are using is configured for 4MHz, MSBFIRST and SPIMODE0.

 

Arduino SPI Configuration as a slave Code

Configure SPI settings for Arduino as a slave device communication and transfer data to the slave device

/* Configure device as SPI slave which receives data from SPI master and prints it on serial monitor */

/* Setup is run once at the start (Power-On or Reset) of sketch */
void setup()
{
  SPI_Init(); /* Configure device as SPI slave */
  Serial.begin(9600); /* opens serial port, sets data rate to 9600 bps */
}

/* Loop runs over and over after the startup function */
void loop()
{
  char data;
  data = SPI_Receive();
  Serial.print("Received : ");
  Serial.println(data);
}

void SPI_Init()                  /* SPI Initialize function */
{
  DDRB &= ~((1<<MOSI)|(1<<SCK)|(1<<SS));    /* Make MOSI, SCK, SS pin direction as input pins */
  DDRB |= (1<<MISO);              /* Make MISO pin as output pin */
  SPCR = (1<<SPE);              /* Enable SPI in slave mode */
}

char SPI_Transmit(char data)          /* SPI transmit data function */
{
  SPDR = data;                /* Write data to SPI data register */
  while(!(SPSR & (1<<SPIF)));         /* Wait till transmission complete */
  return(SPDR);               /* return received data */
}

char SPI_Receive()                /* SPI Receive data function */
{
  while(!(SPSR & (1<<SPIF)));         /* Wait till reception complete */
  return(SPDR);               /* return received data */
}

 

Note : Arduino SPI library is only for master. There is no provision for SPI slave in this library. Hence we have used our own functions for SPI slave settings and communication.

Arduino UNO uses ATmega328P. Refer the datasheet of ATmega328P for details of how to configure SPI slave device.

You can refer SPI communication for ATmega16/32 which is similar to SPI communication in ATmega328P. It will help you understand the functions used in the above code for the slave device. 

 

Arduino I2C Functions

a)  Wire.begin(address)

  • address :  7-bit slave address of the device. If not specified, the device joins the bus as a master.
  • This function is used to initiate the wire library and join the bus as a master or slave.

 

b)  Wire.beginTransmission(address)

  • address : 7-bit address of the device to transmit to.
  • This function is used to begin transmission to the I2C slave device with the given address. After this, queue bytes for transmission using the Wire.write() function and transmit them by calling the Wire.endTransmission() function.

e.g.

Wire.beginTransmission(0x23); //Begin transmission to I2C device with address 0x23.

 

c)  Wire.endTransmission(stop)

  • stop : Boolean data type. True will send a stop message after the request, thus releasing the bus. False will continually send a restart after the request, thus keeping the connection active.
  • This function ends transmission to slave device started using Wire.beginTransmission() function and transmits the bytes that were queued by Wire.write() function.

 

d)  Wire.write(value), Wire.write(string), Wire.write(data, length)

  • value : value to be sent as a single byte.
  • string : string to be sent as a series of bytes.
  • data : array of data to be sent as bytes.
  • length :  number of bytes to be sent.
  • This function writes data from the slave device in response to a request from the master, or queues bytes for transmission from master to a slave device in between calls to Wire.beginTransmission() and Wire.endTransmission().

 

e)  Wire.available()

  • This function returns the numbers of bytes available to be read with the Wire.read() function.

 

f)  Wire.read()

  • This function reads a byte that was transmitted from a slave device to a master device after a Wire.requestFrom() function, or read a byte that was transmitted from a master device to a slave device

 

g)  Wire.requestFrom(address, quantity, stop)

  • address : 7-bit address of device to request bytes from.
  • quantity : number of bytes to be requested.
  • stop : Boolean data type. True will send a stop message after the request, thus releasing the bus. False will continually send a restart after the request, thus keeping the connection active.
  • This function is used by the master to request bytes from a slave device.

 

Arduino I2C Communication Code

Request data using I2C communication from slave device with address 45, print the received data on serial monitor of Arduino and then send data to another slave with address 70

/* Request data using I2C communication from slave device with address 45, print the received data and then send data to another slave with address 70 */

#include <Wire.h>

/* Setup is run once at the start (Power-On or Reset) of sketch */
void setup()
{
  Wire.begin(); /* Join I2C bus as master */
  Serial.begin(9600); /* opens serial port, sets data rate to 9600 bps */
}

/* Loop runs over and over after the startup function */
void loop()
{
  char rx_data;
  Wire.requestFrom(45, 8); /* Request 8 bytes of data from slave with address 45 */
  while(Wire.available()) /* While data is available from the slave, enter while loop */
  {
      rx_data = Wire.read(); /* Read byte of data */
      Serial.println(rx_data); /* Print the received data on serial terminal */
  }
  delay(500); /* Wait for 500 milliseconds */
  
  Wire.beginTransmission(70); /* Begin transmission to device with address 70 */
  Wire.write(0x30); /* Data to be transmitted */
  Wire.write(0x50);
  Wire.endTransmission(); /* End transmission */
}

 


Components Used

Arduino UNO
Arduino UNO
1
Arduino Nano
Arduino Nano
1
Ad