Arduino Uno & Mega connected via Serial Peripheral Interface (SPI)

Nikos Mouzakitis
4 min readFeb 17, 2019
Connection of pins in order to transfer messages from Master(Mega) to Slave(Uno).

SPI stands for Serial Peripheral Interface and it is commonly used among micro-controllers and small peripheral devices(for example SD cards, sensors, or shift registers) to communicate with each other.

Asynchronous serial ports( a common serial port with Tx and Rx lines) doesn’t offer any guarantee that both sides are running in the same rate, and no control over when data is sent. Is important to notice that 2 systems always have slightly differences in their ‘clock’ no matter how precisely they are designed.

SPI on the other hands works in a total different way. Is is a synchronous data bus, using separate lines for data and for the “clock”. The clock is used to keep both sides in a perfect sync.

Master-Slave configuration

In SPI, only one side is generating the clock signal, and it is called the master side or simple master. The other side is called slave. There is always one master, as a restriction, but there can exist multiple slaves; usually master is the micro-controller and peripherals hold the slave title for themselves.

When data flow from the master a slave, they are sent in the line MOSI(Master Out-Slave In). In the case that a slave replies and sends a response message back, data are put in another line called MISO(Master In-Slave Out). In the case to achieve a reply from a slave after master’s transmission, master will continue generating clock cycles and receive the data through the MISO line.

Slave Select(SS)

SS is another line, called Slave Select. Just before data are sent to a slave, SS line is brought LOW, and slave is activated. After the required communication concludes its purpose, SS line is made HIGH again. In case of multiple slaves SS line helps to distinguish to whom of the potential slaves to activate.

One can see the implementation of <SPI.h> for Arduino micro-controllers https://www.arduino.cc/en/reference/SPI for more information on how to use it with Arduino.

In the following example code provided, an Arduino Mega(2560) as a master transfer message to an Arduino Uno who is the slave of the SPI communication.

Pin configurations

In both boards we connect the GNDs to achieve common ground, and also Pin 10’s together. Mega’s PIN 50 is connected to Uno’s PIN 12, Mega’s PIN 52 is connected to PIN 13, and Mega’s PIN 51 is connected into Uno’s PIN 11.

Arduino Mega 2560 (Master code)

#include <SPI.h>
uint8_t val;
void setup() {
Serial.begin(115200); //set baud rate to 115200 for usart
digitalWrite(SS, HIGH); // disable Slave Select
SPI.begin();
SPI.setClockDivider(SPI_CLOCK_DIV8);//divide the clock by 8
Serial.println(“Enter characters to transfer”);
}

void loop() {
char c;
val = 251;

while(Serial.available() > 0) {

digitalWrite(SS, LOW); // enable Slave Select
// send test string
c = Serial.read();
SPI.transfer ©;
//SPI.transfer(val);
//Serial.print(c);
delay(60);
digitalWrite(SS, HIGH); // disable Slave Select
}
}

Arduino Uno (slave code)

#include <SPI.h>
char buff [50];
volatile byte indx;
volatile boolean process;

void setup() {
Serial.begin (115200);
pinMode(MISO, OUTPUT); // have to send on master in so it set as output
SPCR |= _BV(SPE); // turn on SPI in slave mode
indx = 0; // buffer empty
process = false;
SPI.attachInterrupt(); // turn on interrupt
}

ISR (SPI_STC_vect) {// SPI interrupt routine
//Serial.println(“interrupt”);
char c = SPDR; // read byte from SPI Data Register
//Serial.println(c);
if (indx < sizeof buff) {
buff [indx++] = c; // save data in the next index in the array buff
//Serial.println(“written buffer”);
//if ( (c == ‘\r’) || (c == ‘\n’) || (c==’\0') ) //check for the end of the word
process = true;
}
}

void loop(){
if (process) {
//Serial.println(“SPI reception “);
process = false; //reset the process
//Serial.print(“index “);
//Serial.println(indx);
Serial.print(buff); //print the array on serial monitor
indx= 0; //reset button to zero
}

}

We can see that in the slave we have an interrupt attached, so whenever the SS line for the slave is activated, interrupt runs and collect’s each byte master is transmitting.

Inspecting the output by opening the serials and transferring some messages.

--

--

Nikos Mouzakitis

Graduate of Mathematics Department in University of Aegean, Currently Computer Engineer undergrad.