SPI Communication between two Arduino Uno

 What Is SPI Communication

SPI (Serial Peripheral Interface) communication is a synchronous serial communication protocol used primarily for short-distance communication between microcontrollers and peripheral devices, such as sensors, displays, memory devices, and other embedded systems. It was developed by Motorola in the 1980s and is commonly used in embedded systems due to its high speed and simple interface.

Key Components of SPI:

  1. Master and Slave: In SPI communication, there is always one master device that controls the communication and one or more slave devices. The master initiates and controls data transfer, while the slave responds to the master's requests.

  2. Four Main Wires:

    • MISO (Master In Slave Out): Used to send data from the slave to the master.
    • MOSI (Master Out Slave In): Used to send data from the master to the slave.
    • SCLK (Serial Clock): A clock signal generated by the master to synchronize data transfer.
    • SS/CS (Slave Select or Chip Select): A signal from the master to select a particular slave device for communication. Multiple slave devices can be connected, and the master can use the SS/CS line to select which one to communicate with.

How SPI Works:

  • Data is shifted out from the master to the slave through the MOSI line and simultaneously shifted in from the slave to the master through the MISO line.
  • The clock signal (SCLK) synchronizes this data transfer.
  • When the master wants to communicate with a particular slave, it pulls the SS/CS line for that slave low (active low) to select it.

Advantages:

  • Speed: SPI is faster than protocols like I²C due to its simple nature and direct communication.
  • Full-Duplex Communication: Data can be sent and received simultaneously.
  • Flexibility: It supports multiple slaves.

Disadvantages:

  • Requires more wires: SPI needs more lines compared to other protocols, such as I²C, which can be a disadvantage in pin-limited microcontrollers.
  • No Acknowledgment Mechanism: Unlike I²C, SPI doesn’t have a built-in acknowledgment mechanism, making error handling more challenging.

SPI is commonly used in devices like SD cards, EEPROMs, LCD displays, and other embedded devices that require fast communication.

Example: SPI Communication between two Arduino Uno.



Source Code:

Master

#define SCK 5 // Shift Clock is PB5 
#define MISO 4 // Master In Slave Out is PB4
#define MOSI 3 // Master Out Slave In is PB3
#define SS 2 // Slave Selectis PB2
int buttonvalue;
int x;
#define led 7
#define ipbutton 2

void SPI_Begin(){
  // Set MOSI, SCK and SS as Output Pins
  DDRB = (1<<MOSI) | (1<<SCK) | (1<<SS);
  DDRB &= ~(1<<MISO); // Set MISO as an Input Pin
  // Enable SPI, Master mode, Shift Clock = CLK /16
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);
  PORTB &= ~(1<<SS); // Enable Slave Select Pin
}
byte SPI_Transfer (byte data){
  SPDR = data;
  // Start transmission
  // Wait for transmission to complete
  while (!(SPSR & (1<<SPIF)));
  return SPDR; // return the received data
}
void setup(){
  pinMode(led,OUTPUT);
  pinMode(ipbutton,INPUT);
  Serial.begin(9600);
  SPI_Begin();
  Serial.println ("I am SPI Master");
}

void loop(){
  int R, S;
  delay(1000);
  buttonvalue = digitalRead(ipbutton);   //Reads the status of the pin 2

  if(buttonvalue == HIGH)                //Logic for Setting x value (To be sent to slave) depending upon input from pin 2
  {
   x = 1;
  }
  else
  {
    x = 0;
  }
  S=x;
  R = SPI_Transfer (S);

  Serial.print ("I Sent ");
  Serial.print (S,DEC);
  
  Serial.print (", I Received ");
  Serial.println (R,DEC);

  if(R == 1)                   //Logic for setting the LED output depending upon value received from slave
  {
    digitalWrite(led,HIGH);              //Sets pin 7 HIGH
    Serial.println("Master LED ON");
  }
  else
  {
   digitalWrite(led,LOW);               //Sets pin 7 LOW
   Serial.println("Master LED OFF");
  }
  //delay(1000);
}


Salave:

#define SCK 5 // Shift Clock is PB5 
#define MISO 4 // Master In Slave Out is PB4
#define MOSI 3 // Master Out Slave In is PB3
#define SS 2 // Slave Selectis PB2
int buttonvalue;
int x;
#define led 7
#define ipbutton 2

void SPI_Begin_Slave(){
  // Set MOSI, SCK and SS as Output Pins
  DDRB &= ~(1<<MOSI) & ~(1<<SCK) & ~(1<<SS);
  DDRB |= (1<<MISO); // Set MISO as an output Pin
  // Enable SPI, Master mode, Shift Clock = CLK /16
  SPCR = (1<<SPE);

}
byte SPI_Transfer (byte data){
  SPDR = data;
  // Start transmission
  // Wait for transmission to complete
  while (!(SPSR & (1<<SPIF)));
  return SPDR; // return the received data
}
void setup(){
  pinMode(led,OUTPUT);
  pinMode(ipbutton,INPUT);
  Serial.begin(9600);
  SPI_Begin_Slave();
  Serial.println ("I am SPI Slave");
}

void loop(){
  int R, S;
  delay(1000);
  buttonvalue = digitalRead(ipbutton);   //Reads the status of the pin 2

  if(buttonvalue == HIGH)                //Logic for Setting x value (To be sent to slave) depending upon input from pin 2
  {
   x = 1;
  }
  else
  {
    x = 0;
  }
  S=x;
  R = SPI_Transfer (S);
  Serial.print ("I Sent ");
  Serial.print (S,DEC);
  
  Serial.print (", I Received ");
  Serial.println (R,DEC);

  if(R == 1)                   //Logic for setting the LED output depending upon value received from slave
  {
    digitalWrite(led,HIGH);              //Sets pin 7 HIGH
    Serial.println("Slave LED ON");
  }
  else
  {
   digitalWrite(led,LOW);               //Sets pin 7 LOW
   Serial.println("Slave LED OFF");
  }

}


SPI Communication between two Arduino Uno

 What Is SPI Communication SPI (Serial Peripheral Interface) communication is a synchronous serial communication protocol used primarily for...