Establishing SPI between XIAO nrf52840 and Arduino nano

Hello,

I have a Seeed Studio XIAO nrf52840 and an Arduino Nano. I have been trying to establish communication between both of them using SPI protocol. I have been facing certain issues while doing so. Please find the details.

Master: Arduino Nano
Slave: Seeed Studio XIAO nrf52840
Platform Used: Arduino IDE

Master Code:
#include <SPI.h>

#define SS 2
byte Send_Data;
byte Receive_Data;

void setup()
{
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);

Serial.begin(115200);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
}

void loop()
{
digitalWrite(SS, LOW);
Send_Data = 55;
SPI.transfer(Send_Data);
Receive_Data = SPI.transfer(Send_Data);
digitalWrite(SS, HIGH);

Serial.print("Sent: “);
Serial.println(Send_Data);
Serial.print(”, Received: ");
Serial.println(Receive_Data);
delay(1000);
}

Slave Code:

#include <SPI.h>
#include <Adafruit_TinyUSB.h>

#define Slave_Select 1
int data_receive = 0;

void setup()
{
pinMode(Slave_Select, INPUT);
pinMode(SCK, INPUT);
Serial.begin(115200);

SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
}

void loop()
{
if(digitalRead(Slave_Select)==LOW)
{
data_receive = SPI.transfer(0);
while(digitalRead(Slave_Select) == LOW);
Serial.print("Received: ");
Serial.println(data_receive);
data_receive = 0;
}
}

The slave is not receiving 55, instead it is giving random outputs such as, FF, 0, FE etc. Can anyone kindly help me sort this out?

PS: All the hardware connections are in the right place.

HI there,
So the code looks close, a couple things to consider. Post a Picture Also of the connections Please.
On the Xiao (slave) which BSP are you using looks like Non-Mbed?
Try explicitly naming the SPI pins using the GPIO pin number, i.e. SS = 02


I like to add this for testing to see if the pins I think are correct , verify and test.

//Find the default SPI pins for your board
//Make sure you have the right board selected in Tools > Boards
// slow down don't be in such a hurry, LOL gives MCU more time in port
#include <SPI.h>
#define Slave_SCK 8
#define Slave_MISO 9
#define Slave_MOSI 10
#define Slave_CS 0  // may need to use the GPIO name (gpio P0.**02**) 
void setup() {
  // put your setup code here, to run once:
  Serial.begin(9600);
  Serial.print("MOSI: ");
  Serial.println(MOSI);
  Serial.print("MISO: ");
  Serial.println(MISO);
  Serial.print("SCK: ");
  Serial.println(SCK);
  Serial.print("SS: ");
  Serial.println(SS);  
}
void loop() {
  // put your main code here, to run repeatedly:
}

Your close , give that a try and report back. also you may need as well.
run the pin test on both see if they are the ones you wired.

#include <Wire.h>

HTH
GL :slight_smile: PJ
:v:

Thanks a lot for your response.

I have modified the code you have given slightly. It is as follows:

#include <SPI.h>
#include <Wire.h>
#include <Adafruit_TinyUSB.h>

//#define Slave_SCK 8
//#define Slave_MISO 9
//#define Slave_MOSI 10
//#define Slave_CS 0

void setup()
{
Serial.begin(9600);
}

void loop()
{
Serial.print("MOSI: ");
Serial.println(MOSI);
Serial.print("MISO: ");
Serial.println(MISO);
Serial.print("SCK: ");
Serial.println(SCK);
Serial.print("SS: ");
Serial.println(SS);
delay(1000);
}

The outputs for Arduino Nano are:
MOSI: 11
MISO: 12
SCK: 13
SS: 10

The outputs for XIAO nRF52840 are:
MOSI: 10
MISO: 9
SCK: 8
SS: 7

I have modified the master and slave codes as well. I have added the pin declarations along with the directions to it. I ran the code for both the master and slave devices. Yet, I am unable to get the required output.
Please let me know if I have misunderstood something here.

Also, I am unable to attach/upload pictures here somehow. Could you please let me know how its done?

i think new posters are not allowed to post pictures… sorry

Hi there,
New folks only after 3 or 4 posts, can you attach stuff.
HTH
GL :slight_smile: PJ
:v:

So how do I share the pictures of my outputs and connections here?

Hi there,
Ok let’s assume you have it wired like
8-13 SCK
11-10 MOSI
12-9 MISO
10-7 <—OUTput to—> INPUT here…Master/Slave

FYI the Xiao is Slave so it’s SS(CS) should be an Input. and rename to CS (chip select) do a define as such as well.
You’re close… you’ll get it :+1: fix the direction and besure to DE-assert the pin (SS ) when done and Assert it when Starting transfer.
Look at how some of the Flash SPI chips do it… ie. Xiao Grove expansion board demo.
HTH
GL :slight_smile: PJ
:v:

Yes, I have done as mentioned.

Now the code looks this:
// Master (Arduino NANO)

#include <SPI.h>
#define SS 10
#define MOSI 11
#define MISO 12
#define SCK 13

byte Send_Data;
byte Receive_Data;
void setup() {
pinMode(MOSI,OUTPUT);
pinMode(MISO,INPUT);
pinMode(SCK, OUTPUT);
pinMode(SS, OUTPUT);
digitalWrite(SS, HIGH);

Serial.begin(115200);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8);
SPI.setDataMode(SPI_MODE0);
SPI.setBitOrder(MSBFIRST);
}

void loop()
{
digitalWrite(SS, LOW); //Assertion
Send_Data = 10;
SPI.transfer(Send_Data);
Receive_Data = SPI.transfer(Send_Data);
digitalWrite(SS, HIGH); //De-Assertion
Serial.print("Sent: ");
Serial.println(Send_Data);
Serial.print("Received: ");
Serial.println(Receive_Data);
delay(1000);
}

I am still not getting the required output :smiling_face_with_tear:

When the master and the slave devices are connected but the master is not powered my outputs are 0’s but when it is powered, the outputs are 255.

Hi there,
Keep in mind the Xiao outputs are active LOW. so you ay need to invert your logic?
and the XIao is SLAVE so it 's SS needs to be input, right?

pinMode(D6, INPUT_PULLUP);  // /WP
  //pinMode(D7, INPUT_PULLUP);  // /HOLD
  pinMode(SS_SPI0, OUTPUT);          // CS for flash
  digitalWrite(SS_SPI0, HIGH);       // <-- Set CS pin HIGH to deselect
  pinMode(buttonPin, INPUT_PULLDOWN);  // initialize the pushbutton pin as an input: for GROVE PB

from this example, it is a little confusing and is a reverse logic, see comments
So close You are…LOL :+1:

HTH
GL :slight_smile: PJ
:v:

Pardon me for not mentioning, but I provided the code for the master microcontroller since I have triggered the SS signal from the master itself. Here I am providing the code for slave as well

// Slave (Seeed Studio nRF52840)

#include <SPI.h>
#include <Adafruit_TinyUSB.h>
#define CS 7
#define SCK 8
#define MISO 9
#define MOSI 10

int data_receive = 0;

void setup()
{
pinMode(MOSI,INPUT);
pinMode(MISO,OUTPUT);
pinMode(SCK, INPUT);
pinMode(CS, INPUT);

Serial.begin(115200);
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8); // SPI speed
SPI.setDataMode(SPI_MODE0); // SPI mode
SPI.setBitOrder(MSBFIRST); // Most significant bit first
}

