Skip to main content

Documentation 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.

SPI issues typically fall into a few categories — wrong mode, reversed bit order, CS timing errors, or wiring mistakes. This guide covers the most common problems encountered when working through The Embedded Insights SPI examples, with clear causes and concrete fixes for each.
Pins 11, 12, and 13 are shared with the Arduino UNO’s ICSP header. Avoid connecting logic analyzer probes to the ICSP header — use the labeled digital pin numbers on the board edge instead. Using the ICSP header can cause upload failures and unexpected signal interference.

Data / Bit Issues

Cause: No slave device is connected. This is completely normal behavior when running the echo sketches without a slave. The MISO line (pin 12) floats LOW when nothing is driving it, so SPI.transfer() returns 0x00.Fix: This is not an error. Use a logic analyzer connected to CH2 (MOSI, pin 11) to confirm that the correct byte is being transmitted. The Serial.println(receivedValue, HEX) output printing 0 is expected. Connect a real SPI slave — or a loopback wire from MOSI to MISO — to echo data back.
Cause: The SPI mode (CPOL/CPHA) or bit order configured in SPISettings does not match the slave device’s requirements. Even a single-mode mismatch will cause every received byte to be wrong.Fix: Cross-check the dataMode argument in SPISettings against the slave’s datasheet. Try each of the four modes in order (SPI_MODE0 through SPI_MODE3) and observe the decoded output on a logic analyzer. Also verify that bitOrder matches — if the slave uses LSB-first, change MSBFIRST to LSBFIRST. The sketches SPI_Echo_MSB_Mode0.ino through SPI_Echo_LSB_Mode3.ino provide ready-made examples of every combination.
Cause: Baud rate mismatch between the sketch and the Arduino IDE Serial Monitor. All The Embedded Insights sketches initialize serial communication with Serial.begin(9600).Fix: Open the Arduino IDE Serial Monitor and set the baud rate selector (bottom-right corner) to 9600 baud. Any other setting — 115200, 57600, etc. — will display unreadable characters.

CS / Timing Issues

Cause: The CS pin is not properly configured as an output, it was not initialized HIGH before SPI.begin(), or CS is being asserted outside the beginTransaction()/endTransaction() brackets.Fix: Ensure your setup() contains the following lines before SPI.begin():
pinMode(CS, OUTPUT);
digitalWrite(CS, HIGH); // deselect slave at startup
Then in loop(), assert CS inside the transaction:
SPI.beginTransaction(SPISettings(100000, MSBFIRST, SPI_MODE0));
digitalWrite(CS, LOW);           // assert CS after beginTransaction
receivedValue = SPI.transfer(sentValue);
digitalWrite(CS, HIGH);          // deassert CS before endTransaction
SPI.endTransaction();
Pulling CS LOW before calling beginTransaction() can cause the slave to latch incomplete or incorrect data.
Cause: The CS pin is left floating after pinMode(CS, OUTPUT) without being explicitly driven HIGH. A floating output can drift to an indeterminate logic level, inadvertently selecting the slave.Fix: Always call digitalWrite(CS, HIGH) immediately after pinMode(CS, OUTPUT) in setup() — before any call to SPI.begin(). This guarantees the slave is deselected from the very first moment the sketch runs.
void setup() {
  pinMode(CS, OUTPUT);
  digitalWrite(CS, HIGH); // ensure CS is HIGH (slave deselected) at startup
  SPI.begin();
}

Upload / Hardware Issues

Cause: SPI pins 11 (MOSI), 12 (MISO), and 13 (SCK) are also used by the Arduino’s in-system programmer (ISP) during sketch upload. If a slave device or other circuitry is connected to these pins, it can interfere with the upload process and cause avrdude errors.Fix: Disconnect any SPI slave devices — or logic analyzer probes — from pins 11, 12, and 13 while uploading. Reconnect them after the upload completes successfully.
Cause: Some SPI slave devices pull the MISO line HIGH when they are not selected (CS is HIGH). This is normal and compliant behavior — the slave only drives MISO during an active transaction.Fix: Only interpret MISO data (receivedValue) while CS is asserted LOW. Any byte read from SPI.transfer() when CS is HIGH is not valid slave data. Structure your code so that all calls to SPI.transfer() are between digitalWrite(CS, LOW) and digitalWrite(CS, HIGH).
Cause: Missing ground connection, incorrect probe assignment, or the sample rate is set too low to capture the 100 kHz clock transitions.Fix — check in this order:
  1. Confirm the logic analyzer’s ground clip is connected to an Arduino GND pin. Without a shared ground, no signal levels can be measured.
  2. Verify probe assignments match the channel mapping: CH0 → pin 13, CH1 → pin 10, CH2 → pin 11, CH3 → pin 12.
  3. Increase the sample rate to at least 1 MHz (10× the 100 kHz clock). A rate of 4–10 MHz is recommended — see the Sampling Rate note for details.
  4. Check that the capture trigger is set to a falling edge on CH1 (CS) and that the sketch is running (the Arduino is powered and the loop() function is executing).

Start with the simplest sketch — SPI_Echo_MSB_Mode0.ino — and verify that MOSI is transmitting 0x62 correctly using a logic analyzer on CH2. Once you can see a clean waveform, gradually switch to SPI_Echo_MSB_Mode1.ino, Mode2, and Mode3 to observe how the clock idle state and sampling edge change with each mode. This progressive approach makes CPOL and CPHA intuitive rather than abstract.

Build docs developers (and LLMs) love