Arduino SPI Communication Tutorial
Learn high-speed SPI protocol for Arduino projects - faster than I2C
What is SPI Communication?
Serial Peripheral Interface (SPI) is a high-speed, full-duplex communication protocol that's faster than I2C and perfect for Arduino projects requiring rapid data transfer. Unlike I2C's 2-wire system, SPI uses 4 wires for enhanced performance:
SPI Pin Configuration:
- MOSI (Master Out, Slave In) - Data from Master to Slave
- MISO (Master In, Slave Out) - Data from Slave to Master
- SCK (Serial Clock) - Clock signal from Master
- SS (Slave Select) - Individual chip select for each device
Why choose SPI over I2C? SPI communication can reach speeds up to 10MHz compared to I2C's 400kHz, making it ideal for high-bandwidth applications like SD cards, TFT displays, and sensor arrays.
Arduino SPI vs I2C: Complete Comparison
Feature | SPI Protocol | I2C Protocol |
---|---|---|
Speed | Up to 10+ MHz | Up to 400 kHz (3.4 MHz max) |
Wiring | 4 wires + 1 per device | 2 wires (SDA, SCL) |
Device Limit | Limited by available pins | 127 devices (address-based) |
Data Direction | Full-duplex (simultaneous) | Half-duplex (one direction) |
Best Use Cases | High-speed sensors, displays, SD cards | Multiple slow devices, EEPROMs |

CanaKit Raspberry Pi 5 PRO

ELEGOO MEGA R3 ATmega2560

ELEGOO 37-in-1 Sensor Kit
SPI Wiring Guide for Arduino
How do you wire SPI devices to Arduino? Here's the standard pin configuration for Arduino Uno and compatible boards:
Standard Arduino SPI Pins
- Pin 13 (SCK) - Serial Clock
- Pin 12 (MISO) - Master In Slave Out
- Pin 11 (MOSI) - Master Out Slave In
- Pin 10 (SS) - Slave Select (or any digital pin)
Multi-Device Wiring
Connect MOSI, MISO, and SCK to all devices. Use separate digital pins for each device's Slave Select (SS). This allows the master to communicate with multiple SPI devices individually.
Arduino SPI Master Code Example
Ready-to-use SPI master code for controlling multiple devices. This example shows how to send data to different SPI slaves:
#include <SPI.h>
// Define Slave Select pins for multiple devices
const int device1_SS = 10;
const int device2_SS = 9;
const int device3_SS = 8;
void setup() {
Serial.begin(9600);
// Initialize SS pins as outputs
pinMode(device1_SS, OUTPUT);
pinMode(device2_SS, OUTPUT);
pinMode(device3_SS, OUTPUT);
// Set all SS pins HIGH (inactive)
digitalWrite(device1_SS, HIGH);
digitalWrite(device2_SS, HIGH);
digitalWrite(device3_SS, HIGH);
// Initialize SPI communication
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV16); // Set SPI speed
}
void loop() {
// Communicate with Device 1
sendToDevice(device1_SS, 0x55); // Send hex value 0x55
delay(100);
// Communicate with Device 2
sendToDevice(device2_SS, 0xAA); // Send hex value 0xAA
delay(100);
// Communicate with Device 3
sendToDevice(device3_SS, 0xFF); // Send hex value 0xFF
delay(100);
}
void sendToDevice(int ssPin, byte data) {
digitalWrite(ssPin, LOW); // Select device
byte response = SPI.transfer(data); // Send data, receive response
digitalWrite(ssPin, HIGH); // Deselect device
Serial.print("Sent: 0x");
Serial.print(data, HEX);
Serial.print(" | Received: 0x");
Serial.println(response, HEX);
}
Code Breakdown
- SPI.begin() - Initializes SPI communication
- SPI.setClockDivider() - Controls communication speed
- SPI.transfer() - Sends data and receives response simultaneously
- digitalWrite(SS, LOW/HIGH) - Selects/deselects specific devices
Arduino SPI Slave Code Example
Complete SPI slave implementation for receiving data from the master Arduino:
#include <SPI.h>
volatile boolean received = false;
volatile byte receivedData;
const int ledPin = 13;
void setup() {
Serial.begin(9600);
pinMode(ledPin, OUTPUT);
// Set MISO as output for slave mode
pinMode(MISO, OUTPUT);
// Enable SPI in slave mode
SPCR |= _BV(SPE);
// Enable SPI interrupt
SPCR |= _BV(SPIE);
}
void loop() {
if (received) {
// Process received data
Serial.print("Received: 0x");
Serial.println(receivedData, HEX);
// Blink LED based on received data
for (int i = 0; i < receivedData; i++) {
digitalWrite(ledPin, HIGH);
delay(100);
digitalWrite(ledPin, LOW);
delay(100);
}
received = false;
}
}
// SPI interrupt routine
ISR (SPI_STC_vect) {
receivedData = SPDR; // Read received data
received = true; // Set flag
SPDR = receivedData; // Send back same data (echo)
}
Popular SPI Devices for Arduino Projects
Expand your Arduino projects with these common SPI-compatible components:
📱 TFT LCD Displays
High-resolution color displays for data visualization and user interfaces. Fast refresh rates perfect for gaming and real-time monitoring.
💾 SD Card Modules
Data logging and storage solutions. Essential for IoT projects requiring persistent data storage and file management.
🌡️ High-Speed Sensors
Temperature, pressure, and accelerometer sensors requiring fast sampling rates for precision measurements.
📡 RF Modules
Wireless communication modules (nRF24L01+) for remote control and IoT connectivity applications.
SPI Communication Troubleshooting Guide
Common SPI issues and solutions to get your Arduino projects working perfectly:
No Data Transmission
- Verify MOSI, MISO, SCK, and SS pin connections
- Check for proper ground connections between devices
- Ensure SS pin goes LOW before communication
- Confirm SPI.begin() is called in setup()
Garbled or Incorrect Data
- Match SPI clock speeds between master and slave
- Check SPI mode settings (CPOL and CPHA)
- Reduce clock speed with SPI.setClockDivider()
- Add delays between transmissions
Multiple Device Conflicts
- Ensure each device has a unique SS pin
- Set unused SS pins to HIGH
- Use proper timing between device switches
- Check for electrical interference on shared lines
Advanced SPI Project Ideas
Take your Arduino SPI skills to the next level with these innovative project concepts:
🎮 Arduino Game Console
Build a retro gaming system using SPI TFT displays, SD card storage for games, and wireless controllers via nRF24L01+ modules.
📊 IoT Data Logger
Create a weather station with multiple SPI sensors, SD card logging, and wireless data transmission for remote monitoring.
🤖 Multi-Sensor Robot
Build an autonomous robot using SPI communication for high-speed sensor fusion, motor control, and real-time navigation.
Frequently Asked Questions
What's the maximum speed for Arduino SPI communication?
Arduino Uno can handle SPI speeds up to 8MHz (using SPI_CLOCK_DIV2), while Arduino Mega can reach 16MHz. For most projects, speeds between 1-4MHz provide the best balance of speed and reliability.
Can I use SPI and I2C simultaneously on Arduino?
Yes! SPI and I2C use different pins and can run simultaneously. SPI uses pins 10-13 while I2C uses A4/A5 (SDA/SCL). This allows you to connect both types of devices in the same project.
How many SPI devices can I connect to one Arduino?
The number is limited by available digital pins for Slave Select (SS). Arduino Uno has 14 digital pins, so theoretically you could connect 10+ SPI devices (reserving pins 10-13 for SPI). Arduino Mega can handle 50+ devices.
Why choose ELEGOO over official Arduino boards?
ELEGOO boards offer identical functionality at 30-50% lower cost. They're fully compatible with Arduino IDE, use the same ATmega chips, and include quality components. Perfect for learning and prototyping without breaking the bank.
What SPI mode should I use for my project?
Most Arduino projects use SPI Mode 0 (CPOL=0, CPHA=0), which is the default. Check your device datasheet - SD cards typically use Mode 0, while some sensors may require different modes. Use SPI.setDataMode() to change modes if needed.
Essential Tools for SPI Projects
Equip yourself with these must-have components for successful Arduino SPI communication projects:

