I'm trying to have a Raspberry PI act as a SPI master and send data to an Arduino Nano (one of the cheap clones). I partly succeeded, but I don't get a continuous communication, and some bytes get lost.
I only use simple wires on a breadboard to connect the two devices, no other components involved. These are the connections:
- Pi MOSI - Arduino D11
- Pi MISO - Arduino D12
- Pi SCLK - Arduino D13
- Pi GND - Arduino GND
Pi 5V is connected to a bench power supply. The Arduino is powered via USB cable connected to my Mac. Ground is common.
Here's a picture:
Following the instructions I found here, on the Arduino sketch I initialize SPI slave mode (I know it can't be master, or it will send 5V down the line and fry the Pi) this way:
pinMode(SCK, INPUT);
pinMode(MOSI, INPUT);
pinMode(MISO, INPUT);
SPCR |= _BV(SPE);
then I use SPI.attachInterrupt()
and define a function ISR (SPI_STC_vect) { byte c = SPDR; ... }
to read the bytes into a memory buffer in the quickest possible way (since it's an interrupt).
On the RaspberryPI side I tried several libraries:
- node.js pi-spi
- python wiringpi
- python spidev
With all the above libraries I tried to:
- change frequency from 1 KHz to 5 MHz
- change all the 4 possible SPI modes (2 x 2 combinations of clock polarity and phase)
- send a burst of 10-20 bytes, or send one byte at a time, with a program waiting for my user input on the keyboard
In all cases, as I said, I experienced a significant data loss (from, say, 10% to 80%).
I even tried to debug the signal with an oscilloscope. It looked pretty good to me, but I'm no expert.
I saw posts from people having (supposedly) done this with success. Why am I failing?
Hypothesis:
- My wires are crappy
- My Arduino is crappy
- My Raspberry PI is crappy (actually I tried 2 different ones at some point)
- My interrupt handler is too slow
Is there a better way to communicate?
A. I2C B. serial over USB
Please advice, oh knowledgeable crowd, and I shall be happy.