0

I have problem creating Setup which have :

  1. A SPI Master (Arduino Mega 2560)

  2. SPI slaves (Arduino Mega 2560) ,which responds to the Masters request by sending float data (or Rather a 2D float array ,but lets just go step by step).

So,I initially started with 3 Arduinos in total (going step by step):

  • Arduino_1 :Master
  • Arduino_2 :Slave_1
  • Arduino_3 :Slave_2

I used ICSP pins for connection and Digital pin 53 (as mentioned in Nick Gammon's page :http://www.gammon.com.au/spi or How do you use SPI on an Arduino? ,they are good resources to start with SPI) and 10 for SS.

MY Master codes looks like:

#include <SPI.h>
#define SS_Slave_2 10

void setup ()
{
 Serial.begin (9600);//115200

 pinMode(SS,OUTPUT);
 pinMode(SS_Slave_2,OUTPUT);
 pinMode(MOSI,OUTPUT);
 pinMode(SCK,OUTPUT);

 digitalWrite(SS, HIGH);  // ensure SS stays high for now
 digitalWrite(SS_Slave_2, HIGH);

 digitalWrite(SCK,LOW);
 digitalWrite(MOSI,LOW);


 // 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);
}

byte transferAndWait (const byte what)
{
  byte a = SPI.transfer (what);
  delayMicroseconds (100);
  return a;
} 

union first_union
{
 float f;
 byte b[4];
}data;

float yaw, pitch, roll, alt, temp;   
float yaw_2, pitch_2, roll_2, alt_2, temp_2;

void loop (void)
{
 digitalWrite(SS_Slave_2, HIGH);
 digitalWrite(SS, LOW);

 //YAW
 transferAndWait ('Y');
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 yaw = data.f;

 //PITCH
 transferAndWait ('P');
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 pitch = data.f;

 //ROLL
 transferAndWait ('R');
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 roll = data.f;

 //TEMP
 transferAndWait ('T'); 
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 temp = data.f;

 //ALT
 transferAndWait ('A'); 
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 alt = data.f;

 digitalWrite(SS, HIGH);
 digitalWrite(53, HIGH);
 digitalWrite(SS_Slave_2, HIGH);
 Serial.println("Slave_01: Start");
 Serial.print("yaw:");
 Serial.println(yaw, 4);
 Serial.print("pitch: ");
 Serial.println(pitch,4);
 Serial.print("roll:");
 Serial.println(roll,4);
 Serial.print("alt: ");
 Serial.println(alt,4);
 Serial.print("temp: ");
 Serial.println(temp,4);
 Serial.println("Slave_01: End");

 digitalWrite(SS, HIGH);
 digitalWrite(53, HIGH);
 digitalWrite(SS_Slave_2, LOW);

 //YAW
 transferAndWait ('Y');
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 yaw_2 = data.f;

 //PITCH
 transferAndWait ('P');  
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 pitch_2 = data.f;

 //ROLL
 transferAndWait ('R');  
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 roll_2 = data.f;

 //TEMP
 transferAndWait ('T');
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 temp_2 = data.f;

 //ALT
 transferAndWait ('A');
 data.b[0] = transferAndWait ('1');
 data.b[1] = transferAndWait ('2');
 data.b[2] = transferAndWait ('3');
 data.b[3] = transferAndWait ('Z');
 alt_2 = data.f;

 digitalWrite(SS_Slave_2, HIGH);
 digitalWrite(SS, HIGH);
 digitalWrite(53, HIGH);
 Serial.println("Slave_02: Start");
 Serial.print("yaw_2:");
 Serial.println(yaw_2, 4);
 Serial.print("pitch_2: ");
 Serial.println(pitch_2,4);
 Serial.print("roll_2:");
 Serial.println(roll_2,4);
 Serial.print("alt_2: ");
 Serial.println(alt_2,4);
 Serial.print("temp_2: ");
 Serial.println(temp_2,4);
 Serial.println("Slave_02: End");

 delay(500);
}

And Slave Code goes like:

#include <SPI.h>

volatile byte command;
//Set the default object
float ypr[3];
float alt = 0;
float temp = 0;


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

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

  // have to send on master in, *slave out*
  pinMode(MISO, OUTPUT);
  pinMode(MOSI,INPUT);
  pinMode(SCK,INPUT);
  pinMode(SS,INPUT);


  // turn on interrupts
  SPCR |= _BV(SPIE);

}

union first_union
{
    float f;
    byte b[4];
 }data;

