Problem with two Arduino Nano: the first as SPI Master, the second as SPI Slave

Hi All.
I tested method of linking betweene to two Arduino Nano: the first as SPI Master, the second as SPI Slave.
This method was bescriebed by Nick Gammon Gammon Forum : Electronics : Microprocessors : SPI - Serial Peripheral Interface - for Arduino.
In my test Master sends to Slave an array of structures(40 bytes) and then receves from slave an array of structures(8 bytes). So, test works good exept anytime Master receives from Slave structure vith values
{0, 0, 0, 0, 0, 0, 0, 0}. I has couldn’t find the reason of such behaviour. Belowe are shown scetches of Master and Slave Arduinos and fragments of outputs prining an in concole.

Master:________________________

#include <SPI.h>

typedef struct
{
  uint8_t comnd;
}Set;
Set set[8];

typedef struct
{
  uint8_t  Vstat = 1;
  uint16_t Vbat  = 307;
  uint8_t  Sen   = 38;
  int8_t   rssi  = -57;
}Stat;
Stat stat[8];

void setup (void)
{
  Serial.begin(38400);
  digitalWrite(SS, HIGH);  // ensure SS stays high for now

  // Put SCK, MOSI, SS pins into output mode
  // also put SCK, MOSI into LOW state, and SS into HIGH state.
  // Then put SPI hardware into Master mode and turn SPI on
  SPI.begin ();

  // Slow down the master a bit
  SPI.setClockDivider(SPI_CLOCK_DIV8);

}  // end of setup
//----------------------------------------

byte transferAndWait (const byte what)
{
  byte a = SPI.transfer (what);
  delayMicroseconds (10);
  return a;
} // end of transferAndWait
//-----------------------------------------
long Tbegin;
void loop (void)
{
  char c;
  uint8_t lenth, j = 0;
  uint8_t buf[40];
  long temp, tbeg = micros();

  //convering of array of structures in array of bytes
  for (uint8_t i = 0; i < 8; i++)
  {
    buf[i * 5 + 0]   = stat[i].Vstat;
    buf[i * 5 + 1] = stat[i].Vbat >> 8;
    buf[i * 5 + 2] = stat[i].Vbat & 0x00FF;
    buf[i * 5 + 3] = stat[i].Sen;
    buf[i * 5 + 4] = stat[i].rssi;
  }

  Serial.print("Tconv="); Serial.println(micros() - tbeg);
  for (uint8_t i = 0; i < 8; i++)
  {
    Serial.print(buf[i * 5]); Serial.print(" ");
    Serial.print(buf[i * 5 + 1]); Serial.print(" ");
    Serial.print(buf[i * 5 + 2]); Serial.print(" ");
    Serial.print(buf[i * 5 + 3]); Serial.print(" ");
    Serial.println(buf[i * 5 + 4]);
  }
  Serial.println();

  lenth = sizeof(buf);

  Serial.print("Lenth="); Serial.println(lenth);

  tbeg = micros();
  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10
  //Send to Slave command: Send(Satus)
  transferAndWait('S');
  //transferAndWait (10);

  for (uint8_t i = 0; i < lenth; i++)
  {
    transferAndWait(buf[i]);
  }
  transferAndWait(0);
  //  SPI.transfer (buf);
  //  delayMicroseconds (20);

  // disable Slave Select
  digitalWrite(SS, HIGH);
  //Serial.print("Ttransf="); Serial.println(micros() - tbeg);

  delayMicroseconds (200);
  //delay(1);
  // enable Slave Select
  digitalWrite(SS, LOW);    // SS is pin 10
  //Send to Slave command Send(Satus)
  transferAndWait('R');
  transferAndWait(0);

    for (uint8_t i = 0; i < 8; i++)
    {
      set[i].comnd = transferAndWait(0);
    }

  // disable Slave Select
  digitalWrite(SS, HIGH);
  temp = micros() - tbeg;
  Serial.print("Ttransf="); Serial.println(temp);
  
  for (uint8_t i = 0; i < 8; i++)
  {
    Serial.print(set[i].comnd); Serial.print(" ");
  }
  Serial.println();
  Serial.flush();
  
  delay (2000);  // 2 seconds delay
}  // end of loop

Slave_____________________________

#include <SPI.h>

typedef struct
{
  uint8_t comnd;
}Set;
Set set[8] = {1, 2, 3, 4, 5, 6, 7, 8};

typedef struct
{
  uint8_t Vstat;
  uint16_t Vbat;
  uint8_t Sen;
  int8_t rssi;
}Stat;
Stat stat[8];


char buf [100];
bool Fl_buf_done = 0;
volatile byte command = 0;

//---------------------------------------
void setup (void)
{
  Serial.begin (38400);   // debugging
  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  pinMode(9, OUTPUT); //high level on pin9 indicate processing
                      //of SPI interrupt (for serial analizer Channel 4)

  // turn on SPI in slave mode
  SPCR |= _BV(SPE);

  // turn on interrupts
  SPCR |= _BV(SPIE);
  Serial.println("Setup done");
}  // end of setup
//----------------------------------------

