Arduino UNO-Arduino Mega SPI communication

Hi all,

I want to ask that whether we can communicate with Arduino UNO and arduino Mega using SPI communication to configure one as master and another as slave (or vice-versa).If so, please provide a simple code or links (like sending a character or string) between two arduinos using SPI. Is the two boards' SPI pins compatible with each other? I am quite new to this environment.

Regards,
Sreejithrn

I want to ask that whether we can communicate with Arduino UNO and arduino Mega using SPI communication to configure one as master and another as slave (or vice-versa).If so, please provide a simple code or links (like sending a character or string) between two arduinos using SPI.

A lot of information about this topic is found on Nick Gammon's SPI page.

Is the two boards' SPI pins compatible with each other?

Yes and no, depends on what you think "pin compatible" means. For the ICSP pins they are compatible, for the corresponding digitial IOs not.

@pylon:

By mentioning pin compatibility I refer to the following:

Arduino Mega SPI digital I/O pins:

MISO-pin 50
MOSI-pin 51
SCK- Pin 52
SS- pin 53

Arduino Uno SPI digital I/O pins:

MISO-pin11
MOSI-pin12
SCK-pin13
SS-pin10

Do these digital pins show compatibility with each other? Or with only ICSP pins we can achieve SPI communication betweemn UNO and Mega?

1. The Pin-out diagram of the ICSP Connector of MEGA is:

The SPI signals are clearly indicated except the SS/-signal which we need for the MEGA to be selected as Slave by the UNO. The correspondences among these signals and the DPins are:

SS/ (absent in ICSP Connector) <-----------------> 53 (PB0)
SCK <-----------------> 52 (PB1)
MOSI <-----------------> 51 (PB2)
MISO <-----------------> 50 (PB3)

2. The Pin-out diagram of the ICSP Connector of UNO is:

The SPI signals are clearly indicated except the SS/-signal which we will be used to select the SLave (the MEGA). The correspondences among these signals and the DPins are:

SS/ (absent in ICSP Connector) <-----------------> 10 (PB2)
MOSI <-----------------> 11 (PB3)
MISO <-----------------> 12 (PB4)
sck <-----------------> 13 (PB5)

3. My preferred connection between UNO (Master) and MEGA (Slave)

The above diagram indicates that the SPI is a Circular Buffer System. A data byte is shifted out bit-by-bit from Master-SPDR Register response to SCK; the shifted bits also enter bit-by-bit into the Slave-SPDR Register. The present content of the Slave-SPDR Register also shifted out bit-by-bit and enters into Master-SPDR Register.

When the Master begins to shift out data, the SPIF-bit (SPI Flag bit) of SPSR Register becomes LOW, and it remains LOW until all the data bits have been shifted out. At the end of complete shift of all the data bits, the SPIF bit assumes LH (HIGH) state. The Master can continuously monitor this flag bit (SPIF) to determine that data transmission is complete; it can now initiate the transmission of next data byte.

At the Slave side, the Slave waits until all data bit have arrived in its SPDR Register. The Slave knows it by continuously monitoring the SPIF flag bit of the SPSR Register. When SPIF bit found LH, the Slave reads the data from SPDR Register and keeps it in a variable. The Slave, if wishes, can use the interrupt strategy to know the readiness of data in the SPDR register.

There are 3 Registers inside SPI Interface:
SPCR : SPI Control register. It is used to initialize the SPI Port.
SPSR : SPI Status Register. It is used to know the readiness of data.
SPDR : SPI data Register. It is used to exchange data.

5. Test Codes.
Send one byte data (0x23) from the Master-UNO; receive it by Slave-MEGA and show on Serial Moniotr.

Master-UNO Codes:

#include<SPI.h>
#define SS 10  //Slave Select Line

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

  SPI.begin();        //PB2 - PB4 are converted to SS/(OUT-H), MOSI(OUT-L), MISO(IN), SCK(OUT-L)
  bitSet(SPCR, 4);    //UNO_1 is Master
  SPI.setBitOrder(MSBFIRST);  //bit transmission order
  SPI.setDataMode(SPI_MODE1); //CPOL and CPHA (Clock polarity; Clock phase)
  SPI.setClockDivider(SPI_CLOCK_DIV128); //data rate = fosc/128 = 125 kbit
  bitClear(SPCR, 7);  //local SPI interrupt is disable

  digitalWrite(SS, LOW);  //must be LOW to select the slave

  SPI.transfer(0x23);

  SPI.end();
}

void loop()
{

}

Slave-MEGA Codes:

#include<SPI.h>
#define SS 53

void setup()
{
  Serial.begin(9600);
  SPI.begin();                //PB2 - PB4 are converted to SS/, MOSI, MISO, SCK
  pinMode(SS, INPUT);
  bitClear(SPCR, 4);          //UNO-2 is Slave
  SPI.setBitOrder(MSBFIRST);  //bit transmission order
  SPI.setDataMode(SPI_MODE1); //
  SPI.setClockDivider(SPI_CLOCK_DIV128);  //data rate = fosc/128 = 125 kbit
  bitClear(SPCR, 7);                      //local SPI interrupt is disable

  
  while (bitRead(SPSR, 7) != HIGH)  //checkibg SPIF bit for LH condition
    ;
  byte x = SPDR;                 //SPIF falg get cleared
  Serial.print(x, HEX);          /Serial Moniotr should show: 23
  
  SPI.end();
}

