SPI communication between 2 UNOs
hi,
i have written codes below. use spi between 2 arduino unos first trial based on nick gammon's tutorial.
i send commands 'i' , 'o' master on serial. slave receives commands on spi. 'i' turns on , led. 'o' turns led off.
i've set protocol spi communitcation:

the code bothers me seems need have "delaymicroseconds (20)" inbetween transfers else things don't work , stop responding!
the spdr register should updated time spi.transfer complete. why need wait 20us before reading data.
and make things more fun, if use serial.print try , debug, work fine!
any ideas why, anyone?
master:
slave:
i have written codes below. use spi between 2 arduino unos first trial based on nick gammon's tutorial.
i send commands 'i' , 'o' master on serial. slave receives commands on spi. 'i' turns on , led. 'o' turns led off.
i've set protocol spi communitcation:
the code bothers me seems need have "delaymicroseconds (20)" inbetween transfers else things don't work , stop responding!
the spdr register should updated time spi.transfer complete. why need wait 20us before reading data.
and make things more fun, if use serial.print try , debug, work fine!

any ideas why, anyone?
master:
code: [select]
#include <spi.h>
volatile char req[9];
volatile uint8_t a, = 0;
byte transferandwait (byte what)
{
byte x = spi.transfer (what);
delaymicroseconds (20); //wait slave process , reply
return x;
}
void setup (void)
{
serial.begin (9600);
digitalwrite(ss, high); // ensure ss stays high now
spi.begin ();
spi.begintransaction(spisettings(4000000, msbfirst, spi_mode0));
serial.println ("ready");
}
void loop (void)
{
uint8_t j;
if (serial.available()) {
req[i] = serial.read();
++i;
}
if (req[i - 1] == ';') {
if (req[0] == 'o') { //turn led off
// enable slave select
digitalwrite(ss, low);
a = transferandwait(0); //start spi comms
//serial.println (string(a,hex));
a = transferandwait('o'); //send command
//serial.println (string(a,hex));
a = transferandwait(0); //end spi comms
if (a == 'o') {
serial.print("led off!");
serial.println (char(a));
}
else {
serial.print("failed! ");
serial.println (string(a, hex));
}
// disable slave select
digitalwrite(ss, high);
}
else if (req[0] == 'i') { //turn led on
// enable slave select
digitalwrite(ss, low);
a = transferandwait(0); //start spi comms
//serial.println (string(a,hex));
a = transferandwait('i'); //send command
//serial.println (string(a,hex));
a = transferandwait(0); //end spi comms
if (a == 'i') {
serial.print("led on!");
serial.println (char(a));
}
else {
serial.print("failed! ");
serial.println (string(a, hex));
}
// disable slave select
digitalwrite(ss, high);
}
i = 0;
}
}
slave:
code: [select]
#define spi_timeout 25
#include <spi.h>
volatile uint8_t start = 0, command = 0;
// spi interrupt routine
isr (spi_stc_vect)
{
byte spi = spdr;
if (spi == 0 && start == 0) { //start of spi comms
if (command != 0xa3) {
start = 1;
spdr = 0xa4; //acknowledge start of comms
}
else {
command = 0;
spdr = 0;
}
}
else if (start > 0) {
if (start == 1) {
start = 2;
command = spi;
}
if (command == 'o') {
digitalwrite(2, low);
command = 0xa3; //end of command
start = 0; //end of comms
spdr = 'o';
}
else if (command == 'i') {
digitalwrite(2, high);
command = 0xa3; //end of command
start = 0; //end of comms
spdr = 'i';
}
else { //reset spi comms
start = 0;
command = 0;
}
}
timeout = micros();
}
void setup (void)
{
pinmode(2, output); //led output
digitalwrite(2, low);
// have send on master in, *slave out*
pinmode(miso, output);
// turn on spi in slave mode
spcr |= _bv(spe);
// turn on interrupts
spcr |= _bv(spie);
spdr = 0; //initialise spi register
} // end of setup
void loop (void)
{
//re-initialise spi variables on timeout
if (spdr != 0 && (micros() - timeout) > spi_timeout) {
start = 0;
command = 0;
spdr = 0;
}
}
edit - gammon says,
quote
otherwise slave doesn't have chance react incoming data , it.how relate problem?
Arduino Forum > Using Arduino > Programming Questions > SPI communication between 2 UNOs
arduino
Comments
Post a Comment