Potential problem with Arduino Uno's SPI code

Hello all,

I’m using the arduino Uno to interface another development board to the PC via it’s serial terminal.

The communication of the arduino uno with the other board is done via SPI. The arduino uno functions as a master and the other board is slave.
For now I want to just send 1 byte via the SPI from the arduino to the other board to ensure the communication works.

I have ensured that the SPI settings are the same on both sides.
For the other board which is an STM this are the SPI settings:
SLAVE
Frame format: Motorola
Data Size: 8 bits
First Bit: MSB First
Clock Polarity: Low
Clock Phase: 1 edge(CPOL = 0, CPHA = 0)
CRC: Disabled
NSS Signal Type: Input Hardware
Baud rate: 21Mhz

The way I’ve written the sketch is that when I send something on the serial terminal(doesn’t matter what for now) the arduino should send a byte(0) via the SPI to my STM board.
The problem that I’m facing is that the byte does not seem to reach the STM board all the times…It reaches there only sometimes but not all the time.
Since I don’t have experience with arduino I’m guessing maybe I have done a mistake in the sketch but I can’t tell what exactly I did wrong. Please help me correct this issue if it’s a problem on the arduino side. Thank you!

Edited: Posted the code in the original message.

#include <SPI.h>

char received_data;   //variable to store read data
SPISettings settingsA(2100000, MSBFIRST, SPI_MODE0); 

void usart_setup()
{
 Serial.begin(115200);
 Serial.println("Initializing USART");
 Serial.println("USART initialized!"); 
}

void spi_setup()
{
 Serial.println("Initializing SPI");
 
 pinMode(10, OUTPUT); // set the SS pin as an output
 SPI.begin();         // initialize the SPI library   
 
 Serial.println("SPI initialized");
}

void setup() 
{
 usart_setup();
 spi_setup();
}

void loop() 
{
 while(Serial.available())  //check for any data received
 { 
     received_data = Serial.read();
     
     SPI.beginTransaction(settingsA);
     digitalWrite(10, LOW); //pull SS to low to activate slave
     SPI.transfer(0);
     digitalWrite(10, HIGH); //pull SS to HIGH to deactivate slave
     SPI.endTransaction();
     
     Serial.print("Data sent via SPI!");  
     
 }
}

code.ino (971 Bytes)

Why not post the code in code tags, it's short enough.

I found that, when troubleshooting SPI/I2C issues that a cheapo logic analyzer is invaluable. With a login analyzer one can 'see' what's going on and is a big help in finding the offending culprit.

I use this elcheapo model https://smile.amazon.com/HiLetgo-Analyzer-Ferrite-Channel-Arduino/dp/B077LSG5P2/ref=sr_1_3?crid=1H8QESFS7TZBV&dchild=1&keywords=logic+analyzer&sprefix=logic+an%2Caps%2C950&sr=8-3

Also, ask yourself, with millions of Uno's out there would a SPI problem be the Uno/SPI or the code you wrote?

By Arduino Uno's SPI I meant my code...not a hardware problem...I clearly said in the message I assume I have made a mistake in the sketch. Sadly I do not have an analyzer or oscilloscope to help me with this problem. I have added the code in the original message now.

Ima gonna guess the issue is this:

[color=#222222] while(Serial.available())  //check for any data received[/color]
[color=#222222] {

You can test that by commenting it out. Instead send to the STM, for TESTING, a SPI message 1 time a second, use delay(1000) in the loop to send. If the STM is getting a message one time a second, now you know something more.

SPISettings settingsA(2100000,

Baud rate: 21Mhz

Which?

(sp.“MHz”)

TheMemberFormerlyKnownAsAWOL: SPISettings settingsA(2100000,

Which?

(sp."MHz")

Good catch.

Of course, 21 MHz is going to be . . . problematic

TheMemberFormerlyKnownAsAWOL: Of course, 21 MHz is going to be . . . problematic

Is that too much for SPI? I have also tried with 8Mhz and 15 Mhz and got the same result :(. SPISettings settingsA(1500000, MSBFIRST, SPI_MODE0); SPISettings settingsA(800000, MSBFIRST, SPI_MODE0);

Remember, you're running on a 16 MHz process that does not have DMA.

It’s not too much for SPI.
For a 16MHz processor, on the other hand…

SPI on th Uno is limited to these speeds: 8 MHz 4 MHz - the default speed if nothing is changed 2 MHz 1 MHz 512 KHs 256 KHz 128 KHz 64 KHz

Other defaults are MSB First, and Mode 0.

You have to change the defaults if you want something else. You can add lines after you call SPI.begin(); to change them. https://www.arduino.cc/en/Reference/SPI I'v only changed the clock speed to 8 MHz, or 2 MHz, and it's been ages since I did that in any project; I don't recall the format of the command to do it.

CrossRoads:
SPI on th Uno is limited to these speeds:
8 MHz
4 MHz - the default speed if nothing is changed
2 MHz
1 MHz
512 KHs
256 KHz
128 KHz
64 KHz

Other defaults are MSB First, and Mode 0.

You have to change the defaults if you want something else. You can add lines after you call SPI.begin(); to change them.
Arduino - SPI
I’v only changed the clock speed to 8 MHz, or 2 MHz, and it’s been ages since I did that in any project; I don’t recall the format of the command to do it.

Ok. I have modified the code like this since the default settings are ok for me I think(4Mhz clock for master and data MSB first and data format 0) since my Slave is sitting on a bus with 42Mhz top speed, SPI is configured as MSB first and also data format 0.
So I have changed the code like this:

#include <SPI.h>
char received_data;   //variable to store read data
void usart_setup()
{
  Serial.begin(115200);
  Serial.println("Initializing USART");
  Serial.println("USART initialized!"); 
}
void spi_setup()
{
  Serial.println("Initializing SPI");
  
  pinMode(10, OUTPUT); // set the SS pin as an output
  SPI.begin();         // initialize the SPI library   
  digitalWrite(10, HIGH); // disable slave select
  
  Serial.println("SPI initialized");
}
void setup() 
{
  usart_setup();
  spi_setup();
}
void spi_sent()
{
 digitalWrite(10, LOW); //pull SS to low to activate slave
 SPI.transfer(6);
 digitalWrite(10, HIGH); //pull SS to HIGH to deactivate slave
}
void loop() 
{  
  spi_sent();
  delay(1000); 
  Serial.print("Data sent via SPI!\n");
}

But the issue persists…I’m guessing the arduino code is ok and there is a problem with the code for my other board.
I will try to get my hands on an oscilloscope and debug this.