void loop()
{

}

(a) Upload the codes in the respective Arduino.
(b) Press and hold RESET buttons of both Arduinos.
(c) Release the RESET button of MEGA.
(d) Bring in the Serial Monitor (SM2) of MEGA (the Slave).
(e) Release the RESET button of UNO (the Master).
(f) Check that the data byte 23 has appeared on SM2.

@GolamMostafa:

Appreciate a lot for the response!!!

“A lot of information about this topic is found on Nick Gammon’s SPI page.”

Do you think with given preferred connection between arduino UNO and MEGA SPI communication can be achieved?

I tried Nick Gammon SPI code tutorial as master-slave configuration with above connection but it didn’t work quite so well.

Since clock frequency of both boards are same (16 MHz), do we want to alter any SPI configuration settings before connecting these two boards?

Regards,
Sreejithrn

… in continuation of Post#3 of mine, please execute the following codes (tested at my setup) and report your results:

Master-UNO Codes:

#include<SPI.h>
byte myData[4] = {0x98, 0x45, 0x7A, 0xCD}; //to be transfeered to slave
#define SS 10  //Slave Select Line

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

  SPI.begin();        //PB2 - PB4 are converted to SS/(OUT-H), MOSI(OUT-L), MISO(IN), SCK(OUT-L)
  bitSet(SPCR, 4);    //UNO_1 is Master
  SPI.setBitOrder(MSBFIRST);  //bit transmission order
  SPI.setDataMode(SPI_MODE1); //CPOL and CPHA (Clock polarity; Clock phase)
  SPI.setClockDivider(SPI_CLOCK_DIV128); //data rate = fosc/128 = 125 kbit
  bitClear(SPCR, 7);  //local SPI interrupt is disable

  digitalWrite(SS, LOW);  //must be LOW to select the slave

  for (int i = 0; i < 4; i++)
  {
    SPDR = myData[i];
    while (bitRead(SPSR, 7) != HIGH)//SPIF is cleared when SPSR is read
      ;
  }


  SPI.end();
}

void loop()
{

}

BTW:
If you wish, you can replace the following three lines of instructions by this single line SPI.transfer(myData[i});

SPDR = myData[i];
while (bitRead(SPSR, 7) != HIGH)//SPIF is cleared when SPSR is read
  ;

//-------------------------------------------------------------------------------------------------------
Slave-MEGA Codes:

#include<SPI.h>
#define SS 53

byte myData[4];

void setup()
{
  Serial.begin(9600);
  SPI.begin();                //PB2 - PB4 are converted to SS/, MOSI, MISO, SCK
  pinMode(SS, INPUT);
  bitClear(SPCR, 4);          //UNO-2 is Slave
  SPI.setBitOrder(MSBFIRST);  //bit transmission order
  SPI.setDataMode(SPI_MODE1); //
  SPI.setClockDivider(SPI_CLOCK_DIV128);  //data rate = fosc/128 = 125 kbit
  bitClear(SPCR, 7);                      //local SPI interrupt is disable

  for (int i = 0; i < 4; i++)
  {
    while (bitRead(SPSR, 7) != HIGH)  //checkibg SPIF bit for LH condition
      ;
    myData[i] = SPDR;                 //SPIF falg get cleared
    Serial.print(myData[i], HEX);
  }

  Serial.println();
  SPI.end();
}

void loop()
{

}

(a) Upload the codes in the respective Arduino.
(b) Press and hold RESET buttons of both Arduinos.
(c) Release the RESET button of MEGA.
(d) Bring in the Serial Monitor (SM2) of MEGA (the Slave).
(e) Release the RESET button of UNO (the Master).
(f) Check that the data bytes 98457ACD has appeared on SM2.

Arduino Mega SPI digital I/O pins:

MISO-pin 50
MOSI-pin 51
SCK- Pin 52
SS- pin 53

Arduino Uno SPI digital I/O pins:

MISO-pin11
MOSI-pin12
SCK-pin13
SS-pin10

Do these digital pins show compatibility with each other? Or with only ICSP pins we can achieve SPI communication betweemn UNO and Mega?

The ICSP pins of both the UNO and the Mega are connected to the corresponding SPI pins you mentioned above. And yes, these pins are electrically compatible, both use the same voltage level and the use the same interface type.

Do you think with given preferred connection between arduino UNO and MEGA SPI communication can be achieved?

Yes, I’m quite sure it can.

I tried Nick Gammon SPI code tutorial as master-slave configuration with above connection but it didn’t work quite so well.

Please tell us how you connected the two boards (wiring diagram)! And tell us what problems you got, if you got error messages, post these.

N.B.
#2
Uno MISO and MOSI pins wrong way round - MISO is pin 12; MOSI is pin 11

Information of Post#7 agrees with realities:
spi328x.png

spi328x.png