I want send data to/from Arduino Leonardo over SPI using wiringPi/pi4j on Raspberry, using custom GPIO as CS. Raspberry is supposed to be the master, and Arduino slave
First my setup:
Raspberry Pi 3B
Arduino Leonardo
Connection:
SCK - RPi pin 23 -> Arduino pin 13
MOSI - RPi pin 19 -> Arduino pin 11
MISO - RPi pin 21 -> Arduino pin 12
CS - RPi pin 27 (GPIO) -> Arduino pin 10
GND - RPi pi 6 -> Arduino pin GND
Pi and Arduino are wired through digital levels converter - 3,3V to PI and 5V to Arduino.
I'm using Java and Pi4j v1.4 library on Raspberry, made sure to activate SPI using sudo raspi-config
Now the code:
Raspberry
import com.pi4j.wiringpi.Spi;
import com.pi4j.wiringpi.Gpio;
///
int fd = Spi.wiringPiSPISetup(0. 9600);
if(fd <= -1) {
// never triggered, initializes correctly
System.out.println("SPI SETUP FAILED");
return;
}
Gpio.pinMode(0, Gpio.OUTPUT); // physical pin 27 equals GPIO 0 in WiringPi
byte someData[] = new byte[3];
someData[0] = 0x11;
someData[1] = 0x22;
someData[2] = 0x33;
Gpio.digitalWrite(0, false);
Spi.wiringPiSPIDataRW(0, someData, 3);
Gpio.digitalWrite(0, true);
And Arduino
#include<SPI.h>
volatile int i = 0;
byte myArray[2];
void setup()
{
Serial.begin(9600);
pinMode(SS, INPUT_PULLUP);
pinMode(MOSI, INPUT);
pinMode(MISO, OUTPUT);
pinMode(SCK, INPUT);
SPCR |= _BV(SPE);
SPI.attachInterrupt(); //allows SPI interrupt
}
void loop(void)
{
if (i == 2)
{
int x = (int)myArray[0]<<8|(int)myArray[1];
Serial.print("Received 16-bit data item from Master: ");
Serial.println(x, HEX);
i=0;
Serial.println("=============================================");
}
}
ISR (SPI_STC_vect) //Inerrrput routine function
{
myArray[i] = SPDR;
i++;
}
Raspberry Pi code is based on SPI Example in Pi4j, and Arduino code is borrowed from here
However, nothing is printed in Arduino serial monitor, nor Raspberry is getting any data back.
I've noticed something weird in Arduino code. CTRL+Click on i.e. MISO takes me to pins_arduino.h where SPI pins are defined and the mapping doesn't look right:
// Map SPI port to 'new' pins D14..D17
#define PIN_SPI_SS (17)
#define PIN_SPI_MOSI (16)
#define PIN_SPI_MISO (14)
#define PIN_SPI_SCK (15)
static const uint8_t SS = PIN_SPI_SS;
static const uint8_t MOSI = PIN_SPI_MOSI;
static const uint8_t MISO = PIN_SPI_MISO;
static const uint8_t SCK = PIN_SPI_SCK;
where clearly according to Leonardo's pinout documentation SCK is D13, MISO is D12, MOSI is D11 and SS is D10. Values in pins_arduino.h look correct for a different board - like Arduino Micro.
However, changing code to
pinMode(13, INPUT); // SCK
pinMode(10, INPUT); // SS
pinMode(11, INPUT); // MOSI
pinMode(12, OUTPUT); //MISO
doesn't seem to help.
Why the discrepency? Could those mapping be the reason for SPI not working? I've got the Arduino AVR Boards package installed which is supposed to include Leonardo