If you are wiring a high-speed sensor, display, or flash memory chip to an ATmega328P-based board, you need the exact Arduino Nano SPI pins. The primary hardware SPI pins are D11 (MOSI), D12 (MISO), D13 (SCK), and D10 (SS/CS). Alternatively, these exact same hardware lines are broken out on the 2x3 ICSP header near the reset button, which is the preferred routing for custom PCB shields.

SPI (Serial Peripheral Interface) is a synchronous, full-duplex bus that pushes data at megahertz speeds, but it demands strict physical layer discipline. Below is a table-forward breakdown of how SPI compares to other protocols, how to wire the Nano safely, and how to debug the bus when your peripheral refuses to talk.

Bus Mechanics: Protocol Selection Matrix

Before routing traces or plugging in jumper wires, you must verify that SPI is actually the right tool for your peripheral. Unlike I2C, SPI does not use a shared address space, and unlike UART, it requires a dedicated clock line. Use this matrix to decide which protocol fits your distance, speed, and device count constraints.

Feature SPI (Serial Peripheral Interface) I2C (Inter-Integrated Circuit) UART (Universal Asynchronous) RS-485 (Differential UART)
Wires Required 4 (SCK, MOSI, MISO, SS) + 1 per extra device 2 (SDA, SCL) shared across all devices 2 (TX, RX) point-to-point 2 (A, B) differential pair + GND
Typical Speed 1 MHz to 20+ MHz (Hardware dependent) 100 kHz, 400 kHz, or 1 MHz (Fast+) 9600 bps to 1 Mbps (async) Up to 10 Mbps (short distance)
Addressing None (Hardware SS/CS line per device) 7-bit or 10-bit software addressing None (Point-to-point) None (Software protocol dependent)
Max Distance ~30 cm (1 ft) without buffers ~30 cm (1 ft) without buffers ~15 meters (50 ft) at low baud ~1200 meters (4000 ft)
Best Use Case High-throughput local peripherals (TFTs, Flash) Low-speed sensor networks on one PCB GPS modules, simple telemetry Industrial noise, long cable runs

Verdict: Choose SPI when you need raw throughput (e.g., streaming ADC data or driving an ILI9341 display) and all devices share a common ground on the same workbench. Choose I2C if you are out of GPIO pins and only polling slow environmental sensors. Choose RS-485 if your cable run exceeds a meter in a noisy environment.

Physical Layer: Wiring the Nano and Signal Integrity

The Arduino Nano operates at 5V logic. This is the single most common point of failure for modern makers, as 95% of SPI peripherals manufactured today (like the W25Q32 flash chip or nRF24L01 radio) are strictly 3.3V. Feeding 5V from the Nano's D13 (SCK) into a 3.3V peripheral's clock input will eventually fry the silicon.

Pro-Tip: The ICSP Header Advantage
If you are designing a custom shield or wiring a permanent breadboard setup, use the 2x3 ICSP header instead of digital pins 11-13. The ICSP header guarantees you are hitting the hardware SPI bus, and it includes a dedicated 5V and GND pin. Pin 1 is marked by a small triangle on the PCB silkscreen.

The Pull-Up Resistor Question

A frequent question from makers migrating from I2C is: "Do I need pull-up resistors on SPI?"

No, not on the data lines. SPI uses push-pull drivers, meaning the Nano actively drives the MOSI and SCK lines high and low. You do not need the 4.7kΩ pull-ups required for I2C's open-drain architecture.

However, you DO need a pull-up on the Slave Select (SS) line. When the Arduino Nano boots or resets, its GPIO pins momentarily float before the SPI.begin() function initializes them. If your peripheral's SS line floats low during this window, the peripheral will wake up, attempt to drive the MISO line, and collide with any other device on the bus. Always place a 10kΩ pull-up resistor between the peripheral's CS/SS pin and its VCC (3.3V or 5V) to hold it high until the Nano explicitly pulls it low.

Level Shifting for 3.3V Peripherals

If your Nano is 5V and your sensor is 3.3V, you must step down the Nano's MOSI, SCK, and SS lines. A CD4050B non-inverting buffer or a dedicated Adafruit 4-channel I2C-safe bi-directional logic level converter (which works fine for SPI up to ~2 MHz) is mandatory. The peripheral's MISO line (outputting 3.3V) can usually be read directly by the Nano's 5V ATmega328P, as the chip registers anything above 3.0V as a logic HIGH.

Clock Modes and the Minimal Working Exchange