Premium Jumper Wires

USB Serial CH340 Module
SPI Performance Optimization Tips
Maximize your Arduino SPI communication performance with these expert techniques:
🚀 Speed Optimization
- Use SPI Transactions: SPI.beginTransaction() and SPI.endTransaction() for clean, fast communication
- Buffer Data: Send multiple bytes in batches rather than individual transfers
- Optimize Clock Speed: Find the sweet spot between speed and reliability for your specific devices
- Minimize SS Switching: Group operations to the same device to reduce selection overhead
// Optimized SPI transaction example
SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
digitalWrite(SS_PIN, LOW);
// Send multiple bytes efficiently
byte dataBuffer[] = {0x01, 0x02, 0x03, 0x04};
for (int i = 0; i < 4; i++) {
SPI.transfer(dataBuffer[i]);
}
digitalWrite(SS_PIN, HIGH);
SPI.endTransaction();
Building Your First SPI Network
Step-by-step guide to create a multi-device SPI communication system:
Plan Your Network
Identify all SPI devices, assign unique SS pins, and create a wiring diagram. Consider power requirements and signal integrity for longer connections.
Implement Master Controller
Start with the provided master code template. Add device-specific communication functions and error handling for robust operation.
Test Each Device Individually
Verify communication with each SPI device separately before connecting the full network. This simplifies troubleshooting and ensures reliable operation.
Scale and Optimize
Once individual devices work, connect the full network and optimize timing, speed, and power consumption for your specific application.
Why Choose Arduino SPI for Your Next Project?
SPI communication offers compelling advantages for modern Arduino projects:
High-Speed Performance
Up to 25x faster than I2C, perfect for real-time applications and high-bandwidth sensors.
Full-Duplex Communication
Simultaneous send and receive capability enables efficient data exchange and device control.
Precise Device Control
Individual slave select pins provide exact control over which devices communicate when.
Conclusion: Master Arduino SPI Communication
You've learned the fundamentals of Arduino SPI communication - from basic wiring to advanced multi-device networks. SPI's high-speed, full-duplex capabilities make it ideal for demanding applications like displays, sensors, and data logging systems.
🚀 Ready to Build Your SPI Project?
Start with quality components and reliable tutorials. Our recommended ELEGOO boards offer Arduino compatibility at unbeatable prices.
Next Steps: Experiment with different SPI devices, optimize your code for speed, and share your projects with the Arduino community. The combination of SPI's performance and Arduino's simplicity opens endless possibilities for innovation.
💡 Pro Tip: Start with simple one-device projects before building complex networks. Master the basics, then scale up your ambitions. Happy coding! 🔧✨
0 Comments