Zbotic Logo Zbotic Logo
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

  • Shop
  • About Us
  • Contact Us
  • Reseller
  • Blogs
020 69134444
1800 209 0998
[email protected]
Help Desk
Facebook Twitter Instagram Linkedin YouTube
Zbotic Logo Zbotic Logo
0 0

View Wishlist Add all to cart

0 0
0 Shopping Cart
Shopping cart (0)
Subtotal: ₹0.00

View cartCheckout

All departments
  • 3D Print Service
  • 3D Printer
  • Batteries & Chargers
  • Development Boards
  • Drone Parts
  • EBike parts
  • Sensor Modules
  • Electronic Components
  • Electronic Modules
  • IoT and Wireless
  • Mechanical Parts and Workbench Tools
  • Motors & Drivers & Pumps & Actuators
  • DIY and Robot Kits
  • Show more
  • Home
  • Shop
  • Sale
  • 3D Print Service
  • PCB Service
  • B2B
  • Blogs
  • Contact Us
Return to previous page
Home Arduino & Microcontrollers

Arduino SPI Tutorial: Master/Slave Setup & Register Control

Arduino SPI Tutorial: Master/Slave Setup & Register Control

March 11, 2026 /Posted byJayesh Jain / 0

SPI (Serial Peripheral Interface) is the fastest serial communication protocol available on Arduino. When you need to drive a TFT display at 60 fps, stream data from an SD card, or interface with a high-speed ADC, SPI is the protocol of choice. In this tutorial you will learn how SPI works, how to use the Arduino SPI library, how to set up custom clock speeds and modes, and how to control registers directly for maximum performance.

Table of Contents

  • What Is SPI and How Does It Work?
  • SPI Pins on Arduino Boards
  • Using the Arduino SPI Library
  • SPI Clock Polarity and Phase (CPOL/CPHA)
  • Multiple SPI Slave Devices
  • SPI TFT Display Example
  • Direct SPI Register Control
  • Frequently Asked Questions

What Is SPI and How Does It Work?

SPI is a synchronous serial communication protocol developed by Motorola. Unlike I2C which uses addresses, SPI uses dedicated Chip Select (CS) pins to choose which device to communicate with. It is a master/slave protocol — the master (Arduino) controls the clock and initiates all communication.

SPI uses four signal lines:

  • 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 generated by the master
  • CS/SS (Chip Select / Slave Select): Active LOW signal that selects a specific slave

Data transfer is full-duplex — master and slave exchange data simultaneously on MOSI and MISO. For every byte the master sends on MOSI, it simultaneously receives a byte on MISO. This makes SPI inherently faster than I2C for high-throughput applications.

A typical SPI transaction:

  1. Master pulls the slave’s CS pin LOW (selects it)
  2. Master generates clock pulses on SCK
  3. Data bits shift out on MOSI and in on MISO simultaneously, one bit per clock edge
  4. After all bytes are transferred, master pulls CS HIGH (deselects the slave)

Typical SPI speeds on Arduino Uno: up to 8 MHz (half the 16 MHz clock). The Arduino Due can run SPI at 42 MHz for truly high-speed applications. Most sensors operate at 1–10 MHz, while TFT displays can often accept 40–80 MHz.

Recommended: 1.8 Inch SPI 128×160 TFT LCD Display Module with PCB for Arduino — a classic SPI device to learn with. This ST7735-based display uses standard 4-wire SPI and works with the Adafruit ST7735 library right out of the box.

SPI Pins on Arduino Boards

Each Arduino board has dedicated hardware SPI pins. Using these pins (rather than any other pins) is required for hardware SPI — it enables the hardware SPI peripheral for maximum speed. Software SPI (bit-banging) can work on any pins but is much slower.

Board MOSI MISO SCK Default SS
Uno / Nano 11 12 13 10
Mega 2560 51 50 52 53
Leonardo ICSP-4 ICSP-1 ICSP-3 10
Nano 33 IoT 11 12 13 10
Nano RP2040 11 12 13 10

Note for Mega 2560 users: SPI pins are on 50–53 AND also exposed on the ICSP header. If a SPI shield was designed for Uno, it connects via the ICSP header and will also work on the Mega.

The built-in LED is on pin 13 on Uno/Nano, the same pin as SCK. When SPI is active, the LED may flicker. This is normal and does not affect SPI communication.

