Raspberry Pi to Arduino SPI Communication

Hello everyone,

I have a project that, i need to communicate Raspberry Pi 4 (Master) with Arduino Uno (Slave) on SPI.
I am using SPI.h library on Arduino and spidev library in Python on RPi. My aim is that, Master is going to fill a data buffer and send it to the Slave at 1Mbps. I couldn't achieve the data sending process so i designed a simple transmit example. In this example Master send a byte to Slave and Slave print that byte on the screen. But i couldn't this example either. I am using logic converter on my connections so, i think voltage difference is not a problem. When i searched through ethernet, i found some examples with the WiringPi Library but i have to code RPi in Python.
Also i found Penguin Tutor's tutorial but i failed to convert that code for my purpose.

My Arduino Code:

// Jan 2022
// Orkun KESKİN

//SLAVE CODE

#include <SPI.h>

//Received byte from Master
volatile byte recv_byte;

void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600); // for debugging.

  // Turn ON SPI in slave mode.
  SPCR |= bit(SPE);
  // Have to send on MASTER IN, SLAVE OUT
  pinMode(MISO,OUTPUT);
} // end of setup

void loop() {
  
  //Byte Received!
  if ((SPSR & (1 << SPIF)) != 0)
  {
    recv_byte = SPDR;
  }  
    Serial.println(recv_byte);

}

Raspberry Pi Code:

#Master Code 
#Orkun KESKİN Jan 2022

import spidev
import time
#SPI Bus and CE pin selection 
spi_bus=0
spi_device=0

#SPI activating
spi = spidev.SpiDev()
spi.open(spi_bus,spi_device)
#Transmitting speed is 1Mbps
spi.max_speed_hz=1000000

#Sending Sequence
while True:
    send_byte = 0x05  #Sent byte to the Receiver from Transmitter
    spi.xfer2([send_byte])
    time.sleep(0.5)  #Delay for Arduino's register, it may be 0.25

I receive zeros in Arduino's Serial Port Screen. What am i missing?
Thank you.

Did you check that all used hardware is able to work correctly at 1MHz? (We cannot check as you failed to provide a wiring diagram)
Did you connect the grounds?

Don't print anything to the Serial if you didn't receive anything. Compared to SPI speed (1MHz) the serial speed (9.6kHz) is extremely slow.

1 Like

Hello,

My main problem was, serial screen could not catch the SPI speed so, i couldn't see any meaningful variable on screen I raised bitrate, i used interrupt, instead of polling and it worked.
Thank you.

1 Like

Does anyone know how to do the opposite? I mean, having the RPi configured to only read and store the received data via SPI from a sensor connected to Arduino (In my case an ESP32 but It doesn't matter at all)

You cannot read from SPI, you get written.

But to my knowledge there is no software support for that feature. You may try to dive yourself into the lower functions of the BCM2835 as an SPI slave but I wouldn't expect someone else to do that because it doesn't make sense.

The SPI bus isn't a host-to-host communication interface!

1 Like

But then, how can I approach this? Can you point me in the right direction in terms of which documentation should I dive into (which registers to use, how to configure them, etc)?

I have my application working via WiFi and MQTT, via USB and via I2C, but I need to decide which one of the serial "low-level" communications protocol is the fastest for what i want. In this case, the Arduino is the one getting the information and sending it to the Raspberry, which just reads and stores it. Do I have to answer on every transaction with just blank bytes? That's gonna slow me down for sure. I don't know, I'm a bit lost with SPI.

But, anyway, thanks for your answer and your time.

My suggestion: don't use SPI. Use UART or WiFi.

If you insist in SPI, you might have to ask in a Raspberry Pi forum as this definitely isn't out of scope for this forum.

Be prepared to implement a linux kernel module if you actually want to do that.

1 Like

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.