SPI is not a single standard; it is a family of timing agreements defined by Clock Polarity (CPOL) and Clock Phase (CPHA). These combine to form four SPI Modes (0, 1, 2, and 3). If your Nano is using Mode 0, but your DAC expects Mode 1, you will read garbage data. Always check the peripheral's datasheet timing diagram.

Below is a minimal, robust exchange using the native Arduino SPI library. This example reads a dummy register from a peripheral, assuming Mode 0 and a 4 MHz clock.

#include <SPI.h>

// Arduino Nano SPI Pin Definitions
const int PIN_SS = 10;   // Slave Select (Can be any GPIO, but 10 is standard)
// MOSI = 11, MISO = 12, SCK = 13 (Handled internally by SPI.h)

void setup() {
  Serial.begin(115200);
  
  // Initialize SS pin as OUTPUT and set HIGH (deselect peripheral)
  pinMode(PIN_SS, OUTPUT);
  digitalWrite(PIN_SS, HIGH);
  
  // Initialize hardware SPI
  SPI.begin();
  
  // Configure bus mechanics: 4MHz, MSB first, Mode 0
  SPI.beginTransaction(SPISettings(4000000, MSBFIRST, SPI_MODE0));
}

void loop() {
  uint8_t registerAddress = 0x0F; // Example: WHO_AM_I register
  uint8_t readBit = 0x80;         // Many chips require MSB high for reads
  
  // Pull SS LOW to start transaction
  digitalWrite(PIN_SS, LOW);
  
  // Send address with read bit
  SPI.transfer(registerAddress | readBit);
  
  // Clock out the response (send dummy byte 0x00 to generate clocks)
  uint8_t response = SPI.transfer(0x00);
  
  // Pull SS HIGH to end transaction
  digitalWrite(PIN_SS, HIGH);
  
  Serial.print("Register Value: 0x");
  Serial.println(response, HEX);
  
  delay(1000);
}

Wiring Check: Ensure the Nano's GND is tied directly to the peripheral's GND. SPI is single-ended; without a shared ground reference, the voltage thresholds for logic HIGH/LOW will drift, causing intermittent bit-flips.

Debugging the Bus: Sniffing, Failures, and Fixes

When your Serial monitor prints 0xFF or 0x00 endlessly, the bus has failed. Because SPI lacks the built-in ACK/NACK handshake of I2C, the Nano has no idea if the peripheral actually received the data. You must debug at the physical layer.

The Classic Failures

  1. Baud/Clock Mismatch: The ATmega328P hardware SPI divider might be pushing 8 MHz, but your breadboard wiring has too much parasitic capacitance, rounding off the square waves into triangles. Fix: Drop the SPISettings clock to 1 MHz or 500 kHz to verify signal integrity.
  2. SS Clash (The SPI 'Address Clash'): If you have two SPI devices on the same bus and accidentally leave both SS lines LOW, both devices will attempt to drive the MISO line simultaneously. Because SPI uses push-pull outputs, Device A driving HIGH and Device B driving LOW creates a direct short circuit through their silicon, potentially burning out the output driver. Fix: Ensure only one SS pin is LOW at any given microsecond.
  3. Missing Common Ground: As mentioned, floating grounds cause voltage reference mismatches. Fix: Run a dedicated ground wire from the Nano's GND pin to the peripheral's GND pin; do not rely solely on USB shield grounding.

How to Sniff and Debug the SPI Bus

You cannot debug SPI timing with a standard multimeter. You need a Logic Analyzer. A $15 clone of the Saleae Logic (based on the Cypress CY7C68013A chip) running the open-source PulseView / Sigrok software is the industry standard for hobbyist bench debugging.

Sniffing Procedure:

  1. Connect the logic analyzer's GND to the Nano's GND.
  2. Connect channels 0-3 to SCK, MOSI, MISO, and SS respectively.
  3. In PulseView, set the sample rate to at least 4x your SPI clock speed (e.g., if SPI is 4 MHz, sample at 16 MHz or 24 MHz to capture clean edges).
  4. Set the trigger to the falling edge of the SS line. This ensures the analyzer only captures data when the peripheral is actually awake.
  5. Add the SPI protocol decoder in PulseView, map the pins, and set the correct CPOL/CPHA mode.

By decoding the bus, you can visually verify if the Nano is sending the correct hex bytes on MOSI, and more importantly, you can see if the peripheral is actually responding on MISO, or if the line is just floating high. If MOSI looks perfect but MISO is flat, your peripheral is either unpowered, held in reset, or you have the wrong SPI Mode selected in your code.