Recommended: Arduino Mega 2560 R3 Board — with more memory, more I/O, and a dedicated SS pin at 53, the Mega is ideal for SPI projects that simultaneously control multiple peripherals like displays, SD cards, and sensor modules.

Using the Arduino SPI Library

The Arduino IDE includes the SPI library which provides a clean interface to the hardware SPI peripheral. Here is a complete example that transfers data to a SPI device:

Basic SPI Transfer Example

#include <SPI.h>

const int CS_PIN = 10;  // Chip Select pin

void setup() {
  Serial.begin(9600);
  
  // Initialize CS pin as output and deselect device
  pinMode(CS_PIN, OUTPUT);
  digitalWrite(CS_PIN, HIGH);
  
  // Initialize SPI
  SPI.begin();
}

void writeToDevice(uint8_t reg, uint8_t value) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  digitalWrite(CS_PIN, LOW);   // Select device
  
  SPI.transfer(reg);           // Send register address
  SPI.transfer(value);         // Send value
  
  digitalWrite(CS_PIN, HIGH);  // Deselect device
  SPI.endTransaction();
}

uint8_t readFromDevice(uint8_t reg) {
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));
  digitalWrite(CS_PIN, LOW);
  
  SPI.transfer(reg | 0x80);    // Set MSB to indicate read (device-specific)
  uint8_t result = SPI.transfer(0x00);  // Send dummy byte, receive response
  
  digitalWrite(CS_PIN, HIGH);
  SPI.endTransaction();
  
  return result;
}

SPISettings Parameters Explained

SPISettings(speed, bitOrder, dataMode) takes three arguments:

  • speed: Maximum clock frequency in Hz (e.g., 1000000 for 1 MHz, 8000000 for 8 MHz). The SPI library will round down to the nearest achievable speed.
  • bitOrder: MSBFIRST (most significant bit first — standard) or LSBFIRST
  • dataMode: SPI_MODE0, SPI_MODE1, SPI_MODE2, or SPI_MODE3 (see next section)

Always use SPI.beginTransaction() and SPI.endTransaction() to bracket your SPI transfers. This ensures that if multiple libraries or interrupt handlers try to use SPI, they wait their turn without corrupting each other’s data.

SPI Clock Polarity and Phase (CPOL/CPHA)

SPI has four modes defined by two bits: CPOL (Clock Polarity) and CPHA (Clock Phase). These determine the idle state of the clock and which edge data is sampled on.

Mode CPOL CPHA Clock idle Data sampled on
SPI_MODE0 0 0 LOW Rising edge
SPI_MODE1 0 1 LOW Falling edge
SPI_MODE2 1 0 HIGH Falling edge
SPI_MODE3 1 1 HIGH Rising edge

Most common sensors and displays (including the ST7735 TFT) use SPI_MODE0. Always check your component’s datasheet for the correct mode. Using the wrong mode produces garbage data without any error.

Multiple SPI Slave Devices

Unlike I2C, SPI does not use addresses. Instead, each slave device needs its own Chip Select (CS) pin connected to the Arduino. MOSI, MISO, and SCK are shared by all devices.

#include <SPI.h>

const int CS_DISPLAY = 10;
const int CS_SD_CARD = 9;
const int CS_SENSOR  = 8;

void setup() {
  // Initialize all CS pins HIGH (deselected)
  pinMode(CS_DISPLAY, OUTPUT); digitalWrite(CS_DISPLAY, HIGH);
  pinMode(CS_SD_CARD, OUTPUT); digitalWrite(CS_SD_CARD, HIGH);
  pinMode(CS_SENSOR,  OUTPUT); digitalWrite(CS_SENSOR,  HIGH);
  
  SPI.begin();
}

void talkToDisplay() {
  SPI.beginTransaction(SPISettings(8000000, MSBFIRST, SPI_MODE0));
  digitalWrite(CS_DISPLAY, LOW);  // Select only the display
  SPI.transfer(0x01);
  digitalWrite(CS_DISPLAY, HIGH);
  SPI.endTransaction();
}

void talkToSD() {
  SPI.beginTransaction(SPISettings(250000, MSBFIRST, SPI_MODE0));
  digitalWrite(CS_SD_CARD, LOW);  // Select only the SD card
  SPI.transfer(0x40);
  digitalWrite(CS_SD_CARD, HIGH);
  SPI.endTransaction();
}