// SPI interrupt routine------------------
ISR (SPI_STC_vect)
{
  byte c = SPDR;
  static uint8_t i;

  noInterrupts(); //disable all interrupts

  switch (command)
  {
    case 0: // no command? then this is the command
      command = c;
      i = 0;
      Fl_buf_done = 0;
      SPDR = 0;
      break;
    case 'S': // receive array from Master
      buf[i] = c;
      i++;
      if (i > 39)
        Fl_buf_done = 1;

      //Pin9 for indication in serial analizer  
      digitalWrite(9, HIGH); 
      digitalWrite(9, LOW);       
      break;
    case 'R': //send array to Master
       if (bitRead(SPSR, 6))
      {
        digitalWrite(9, HIGH);
        digitalWrite(9, LOW);
      }
      SPDR = set[i].comnd;
      i++;
      break;
    default :
      break;
  } // end of switch
  interrupts(); //enable interrupt again
}  // end of interrupt routine SPI_STC_vect
//--------------------------------------------------
// main loop - wait for flag set in interrupt routine
void loop (void)
{
  // if SPI not active, clear current command
  if (digitalRead (SS) == HIGH)
    command = 0;
  if (Fl_buf_done)
  {

    for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(buf[i * 5], DEC); Serial.print(" ");
      Serial.print(buf[i * 5 + 1], DEC); Serial.print(" ");
      Serial.print(buf[i * 5 + 2], DEC); Serial.print(" ");
      Serial.print(buf[i * 5 + 3], DEC); Serial.print(" ");
      Serial.println(buf[i * 5 + 4], DEC);
    }
    Serial.println();
    Serial.flush();

    //clear buffer
   for (uint8_t k = 0; k < 40; k++)
    {
     buf[k] = 0;
    }
    Fl_buf_done = 0;
  }

}  // end of loop

Output of Master:___________________________

Tconv=72
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199

Lenth=40
Ttransf=984             must be     :  1 2 3 4 5 6 7 8
0 0 0 0 0 0 0 0 <<-----------------------------------
Tconv=72                but receved:  0 0 0 0 0 0 0 0
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199

Lenth=40
Ttransf=984
1 2 3 4 5 6 7 8 
Tconv=72
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199
1 1 51 38 199

Lenth=40
Ttransf=984
1 2 3 4 5 6 7 8 
Tconv=68
1 1 51 38 199
1 1 51 38 199

Slave (here all is Ok):____________________

1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57

1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57

1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57

1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57
1 1 51 38 -57

What may be the reason of such behaviour?
Thank You.

ISR (SPI_STC_vect)
{
  byte c = SPDR;
  static uint8_t i;

  noInterrupts(); //disable all interrupts

Disabling interrupts is not necessary inside ISRs as interrupts are disabled already when the processor enters the ISR.

The rest is probably a race condition. You check the state of SS only once per loop. On the master you pull SS high for 200µs, a bit less than the time you need on the slave to transfer one character over the serial interface. You print much more than 64 bytes to the serial interface per loop (if the buffer was filled) so that loop is not checking SS for a long time and command is not reset. That results in not recognizing your request command from the master, so the master just reads 0.

Thank You.

You check the state of SS only once per loop

You are right. Some days ago I edited ISR (SPI_STC_vect) and loop() in Slave.

// SPI interrupt routine------------------
ISR (SPI_STC_vect)
{
  byte c = SPDR;
  static uint8_t i;

  noInterrupts(); //disable all interrupts

  switch (command)
  {
    case 0: // no command? then this is the command
      command = c;
      last_cmnd = command;
      i = 0;
      SPDR = 0;
      break;
    case 'S': // receive array from Master
      //      digitalWrite(9, HIGH);
      buf[i] = c;
      i++;
      if (i > 39) //if (i > 39)
        Fl_buf_done = 1;
      break;
    case 'R': //send array to Master
      SPDR = set[i].comnd;
      i++;
      break;
    default :
      break;
  } // end of switch

  interrupts(); //enable interrupt again

}  // end of interrupt routine SPI_STC_vect
//--------------------------------------------------
// main loop - wait for flag set in interrupt routine
void loop (void)
{
  long tbeg = micros();

  // if SPI not active, clear current command
  if (digitalRead (SS) == HIGH)
  {
    command = 0;
  }

  if (Fl_buf_done and  (digitalRead (SS) == HIGH) and last_cmnd == 82) //82 is code of symbol 'R'
  {
    for (uint8_t i = 0; i < 8; i++)
    {
      Serial.print(buf[i * 5], DEC); Serial.print(" ");
      Serial.print(buf[i * 5 + 1], DEC); Serial.print(" ");
      Serial.print(buf[i * 5 + 2], DEC); Serial.print(" ");
      Serial.print(buf[i * 5 + 3], DEC); Serial.print(" ");
      Serial.println(buf[i * 5 + 4], DEC);
    }
    Serial.println(last_cmnd);
    Fl_buf_done = 0;
    last_cmnd = 0;


    for (uint8_t i = 0; i < 40; i++)
    {
      buf[i] = 0;
    }
  }
 
  //Serial.print("Tloop="); Serial.println(micros() - tbeg);
}  // end of loop

Now Slave works right.