Master doesn't receive the correct values in a master/slave SPI link I've been struggling for 3 weeks looking for a solution to my problem concerning SPI communication.

So, I need to establish a SPI communication between two Arduino devices: for instance, the master sends a letter 'a' to the slave; the slave receives it and does some processing. In my case, it should set one of his  8 pins to high then read all pins and send the report back to the master. 

The part where the master sends 'a' and the slave processing it works fine but the master doesn't seem to receive the correct values. Instead it always receives 0.

Here's the code:



Slave:

#include &lt;SPI.h&gt;;

volatile byte command = 0;
byte ett =8; //nbr of test points
byte motif= 0b000000000 ; //intiatition of my varible which will contain my pin's states
byte end[8] = { 2,3,4,5,6,7,8,9}; //array containing the pins

void setup (void) {
  Serial.begin (9600);
  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  // turn on SPI in slave mode
  SPCR |= _BV(SPE);
  // turn on interrupts
  SPCR |= _BV(SPIE);
}  // end of setup

// SPI interrupt routine
ISR (SPI_STC_vect) {
  byte c = SPDR;
  switch (command) {
    //////////////Slave traitement/////////////
    // no command? then this is the command
  case 0:
    command = c;
    SPDR = 0;
    break;

  case 'z': ////case 'z", set all pins to INPUT
    for (int i=0; i&lt;8; i++){
      pinMode (end[i], INPUT);
    }
    break;

  case 'a': // //if 'a' : Set one pin to high then read all pin's satete to verify if there is any open circuit or short circuit
    for (int j = 0; j &lt; ett; j++) {
      pinMode(end[j], INPUT);   // set all pins as INPUT
    }
    motif = 0;
    pinMode(end[0], OUTPUT);  // Set one pin as OUTPUT
    digitalWrite(end[0], HIGH); // Set the output pin to HIGH       
    Serial.println();
    Serial.print(" ");  
    for (int k = 0; k &lt; ett ; k++) { // scan
      if (digitalRead(end[k]) == HIGH) {
        // if pin == HIGH add '1' to my vector
        Serial.print("| ");
        motif = motif + 1; // +1 
      } else { // if pin == LOW
        Serial.print(". ");
      }
      motif = motif &lt;&lt; 1; // shift left
    }
    Serial.print(" -MOTIF LU= ");
    Serial.print(motif, BIN); 
    SPDR = byte (motif); //SPDR is the SPI Data Register: it contains the data that will be sent to the Master
    Serial.print(" ");
    break;
  }
}

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


Master:

#include &lt;SPI.h&gt;

byte CS0=10;
byte CS1=9;

void setup (void) {
  Serial.begin (9600);
  Serial.println ();
  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 (1000);
  return a;
} // end of transferAndWait
///traitement au niveau du maitre

void loop (void)  {
  byte esclave0_testpin0;
  /////////////Set the first slave's pin to High then read all pins
  digitalWrite (CS0,LOW); //activate the slave
  transferAndWait ('a'); // set first slave's pin to high
  esclave0_testpin0 = transferAndWait ('z'); //read all slave's pins and report it in the variable esclave0_testpin0
  digitalWrite (CS0,HIGH); //disactivate the slave
  Serial.println ("test_0");
  Serial.println (esclave0_testpin0, BIN);
  delay (1000);  // 1 second delay 
}  // end of loop
In slave, command is always 0. You problably meant:

void loop(void) {
    command = (digitalRead(SS) == HIGH ? 0 : 1);
}


and at ISR:

ISR (SPI_STC_vect) {

    byte input = SPDR;
    byte output = 0;

    if (command) {

        switch (input) {

            case 'a':
                //...
                break;

            case 'z':
                //...
                break;
        }
    }

     // send data back
     SPDR = output;
}


As a best practice, avoid to implement the logic within the ISR and use global volatile variables to pass state changes to the code in the main loop. Probably you will have to implement a circular buffer to receive from and send to the SPI bus...