The critical rule: only one CS pin should be LOW at any time. If two devices are selected simultaneously, their MISO outputs collide and you get corrupted data. Always pull CS HIGH before selecting a different device.

SPI TFT Display Example

The 1.8-inch ST7735 TFT is one of the most popular SPI devices for Arduino. Here is how to set it up:

Wiring (Uno):

  • VCC → 5V
  • GND → GND
  • SCL → Pin 13 (SCK)
  • SDA → Pin 11 (MOSI)
  • RES → Pin 9 (Reset)
  • DC → Pin 8 (Data/Command)
  • CS → Pin 10 (Chip Select)
  • BL → 3.3V or 5V (backlight)
#include <Adafruit_GFX.h>
#include <Adafruit_ST7735.h>
#include <SPI.h>

#define TFT_CS   10
#define TFT_DC    8
#define TFT_RST   9

Adafruit_ST7735 tft = Adafruit_ST7735(TFT_CS, TFT_DC, TFT_RST);

void setup() {
  tft.initR(INITR_BLACKTAB);  // Init ST7735S chip, black tab
  tft.fillScreen(ST77XX_BLACK);
  
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(2);
  tft.setCursor(10, 30);
  tft.println("Hello SPI!");
  
  // Draw a colored rectangle
  tft.fillRect(10, 60, 100, 40, ST77XX_BLUE);
}

void loop() {
  // Update display with sensor data
  tft.fillRect(10, 60, 100, 40, ST77XX_RED);
  delay(500);
  tft.fillRect(10, 60, 100, 40, ST77XX_GREEN);
  delay(500);
}
Recommended: 2.4 Inch Touch Screen TFT Display Shield for Arduino UNO MEGA — a full SPI TFT shield with touch input that plugs directly into the Uno’s headers, no wiring needed. Uses the ILI9341 driver and includes SD card slot — great for learning SPI with multiple devices simultaneously.

Direct SPI Register Control

For the absolute maximum SPI speed on ATmega Arduinos, you can bypass the SPI library and write directly to the hardware registers. This eliminates function call overhead and is useful in time-critical applications:

void spiInit() {
  // Set MOSI, SCK, SS as outputs
  DDRB |= (1 << PB3) | (1 << PB5) | (1 << PB2);
  // Set MISO as input
  DDRB &= ~(1 << PB4);
  
  // Enable SPI, Master mode, clock = fosc/2 (8 MHz)
  // SPIE=0 (no interrupt), SPE=1 (enable), DORD=0 (MSB first)
  // MSTR=1 (master), CPOL=0, CPHA=0 (Mode 0)
  // SPR1=0, SPR0=0 + SPI2X=1 → clock / 2 = 8 MHz
  SPCR = (1 << SPE) | (1 << MSTR);
  SPSR = (1 << SPI2X);  // Double speed
}

uint8_t spiTransfer(uint8_t data) {
  SPDR = data;                    // Start transfer
  while (!(SPSR & (1 << SPIF)));  // Wait for completion
  return SPDR;                    // Return received byte
}

This gives you the maximum 8 MHz SPI clock on a 16 MHz Uno. The SPI library with SPISettings(8000000, ...) achieves the same clock speed but with slightly more overhead due to function calls and transaction management.

The available clock speeds on a 16 MHz Uno using the prescaler bits (SPR1, SPR0, SPI2X):

  • fosc/2 = 8 MHz (SPI2X=1, SPR=00)
  • fosc/4 = 4 MHz (SPI2X=0, SPR=00)
  • fosc/8 = 2 MHz (SPI2X=1, SPR=01)
  • fosc/16 = 1 MHz (SPI2X=0, SPR=01)
  • fosc/64 = 250 kHz (SPI2X=0, SPR=10)
  • fosc/128 = 125 kHz (SPI2X=0, SPR=11)
Recommended: Arduino Nano RP2040 Connect with Header — the RP2040 chip supports SPI at up to 62.5 MHz and has two independent SPI controllers, making it ideal for high-speed SPI applications like fast display updates or SD card logging.

Frequently Asked Questions

What is the maximum SPI speed on Arduino Uno?

The Arduino Uno’s ATmega328P hardware SPI peripheral supports a maximum of fosc/2 = 8 MHz (with the SPI2X double-speed bit set). Requesting any higher speed with SPISettings() will automatically be capped at 8 MHz. For higher SPI speeds, use the Arduino Due (42 MHz) or Nano RP2040 Connect (up to 62.5 MHz).

