Can't get SPI to work on Arduino UNO (in a simulation)

Hello everyone,

I just learnt how the SPI protocol works, and wanted to try it out on a simulator before doing it on hardware. So, I wrote some code for communicating between two UNOs and tried to run it on Tinkercad.

The master sends an integer ‘10’ and the slave sends an integer ‘20’ back (well, at least that’s what I want them to do). Then both of them print their received values over Serial. The SS pin (pin 10) on the master is set as an output and the one on the slave is hooked to ground (as an input), as explained in this application note.

But the problem is, it does not seem to work. Looks like it gets stuck in this line :

while(!(SPSR & (1 << SPIF)));

I guess this means that a transaction never takes place. What’s wrong?

Here are the codes for the two devices:

//Master device
byte val;

void setup()
{
  
  SPI_initMaster();
  Serial.begin(9600);
  Serial.println("Ready...");
}

void loop()
{
  val = SPI_transact(10);
  Serial.println(val);
}

void SPI_initMaster(){
  DDRB |= (1<<PB2)|(1<<PB3)|(1<<PB5); //Configure MOSI, SCK and SS pins as output
  SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0);  //Enable SPI as Master, Prescaler = 16
}

byte SPI_transact(byte data){
  SPDR = data;
  while(!(SPSR & (1 << SPIF)));
  return SPDR;
}
//Slave device
byte val;

void setup()
{
  SPI_initSlave();
  Serial.begin(9600);
  Serial.println("Ready...");
}

void loop()
{
  val = SPI_transact(20);
  Serial.println(val);
}
   
void SPI_initSlave(){
  DDRB |= (1<<PB4); //Configure MISO as output
  SPCR = (1<<SPE);  //Enable SPI as Slave
}

byte SPI_transact(byte data){
  SPDR = data;
  while(!(SPSR & (1 << SPIF)));
  return SPDR;
}

Here is the Tinkercad simulation.

Never used simulations myself, I prefer the real thing.

But why are you simulating at the register level ?

Normally you would do just use the SPI library that does it all for you.

Does the Tinkercad application have a support forum ?

Yes, they do. But I thought the Arduino forum would be better.

The trouble with the SPI library is that it has no slave mode. Plus, doing things on register level gives a lot more control.

I'm going to try it for real soon. Just to be sure, do you see any problems in the code?