SPI Between 'Arduinos'

Hello,

Never used SPI before between Arduino's before, have only used I2C.

Basically I have a atMega2560 talking over SPI to 3x atTiny84's. Ignore the type of micros, I just am trying to get my head around the code to do what I want.

Basically, I want the 2560 to be the master, and to request data from each of the atTinys. Each atTiny has a seperate Chip Select going to it from the Master.

Looking at the SPI library, http://arduino.cc/en/Reference/SPI , there doesnt seem to be much in there.... So basically after I set up who is master and who is slave, set the speed etc, is it just a case of doing the transfer() ?

I am searching more, but thought I would post incase someone knows how to do this. I am just wanting to set up a quick test program to prove the point. atTiny does stuff and then when requested from the 2560, it will give up a value. Job done.

Any help would be very handy.

Thanks

Example code here:

http://www.gammon.com.au/spi

Thanks Nick

Code doesnt compile in the atTiny84 (I found another post of yours I stole some test code from).

I put the core for the atTiny84 that I found on the forum from CodingBadly, however I am not sure if SPI is supported yet or not.

Damn.

The AtTiny25/45/85 seems to support SPI. Not sure about the 84.

I get these errors

In file included from Brick_Tiny_Functions.cpp:1: D:\Projects\Arduino-0022\libraries\SPI/SPI.h: In static member function 'static byte SPIClass::transfer(byte)': D:\Projects\Arduino-0022\libraries\SPI/SPI.h:56: error: 'SPDR' was not declared in this scope D:\Projects\Arduino-0022\libraries\SPI/SPI.h:57: error: 'SPSR' was not declared in this scope D:\Projects\Arduino-0022\libraries\SPI/SPI.h:57: error: 'SPIF' was not declared in this scope D:\Projects\Arduino-0022\libraries\SPI/SPI.h: In static member function 'static void SPIClass::attachInterrupt()': D:\Projects\Arduino-0022\libraries\SPI/SPI.h:63: error: 'SPCR' was not declared in this scope D:\Projects\Arduino-0022\libraries\SPI/SPI.h:63: error: 'SPIE' was not declared in this scope D:\Projects\Arduino-0022\libraries\SPI/SPI.h: In static member function 'static void SPIClass::detachInterrupt()': D:\Projects\Arduino-0022\libraries\SPI/SPI.h:67: error: 'SPCR' was not declared in this scope D:\Projects\Arduino-0022\libraries\SPI/SPI.h:67: error: 'SPIE' was not declared in this scope Brick_Tiny_Functions.cpp: In function 'void setup()': Brick_Tiny_Functions:8: error: 'SPCR' was not declared in this scope Brick_Tiny_Functions:8: error: 'SPE' was not declared in this scope Brick_Tiny_Functions.cpp: In function 'void loop()': Brick_Tiny_Functions:16: error: 'SPDR' was not declared in this scope Brick_Tiny_Functions.cpp: In function 'byte slave()': Brick_Tiny_Functions:22: error: 'SPSR' was not declared in this scope Brick_Tiny_Functions:22: error: 'SPIF' was not declared in this scope Brick_Tiny_Functions:23: error: 'SPDR' was not declared in this scope

Hmm. Looks like you might have to do a bit more work. I don't have an AtTiny84 to test on. Try reading this:

http://atmel.com/dyn/resources/prod_documents/doc2582.pdf

Success :)

Just some test code, here is the slave.

#include "pins_arduino.h"

byte Command;

void setup() 
{
  pinMode(MISO, OUTPUT);
  USICR = (1 << USIWM0) | (1 << USICS1);
}

void loop() 
{
  Command = slave();  //receive data from Master
  if(Command == 10)
  {
    USIDR = 5;  //Generic reply of 5
    USISR = (1 << USIOIF);
  }
  else
  {  
    USIDR = 7;  //Generic reply of 7
    USISR = (1 << USIOIF);
  }
}

byte slave()
{ 
  while (!(USISR & (1 << USIOIF))); 
  return USIDR;
}

Cool!

Ha - yeah. Now I just need to fully understand why it is working and how to make it better!

These are going to be doing high speed counting so I need to make sure that what I have there isnt blocking, which I am thinking it might be with that while loop...

Yes it looks like it would block. Now you need to get an interrupt out of it. ;)

Your example you posted above in the link does interrupts does it... I havent looked again.

hmm

It mentions interrupts. I don't see any code there.

Care of GrayNomad - Thanks Rob!

#include "pins_arduino.h"

byte Command;

void setup() 
{
  pinMode(MISO, OUTPUT);
   USICR = (1 << USIWM0) | (1 << USICS1) | (1 << USIOIE);
}

ISR (USI_OVF_vect) 
{  

  Command = USIDR;

  if(Command == 10)
  {
    USIDR = 5; //Generic reply of 5
    USISR = (1 << USIOIF);
  }
  else
  {  
    USIDR = 7; //Generic reply of 7
    USISR = (1 << USIOIF);
  }  
}

void loop() 
{
}

Better would be:

ISR (USI_OVF_vect) 
{  

  Command = USIDR;

  if(Command == 10)
  {
    USIDR = 5; //Generic reply of 5
  }
  else
  {  
    USIDR = 7; //Generic reply of 7
  }  

  USISR = 1 << USIOIF;

}

Otherwise you don't clear the interrupt bit if you don't match the "if". (Although in this case you would, of course).

Also make "byte Command;" volatile, otherwise move it into the ISR.

Good thinking, thanks!

Hi WanaGo,

did you ever get your code working? Im trying to accomplish a quite similar thing and Im stuck somehow.

Best regards, Jan

Sure did

Whats up?

Would you mind sharing your final SPI Slave Code for the Attiny? The code sniplet on the previous page did not work correctly.

If not, maybe you could take a look at http://arduino.cc/forum/index.php/topic,126771.15.html and have a look at my code snipplets. I cant get them to work.

Many thanks in advance, Jan

Code on the last page should work, from memory

Ill do some digging on my hard drive and find the code I got working on both ends

PM me your email, ill flick you my files