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.
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.
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)
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!
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.