This sketch is your first complete SPI example on the Arduino UNO. The master iterates over a 32-character string and transmits each byte one at a time over MOSI, simultaneously capturing whatever the slave returns on MISO into aDocumentation Index
Fetch the complete documentation index at: https://mintlify.com/manish04-mu/TheEmbeddedInsights/llms.txt
Use this file to discover all available pages before exploring further.
receivedValue buffer. If no slave is connected, every received byte will read back as 0x00 — but the SPI waveform on SCK, CS, and MOSI will be fully correct and ready to inspect on a logic analyzer.
The Sketch
SPI_Echo_Hello.ino
How It Works
Initialize
Serial.begin(9600) opens the Serial Monitor at 9600 baud so received bytes can be printed. pinMode(CS, OUTPUT) configures pin 10 as a digital output, and digitalWrite(CS, HIGH) pulls Chip Select high immediately — this deselects any slave on the bus before SPI is configured. Finally, SPI.begin() initializes the hardware SPI peripheral and sets SCK (pin 13), MOSI (pin 11), and SS (pin 10) as outputs.Begin Transaction
SPISettings(100000, MSBFIRST, SPI_MODE2) configures three things at once:- 100000 — clock speed of 100 kHz, slow enough to observe cleanly on most logic analyzers
- MSBFIRST — bit 7 of each byte is sent first on MOSI
- SPI_MODE2 — CPOL=1, CPHA=0: the clock idles HIGH, and data is sampled on the falling (leading) edge
SPI.beginTransaction() applies these settings atomically, preventing other SPI devices or interrupt handlers from interfering mid-transfer.Select the Slave
digitalWrite(CS, LOW) asserts Chip Select, pulling the line low to signal the target slave that a transfer is about to begin. CS must go low after SPI.beginTransaction() is called to ensure the correct clock polarity is in place before the slave latches CS.Transfer Loop
The
for loop iterates over every character in sentValue. On each iteration, SPI.transfer(sentValue[x]) performs a full-duplex exchange: it clocks out one byte from sentValue[x] on MOSI while simultaneously clocking in one byte from MISO, returning the received value. That received byte is stored directly into receivedValue[x]. The delay(1) between each byte gives the slave 1 ms to process the received byte and prepare its MISO response before the next transfer begins.Deselect the Slave
digitalWrite(CS, HIGH) releases the slave by pulling CS back high, signalling the end of the transaction. SPI.endTransaction() is called immediately after to release the SPI bus so other devices or interrupt-driven SPI code can use it.Print Received Bytes
The second
for loop iterates 37 times and prints each entry of receivedValue to the Serial Monitor in hexadecimal using Serial.println(receivedValue[x], HEX). Each line is prefixed with "Received: " for readability. The loop runs to index 36 to cover the full string length plus any trailing null or padding bytes in the buffer.Key Settings
| Parameter | Value | Explanation |
|---|---|---|
| Clock Speed | 100000 Hz | 100 kHz — conservative speed suitable for breadboard wiring and analyzers |
| Bit Order | MSBFIRST | Most-significant bit (bit 7) is transmitted first on MOSI |
| SPI Mode | SPI_MODE2 | CPOL=1, CPHA=0 — clock idles HIGH; data is sampled on the falling edge |
Expected Output
With no slave connected (MISO floating or tied low), the Serial Monitor will display a stream of zero-value bytes repeating every second:53 for 'S', 50 for 'P', 49 for 'I', and so on.
The
delay(1) inside the transfer loop is intentional. It inserts a 1 ms pause between consecutive SPI.transfer() calls, giving the slave device time to process the byte it just received and load its response onto MISO before the master clocks in the next transfer. Removing this delay may result in corrupted or zeroed received values when working with slower slave peripherals or software-based SPI slaves.