ISR (SPI_STC_vect)
{
  byte c = SPDR;

  command = c;

  switch (command)
  {
   case 'Z':
   data.f = 0;
   SPDR = 0;
   break;
   case 'Y':
   data.f = ypr[0];
   SPDR = data.b[0]; 
   break;
   case 'P':
   data.f = ypr[2];
   SPDR = data.b[0]; 
   break;
   case 'R':
   data.f = ypr[1];
   SPDR = data.b[0]; 
   break;
   case 'A':
   data.f = alt;
   SPDR = data.b[0]; 
   break;
   case 'T':
   data.f = temp;
   SPDR = data.b[0]; 
   break;
   case '1':
   SPDR = data.b[1];
   break;
   case '2':
   SPDR = data.b[2];
   break;
   case '3':
   SPDR = data.b[3];
   break;
  }
}

void loop() 
{
  Serial.println("loop() starts");
  ypr[0] = -1.1111;
  ypr[1] = -2.2222;
  ypr[2] = -3.3333;

  alt = -4.4444;
  temp = -5.5555;
  Serial.println("loop() ends");
}

The above codes (Master and Slave) are basically modified and adopted from Joseph Roberts' Question on https://stackoverflow.com/questions/20409799/sending-floats-from-an-arduino-to-another-arduino-over-spi-using-a-union , purely for learning purpose only. (I modified it a bit and now similar codes works well for 1 SPI Master and 1 SPI slave Arduino setup).

//Note:Same Slave code uploaded to both the slaves.

OUTPUT:

Slave_01: Start
yaw:-1.1111
pitch: -3.3333
roll:-2.2222
alt: -4.4444
temp: -5.5555
Slave_01: End
Slave_02: Start
yaw:0.0000
pitch: 0.0000
roll:-2.2222
alt: 0.0000
temp: 0.0000
Slave_02: End
Slave_01: Start
yaw:-1.1111
pitch: -3.3333
roll:-2.2222
alt: -4.4444
temp: -5.5555
Slave_01: End
Slave_02: Start
yaw:0.0000
pitch: 0.0000
roll:0.0000
alt: 0.0000
temp: 0.0000
Slave_02: End
Slave_01: Start
yaw:-1.1111
pitch: -3.3333
roll:-2.2222
alt: -4.4444
temp: -5.5555
Slave_01: End
Slave_02: Start
yaw:0.0000
pitch: 0.0000
roll:0.0000
alt: ovf
temp: 0.0000
Slave_02: End
Slave_01: Start
yaw:-1.1111
pitch: -3.3333
roll:-2.2222
alt: -4.4444
temp: -5.5555
Slave_01: End
Slave_02: Start
yaw:0.0000
pitch: 0.0000
roll:0.0000
alt: 0.0000
temp: ovf
Slave_02: End

As we can see from output ,I got output from one of the slave only (Arduino_2:Slave_1) ,the other gave unreliable/garbage output .That is the problem ,I don't get it where the zeros for 2nd Slave comes from ?And how to correct it.Did I missed something ?

Even the page(http://www.gammon.com.au/spi) by Nick Gammon on SPI ,lacks details on Multiple Slave Arduino SPI connection (Although It is really a good place to start with SPI on Arduino, no offense ).I know my Question is similar to Slaving multiple Arduinos via SPI ,but still the answer there doesn't helps much. I almost spend entire Night searching for the solution.

I even tried things like changing the SS for the Slaves ,but still only Arduino_2 gave the correct results and Arduino_3 does not.

And yes ,Arduino_3 is not damaged (It works well in 1master_1slave setup). And all the Arduinos has common GND .

Any constructive criticisms are also welcomed.

Warm Regards

SV

3
  • Hi , this is my first post/question to the forum ,so please bear with me If I lacked some important details(if any) in the Above Question.
    – user41242
    Commented Dec 28, 2017 at 3:35
  • why don't you get the setup to reliably transfer a single byte before you try sending an array?
    – jsotola
    Commented Dec 28, 2017 at 4:21
  • Please can you show your wiring of the two slave setup?
    – Majenko
    Commented Dec 28, 2017 at 9:23

1 Answer 1

1

I know this item is quite old, and I'm also trying to implement multiple Arduino SPI slaves, and looking at all documentations, my understanding is that the SS is not automatically managed in the slave Arduinos. From that, unsure about the wiring of your 1 master/2 slaves Arduinos that can alter the results as shown above, it looks to me your slave code does not manage the SS from two aspects :

1 - I don't see when you identify in your ISR reception procedure if the applicable slave is enabled ( aren't both modules processing the message all the time in this configuration, I suspect they both do )

2 - Also about the SS event management in the slave module, pinMode(MISO, OUTPUT); should only be set when SS is low, otherwise you may have faulty signal with two slaves having MISO as outputs. My understanding is that only one slave at a time should have it as an output ( hence my question about wiring )

Hope it helps,

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.