Most Arduino SPI tutorials show this simple but poor SPI bus design:
A much better SPI bus design can prevent conflicts. 3 simple improvements are needed:
-
Use pullup resistors on all chip select signals.
-
Verify tri-state behavior on MISO: use a tri-state buffer chip if necessary.
-
Protect bus access with SPI.beginTransaction(settings) and SPI.endTransaction().
Click “Read more” for details on these 3 steps.
Step 1: Pullup Resistors for Chip Select & Reset Signals
When multiple SPI devices are used, and especially when each is supported by its own library, pullup resistors are needed on the chip select pins.
Without a pullup resistor, the second device can “hear” and respond to the communication taking place on the first device, if that second device’s chip select pin is not pulled up. This is easy to understand in hindsight, but it can be temendously confusing and frustrating to novice Arduino users who purchase shields or breakout boards without pullup resistors. Each SPI device works when used alone, but they sometimes mysteriously fail when used together, only because both devices are hearing communication meant to initialize only the first device!
A simpe workaround for devices without pullup resistor involves adding code at the beginning of setup.
void setup() { pinMode(4, OUTPUT); digitalWrite(4, HIGH); pinMode(10, OUTPUT); digitalWrite(10, HIGH); delay(1); // now it's safe to use SD.begin(4) and Ethernet.begin() }
For more detail: Better SPI Bus Design in 3 Steps