void loop()
{
if(digitalRead(CS)==LOW)
{
data_receive = SPI.transfer(0);
while(digitalRead(CS) == LOW);
Serial.print("Received: ");
Serial.println(data_receive);
data_receive = 0;
}
}

Hi there,
Great , yes my bad, you add the print of the pins for SPI at the end to verify, use the SS nomenclature.
Sorry, for CS
Also add some delays in between the read and writes of SPI. that usually does the trick
HTH
GL :slight_smile: PJ
:v:

Hi!
Please find the snippet of the Master code where I have added the delays. Kindly let me know if I have done it right.

void loop()
{
digitalWrite(SS, LOW);
Send_Data = 10;
SPI.transfer(Send_Data);
delay(1000);
Receive_Data = SPI.transfer(Send_Data);
delay(1000);
digitalWrite(SS, HIGH);
}

I am still not able to get the output.

Hi there,
Can you switch the (SS) logic to opposite of what you have and try again.

SS = D7;
void loop()
{
digitalWrite(SS, HIGH);
Send_Data = 10;
SPI.transfer(Send_Data);
delay(1000);
Receive_Data = SPI.transfer(Send_Data);
delay(1000);
digitalWrite(SS, LOW);
Serial.println("Master sent");
}

Which BSP are you using for the Nrf52840 Xiao suggesting 1.1.1
HTH
GL :slight_smile: PJ
:v:

Hey, I have made the changes.

Output from the master.
Master sent
Sent: 10
Received: 0
Master sent
Sent: 10
Received: 0

This is the output from the slave:
Received: 0
Received: 255
Received: 255

Now what to do? The BSP I have installed is 1.1.8.

Hi there,
What kind of variable is Send and received data I don’t see any assignment of is being hex or ascii or decimal. BSP 1.1.8 should be ok, Check and make sure your libraries are the correct ones Look at you compiler output to see they are what you think version wise.
You can go to the board tab and roll it back to 1.1.1 if just to test. if you get the same output then go with the latest. The SPI may be different for each MCU.
back out the delay’s reducs them and also what SPI clock divider are you setting if any, for the SPi buss speed.
HTH
GL :slight_smile: PJ
:v:
keep going. :+1:

Arduino_nano’s input/output is 5V logic and XIAO’s input/output is 3.3V logic. Normally, you need a level shifter to connect them. Has this been discussed anywhere in this thread?

1 Like

Hi there,
as always , you spot the issue easily over looked…
OP may want to look at that as he makes NO mention of it anywhere.
I completely missed that myself. for some reason I was thinking it was a Arduino Due’
GL :slight_smile: PJ
:v:

… Duo… Tripo… What’s the diffo?..lol

Hi there,
One is a 5v signal and the others Are 3vsignal compatible…
Nano is a 5V hence the level shifter and why he’s getting 255’s
HTH
GL :slight_smile: PJ
:v:

Hi,

I apologize for the late response. I have tried the same codes after connecting both the devices with a level converter. I am unable to see any output on the receiver’s end.

But, the outputs from the master’s end has been showing some variation.

When the level converter has a 5V to 3V connection:
Master sent
Sent: 10
Received: 255

When the level converter does not have a 5V to 3V connection:
Master sent
Sent: 10
Received: 0