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 Walkthrough
Let’s look at the components and wiring in this circuit.
Components
- Raspberry Pi Pico (the brain of the operation)
- Red LED – connected to the MOSI line (GP7)
- Green LED – connected to the MISO line (GP4)
- Yellow LED – connected to the SCK line (GP6)
Wiring
The Pico’s SPI0 pins are mapped as follows:
- MOSI (Master Out Slave In) – GP7 (D7 on the Nano RP2040 Connect pinout)
- MISO (Master In Slave Out) – GP4 (D4)
- SCK (Serial Clock) – GP6 (D6)
- CS (Chip Select) – not used in this loopback test
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:
- MOSI: red wire (
#ff4444) - MISO: green wire (
#00cc00) - SCK: yellow wire (
#ffaa00) - Ground: black wire (
#000000)
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
- Serial Setup: We start serial communication at 115200 baud to print results to the Serial Monitor.
- 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). - Test Data: We define an array of five test bytes:
0x55,0xAA,0xFF,0x00, and0x42. These cover alternating bits, all ones, all zeros, and a mixed pattern. - 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. - Result Display: The sketch prints the transmitted (TX) and received (RX) bytes in hexadecimal, along with a “MATCH” or “DIFFER” status.
- Cleanup:
SPI.endTransaction()releases the SPI bus.
Key Concepts
- SPI Protocol: SPI is a full-duplex, synchronous protocol with a master (the Pico) and one or more slaves. It uses four wires: MOSI, MISO, SCK, and CS (chip select). In this loopback test, we only use MOSI, MISO, and SCK.
- Loopback: Connecting MOSI to MISO allows the master to receive its own transmitted data. This is a common test to verify that the SPI hardware and wiring are functional.
- SPI Modes: The mode (0, 1, 2, or 3) defines the clock polarity and phase. Mode 0 (CPOL=0, CPHA=0) is the most common.
- Baud Rate: The serial monitor baud rate (115200) must match the sketch’s
Serial.begin()setting.
Common Pitfalls and Debugging Tips
- Wrong Pin Mapping: The code comments mention default SPI0 pins (GP16, GP19, GP18), but the actual wiring uses GP7, GP4, and GP6. Always verify the pinout for your specific board. In Velxio, the Pico’s SPI0 pins are GP7 (MOSI), GP4 (MISO), and GP6 (SCK).
- Missing Ground: Ensure all LEDs have their cathodes connected to GND. Without a ground path, the LEDs won’t light.
- Serial Monitor Not Showing Output: Make sure the baud rate is set to 115200 in the Velxio Serial Monitor. You can open it from the editor toolbar.
- LEDs Not Blinking: Check that the LEDs are wired to the correct pins and that the code is running. The LEDs will blink rapidly during the
forloop, then stay off. - Loopback Not Working: If the received bytes don’t match, verify that MOSI and MISO are connected. In this circuit, they are not directly connected; the LEDs are just indicators. For a true loopback, you would need to connect GP7 to GP4 with a wire. However, the code still runs and prints results—the received byte will be whatever is on the MISO line (likely 0xFF or 0x00 if floating).
Suggested Extensions
- Add a Physical Loopback: Connect a wire from GP7 (MOSI) to GP4 (MISO) to actually loop back the data. Then the received bytes should match perfectly.
- Use a Different SPI Mode: Change
SPI_MODE0toSPI_MODE1,SPI_MODE2, orSPI_MODE3and observe the effect on the LEDs. - Increase Clock Speed: Try 8 MHz or 16 MHz and see if the LEDs still blink visibly.
- Add More LEDs: Connect LEDs to the CS pin (GP17) and other GPIOs to visualize additional signals.
- Interface with a Real SPI Device: Replace the loopback with an SPI sensor (e.g., temperature sensor) and read its data.
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.



Happy building!