Can I use SPI without the CS pin?

Only if you have exactly one SPI device. In that case, you can tie the device’s CS pin permanently LOW. However, if there is any chance you will add more devices, use a CS pin. Also note that the Arduino’s hardware SPI requires the SS pin (pin 10 on Uno) to be an output, even if you are using a different pin as CS. If SS is configured as an input and pulled LOW by external hardware, the SPI peripheral switches to slave mode.

Why does my SPI device return 0xFF or garbage data?

Common causes: wrong SPI mode (try all four modes), wrong clock speed (try 1 MHz as a safe starting point), CS pin not pulled LOW during transfer, MOSI/MISO swapped, or the device needs initialization commands before responding. Check the datasheet carefully for the correct command format — many devices expect a specific framing byte or command byte before accepting read requests.

What is the difference between hardware SPI and software SPI?

Hardware SPI uses the Arduino’s built-in SPI peripheral and is limited to fixed pins (MOSI, MISO, SCK). It runs at maximum speed (up to 8 MHz on Uno) with no CPU overhead per bit. Software SPI (bit-banging) manually toggles any GPIO pins using code, which is much slower (typically 100–500 kHz) but allows using any pins. Use hardware SPI whenever possible. Use software SPI only when the hardware SPI pins are occupied by another device or the device requires an unusual configuration.

Can Arduino be both a SPI master and a SPI slave at the same time?

No, not on the same SPI bus. The ATmega328P has one SPI peripheral that can only be in master or slave mode at a time. If you need to act as both (e.g., read data from a sensor as master and send it to a Raspberry Pi as slave), you would need to use software SPI for one role while using hardware SPI for the other, or use a processor with multiple independent SPI controllers like the Raspberry Pi Pico / RP2040.

Start Building High-Speed SPI Projects

SPI is the protocol to reach for when you need speed. Its full-duplex operation and high clock rates make it the best choice for TFT displays, SD card modules, ADCs, DACs, and any peripheral where data rate matters. The SPI library makes it straightforward, while direct register access lets you push every last MHz of performance from your Arduino.

Browse the Arduino boards, SPI displays, and accessories at Zbotic.in — India’s go-to electronics store for makers and engineers. From beginner kits to the powerful Nano RP2040 Connect, we have the right hardware for your SPI project.

Tags: arduino display, arduino master slave, arduino spi tutorial, arduino tft, serial peripheral interface, spi communication, SPI library
Share Post
  • Facebook
  • Linkedin
  • Whatsapp
Raspberry Pi OS Lite vs Deskto...
blog raspberry pi os lite vs desktop which should you use 595005
blog best arduino simulator tools tinkercad vs wokwi vs proteus 595008
Best Arduino Simulator Tools: ...

Related posts

Svg%3E
Read more

Arduino Batch Programming: Flash Multiple Boards Quickly

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Based Radar System with Ultrasonic Sensor

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Automatic Plant Monitor: Sunlight, Moisture, Temperature

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Lie Detector: GSR Sensor Polygraph Project

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading
Svg%3E
Read more

Arduino Metal Detector: Build a Treasure Finder

April 1, 2026 0
Table of Contents Introduction Components and Hardware Setup Wiring Diagram and Connections Complete Code with Explanation Customization and Improvements Troubleshooting... Continue reading

Add comment Cancel reply

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

Facebook Twitter Instagram Pinterest Linkedin Youtube

Get the latest deals and more.

Download on Google Play Download on the App Store

Call us: 020 69134444 / 1800 209 0998

Monday - Saturday 09:30 AM - 06:00 PM
For Technical Supports Email: [email protected]
For Sales / Enquiries Email: [email protected]

  • My Account

    • Cart

    • Wishlist

    • Checkout

    • My Orders

    • Track Order

    • My Account

  • Information

    • FAQs

    • Blogs

    • Career

    • About Us

    • Contact Us

    • Payment Options

  • Policies

    • Privacy Policy

    • Terms & Conditions

    • GST Input Tax Credit

    • Shipping Return Policy

    • E-Waste Collection Points

    • Our Sitemap

© Zbotic.in is registered trademark of Moxie Supply Pvt Ltd – All Rights Reserved
Login
Use Phone Number
Use Email Address
Not a member yet? Register Now
Reset Password
Use Phone Number
Use Email Address
Register
Already a member? Login Now