Go Down

Topic: Communication between 3 or more Arduinos with SPI (Read 1 time) previous topic - next topic

Muchael

Oct 29, 2012, 08:55 pm Last Edit: Oct 30, 2012, 03:08 pm by Muchael Reason: 1
Hi,
I need to communicate  more than 2 Arduinos with SPI.
I connected them this way:



I wrote the following code for receive double on master:

Code: [Select]
#include <SPI.h>

const int SS1 = 8;
const int SS2 = 9;
double valor;
byte* pvalor;
byte slave = 0;

void setup() {
 // set the SS1 as an output:
 pinMode (SS1, OUTPUT);
 pinMode (SS2, OUTPUT);
  // Begin sending data to Slave 1
 digitalWrite(SS1,LOW);
 digitalWrite(SS2,HIGH);
 // initialize SPI:
 SPI.begin();
 Serial.begin (57600);   // debugging
 
 pvalor = (byte *) &valor;
}

void loop() {
 
 SPI.transfer(0x0F);
 for (int i = 0; i < 4; i++) {
   pvalor[i] = SPI.transfer(i);
   delay(100);
 }
 delay(500);
 Serial.println(valor);
 
 i++;
 
 if ((i % 10) == 0) {
   slave = (slave + 1) % 2;
   switch (slave) {
     case 0:
       digitalWrite(SS2,HIGH);
       delay(1000);
       digitalWrite(SS1,LOW);
       break;
     case 1:
       digitalWrite(SS1,HIGH);
       delay(1000);
       digitalWrite(SS2,LOW);
       break;
   }
 }
}


and for slaves:

Code: [Select]
#include <SPI.h>
// Definition of interrupt names
#include < avr/io.h >
#include < avr/interrupt.h >

int sensePin = 2;
double valor = 5000;
byte* pvalor;
boolean interrupt = false;
int led = 9;

void setup (void)
{
 Serial.begin (57600);   // debugging

 // read from the sense pin
 pinMode(sensePin, INPUT);
 // have to send on master in, *slave out*
 pinMode(MISO, OUTPUT);
 pinMode(led, OUTPUT);
 digitalWrite(led, LOW);

 pvalor = (byte *) &valor;

}  // end of setup

// SPI interrupt routine
ISR (SPI_STC_vect)
{
 byte c = SPDR;  // grab byte from SPI Data Register
 Serial.print(c);
 Serial.print(" ");
 switch (c) {
   case 0x0F:
     valor = valor + 1.12;
     SPDR = pvalor[0];
     break;
   case 0:
     SPDR = pvalor[1];
     break;
   case 1:
     SPDR = pvalor[2];
     break;  
   case 2:
     SPDR = pvalor[3];
     break;      
 }
}  // end of interrupt routine SPI_STC_vect

void loop (void)
{
 int valor = digitalRead(sensePin);
 if ((valor == HIGH) && (interrupt == true)) {
   digitalWrite(led, LOW);
   
   SPI.detachInterrupt();
   SPI.end();
   interrupt = false;
 } else if ((valor == LOW) && (interrupt == false)) {
   digitalWrite(led, HIGH);
   
   // turn on SPI in slave mode
   SPCR |= _BV(SPE);
   // now turn on interrupts
   SPI.attachInterrupt();
   interrupt = true;
 }
 delay(100);
}  // end of loop


This works fine for communicating 2 arduinos but, when I connect another arduino the master only receive zeros. Anyone know what can be happening?

Nick Gammon

Quote
when I put another arduino


What do you mean by that? How have you wired it all up?

Muchael

Nick, I mean when a connect another Arduino to the bus, now there is a image of how I wired it on the first post.

Graynomad

#3
Oct 30, 2012, 04:15 pm Last Edit: Oct 30, 2012, 04:25 pm by Graynomad Reason: 1
You don't have the slave's SS pins (pin 10) connected. You do have two wires going to pins 2 for some reason but that won't do anything for SPI.

Read up on SPI's use of the SS pin when the chip is a slave.

BTW you can't just hang a LED form a pin straight to GND, you MUST have a current-limiting resistor.

Also I can't really follow your master code but you seem to do X SPI.transfer()s and then dick with SS1 and SS2 after the transfers?? You have to drop SSx, do the transfers then raise SSx.

Is SPI.attachInterrupt(); valid code? It does compile but I can't see any documentation for it. And if it is valid surely it needs a reference to a function as the parameter.

______
Rob
Rob Gray aka the GRAYnomad www.robgray.com

Muchael

Thanks Graynomad, the problem was with the SS pin.
And the SPI.attachInterrupt(); is a valid code. I didn't pass the function as parameter because I'm registering the interrupt this way:  ISR (SPI_STC_vect)

Go Up