Go back

Pico SPI Loopback: Test Your RP2040's Serial Communication

Introduction

SPI (Serial Peripheral Interface) is a synchronous serial communication protocol widely used to connect microcontrollers to sensors, displays, and other peripherals. In this tutorial, we’ll build a simple SPI loopback test on the Raspberry Pi Pico using the Velxio in-browser simulator. The Pico will send bytes over SPI0 and read them back, while three LEDs visually indicate activity on the MOSI, MISO, and SCK lines. This is a great way to verify that your SPI hardware and wiring are working correctly before moving on to more complex projects.

Circuit diagram of pico-spi-loopback on the Velxio simulator canvas

Circuit Walkthrough

Let’s look at the components and wiring in this circuit.

Components

Wiring

The Pico’s SPI0 pins are mapped as follows:

Each LED’s anode (A) connects to the respective SPI pin, and its cathode (C) connects to GND (GND.1 on the Pico). The wire colors in the simulator are:

This simple setup lets you see SPI activity: the LEDs will blink as data is transmitted.

Code Walkthrough

Here’s the full Arduino sketch for the Pico:

// Raspberry Pi Pico — SPI Loopback Test
// Sends bytes over SPI0 and reads the loopback response
// Default SPI0 pins: MISO=GP16, MOSI=GP19, SCK=GP18, CS=GP17

#include <SPI.h>

void setup() {
  Serial.begin(115200);
  delay(500);
  Serial.println("=== Pico SPI Loopback Test ===");
  Serial.println("SPI0: MISO=GP16, MOSI=GP19, SCK=GP18");
  Serial.println();

  SPI.begin();
  SPI.beginTransaction(SPISettings(1000000, MSBFIRST, SPI_MODE0));

  // Send test bytes
  byte testBytes[] = {0x55, 0xAA, 0xFF, 0x00, 0x42};
  int count = sizeof(testBytes);

  Serial.println("Sending bytes and reading loopback:");
  for (int i = 0; i < count; i++) {
    byte rxByte = SPI.transfer(testBytes[i]);
    Serial.print("  TX: 0x");
    if (testBytes[i] < 16) Serial.print('0');
    Serial.print(testBytes[i], HEX);
    Serial.print("  RX: 0x");
    if (rxByte < 16) Serial.print('0');
    Serial.print(rxByte, HEX);
    Serial.print("  ");
    Serial.println(rxByte == testBytes[i] ? "MATCH" : "DIFFER");
  }

  SPI.endTransaction();
  Serial.println();
  Serial.println("SPI test complete.");
}

void loop() {
  delay(10000);
}

How It Works

  1. Serial Setup: We start serial communication at 115200 baud to print results to the Serial Monitor.
  2. SPI Initialization: SPI.begin() initializes the SPI0 peripheral. SPI.beginTransaction() configures the bus with a clock speed of 1 MHz, MSB-first data order, and SPI mode 0 (CPOL=0, CPHA=0).
  3. Test Data: We define an array of five test bytes: 0x55, 0xAA, 0xFF, 0x00, and 0x42. These cover alternating bits, all ones, all zeros, and a mixed pattern.
  4. Loopback Transfer: For each byte, we call SPI.transfer(). This simultaneously sends a byte and receives the byte currently on the MISO line. Since we have a loopback (MISO connected to MOSI externally or internally), the received byte should match the sent byte.
  5. Result Display: The sketch prints the transmitted (TX) and received (RX) bytes in hexadecimal, along with a “MATCH” or “DIFFER” status.
  6. Cleanup: SPI.endTransaction() releases the SPI bus.

Key Concepts

Common Pitfalls and Debugging Tips

Suggested Extensions

Try It Yourself

Ready to build this project? Open the live example in Velxio and start experimenting:

Open Pico SPI Loopback in Velxio

Use the Velxio editor toolbar to compile and run the code, and open the Serial Monitor to see the results. The canvas toolbar lets you zoom and pan the circuit. If you need to add components, use the component picker.

Velxio editor toolbar with compile and run controls

Velxio canvas toolbar above the simulation viewport

Velxio component picker modal browsing parts by category

Happy building!


Share this post on:
David Montero

Written by

David Montero

Creator of Velxio, the open-source circuit and Arduino simulator.

GitHub velxio.dev

Related posts


Previous Post
Read Analog Sensors on Raspberry Pi Pico with Velxio
Next Post
Pico I2C EEPROM Read/Write: Simulate Non-Volatile Memory in Your Browser