Communicating Between Multiple Arduino UNO Boards Using SPI

Communicating Between Multiple Arduino UNO Boards Using SPI

When working with multiple Arduino UNO boards, it is often necessary to exchange information simultaneously or at the same time. One effective method to achieve this is by utilizing the Serial Peripheral Interface (SPI). In this comprehensive guide, we will explore how to set up a master-slave configuration where a single Arduino UNO acts as the master, controlling communication with three additional slave boards.

Components Needed

4 Arduino UNO boards Connecting wires (Optional) Breadboard for easier connections

SPI Pin Configuration

For Arduino UNO, the relevant SPI pins are:

MOSI (Master Out Slave In): Pin 11 MISO (Master In Slave Out): Pin 12 SCK (Serial Clock): Pin 13 SS (Slave Select): Pin 10 for the master (each slave will have its own SS pin)

Wiring

Here is the wiring setup:

Connect all Arduinos' MOSI pins (Pin 11) together Connect all Arduinos' MISO pins (Pin 12) together Connect all Arduinos' SCK pins (Pin 13) together Connect the master's SS pin (Pin 10) to each slave's SS pin: Slave 1 (Pin 10), Slave 2 (Pin 9), Slave 3 (Pin 8) Ensure each slave has its own SS pin to enable/disable it during communication Connect all Arduinos’ GND pins together

Code Example

Master Code

#include SPI.h
const int slaveSelectPin1  10; // SS pin for Slave 1
const int slaveSelectPin2  9;  // SS pin for Slave 2
const int slaveSelectPin3  8;  // SS pin for Slave 3
void setup {
  pinMode(slaveSelectPin1, OUTPUT);
  pinMode(slaveSelectPin2, OUTPUT);
  pinMode(slaveSelectPin3, OUTPUT);
  digitalWrite(slaveSelectPin1, HIGH);
  digitalWrite(slaveSelectPin2, HIGH);
  digitalWrite(slaveSelectPin3, HIGH);
}
void loop {
  // Example data to send
  byte dataToSend  42;
  // Communicate with Slave 1
  digitalWrite(slaveSelectPin1, LOW);
  (dataToSend);
  digitalWrite(slaveSelectPin1, HIGH);
  // Communicate with Slave 2
  digitalWrite(slaveSelectPin2, LOW);
  (dataToSend);
  digitalWrite(slaveSelectPin2, HIGH);
  // Communicate with Slave 3
  digitalWrite(slaveSelectPin3, LOW);
  (dataToSend);
  digitalWrite(slaveSelectPin3, HIGH);
  delay(1000); // Adjust as needed
}

Slave Code for all slaves

#include SPI.h
volatile byte receivedData;
void setup {
  pinMode(MISO, OUTPUT); // Set MISO as OUTPUT
  (SPI_CLOCK_DIV8); // Set clock speed
  attachInterrupt(digitalPinToInterrupt(2), dataReceived, RISING);
}
void loop {
  // Main logic can go here
}
ISR(SPI_STC_vect) {
  receivedData  SPDR; // Read received data
  // Process received data as needed
}

Explanation

The master initializes the SPI bus and sets the slave select pins as outputs. In the loop, it sends data to each slave in sequence by pulling the corresponding SS pin low, sending the data, and then setting the SS pin high.

Each slave listens for incoming data on the SPI bus. The ISR(SPI_STC_vect) function is an interrupt service routine that gets triggered when data is received. The received data can be processed as needed.

Notes

Ensure that the slaves are ready to receive data and that their SS pins are correctly managed. The SPI clock speed can be adjusted based on your requirements and the distance between the devices. For more complex interactions, consider implementing a protocol to manage the data being sent and received.

This setup allows for simultaneous communication between the master and multiple slaves using SPI. Adjust the code and wiring as necessary for your specific application!