Browse our Blog. You will find multiple applications, solutions, code examples. Navigate using the tag cloud or search using specific criteria

Bus SPI on PLC Arduino from Industrial Shields

Using the Serial Peripheral Interface Bus (SPI)


In this post we will see the SPI bus, one of the communications available in our entire range of Arduino-based PLCs.

The SPI bus is interesting because a wide variety of sensors and commercial devices have an SPI interface as a mean of communication; for example, many Display TFT units use SPI protocol, as well as a wide range of sensors such as thermocouples, temperature sensors or humidity sensors.  

Resultado de imagen de SPI


In the sketch example, we have used an industrial controller Arduino M-Duino 21+, but all of the industrial Arduino PLCs range of Industrial Shields can also be used to perform the same example:

- WiFi & Bluetooth Controller Family

- 20 I/Os Controller Family 

- Ethernet Controller Family

- GPRS / GSM Controller Family

SPI protocol

The SPI (Serial Peripheral Interface) bus was developed by Motorola in 1980. It is currently a standard in the world of electronics and automation.

The SPI bus has a master-slave architecture.

The master device can initiate communication with one or more slave devices, and send or receive data from them. Slave devices cannot initiate communication, nor exchange data with each other directly. 

Data communication between masters and slaves takes place on two independent lines, one from the master to the slaves, and another from the slaves to the master. Therefore the communication is Full Duplex, that is, the master can send and receive data simultaneously.

Another feature of SPI is that it is synchronous bus. The master device provides a clock signal, which keeps all devices synchronized. This reduces the complexity of the system compared to asynchronous systems. 

Then, we need a minimum of 3 signals for the transmission of data through SPI: one of the lines to send data to the slaves, another line to receive data from the different slaves and the clock signal to synchronize the entire bus. In addition, an additional SS (Slave Select) line is required for each connected slave device, to select the device with which the communication is to be made:

  • MOSI (Master-out, slave-in) Master to Slave communication
  • MISO (Master-in, slave-out) Slave to Master communication.
  • SCK (Clock) Clock signal generated by the master
  • SS (Slave Select) It selects the device with which communication is to be made


      Typical SPI wiring

 Advantages and Disadvantages



  • Full Duplex Communication.

  • Higher transmission speed than with I²C or SMBus.

  • Flexible protocol in which you can have absolute control over the transmitted bits.

  • It is not limited to 8-bit block transfer.

  • Choice of bit frame size, its meaning and purpose.

  • Its hardware implementation is extremely simple.

  • It consumes less energy than I²C or SMBus because it has fewer circuits (including pull-up resistors) and these are simpler.

  • No arbitration or failure response mechanism is necessary.

  • Client devices use the clock sent, therefore they do not need their own clock.

  • It is not mandatory to implement a transceiver (transmitter and receiver): a connected device can be configured to only send, only receive or both options at the same time.

  • It uses much less terminals on each chip / connector than an equivalent parallel interface.

  • At most, a single specific signal is required for each user (SS signal); the other signals can be shared.


  • It consumes more pins of each chip than I²C, even in the 3-wire variant.

  • The addressing is done through specific lines (out-of-band signaling) unlike what happens in I²C where each chip is selected by a 7-bit address that is sent by the same bus lines.

  • There is no hardware flow control.

  • There is no sign of assent. The server could be sending information without no customers connected and would not notice anything.

  • It does not easily allow having multiple servers connected to the bus.

  • It only works over short distances unlike, for example, RS-232 or RS-485.

Typical SPI connections

Option 1) If it is a connection where few slaves have to be connected, the following connection scheme is used:

An additional SS (Slave Select) line is required for each slave device connected, to select the device with which communication have to be made. 

Option 2) This previous connection has the disadvantage of requiring a line for each slave device. In case of having many slave devices, this may not be practical, so it is possible to adopt a cascade connection, where each slave transmits data to the next one:

On the other hand, in this configuration the information must reach all the slaves so that the communication is terminated, that is why, in general, the bus response speed is lower than in the first configuration.


Every Industrial Shields programmable logic controller has the SO, SI and SCK pins. C
heck the User Manual of your industrial PLC version to see where this pins are located. Also check the Pinout chapter of the User Manual to see how many pins can be used as SS (Slave Select). Here you have the M-Duino 21+ PLC controller example: 


To use the SPI port on Arduino the IDE Standard provides the library "SPI.h" that contains the functions needed to control the integrated SPI hardware.

Basic SPI functions: 

SPI.begin();            // Starts the SPI bus
SPI.transfer(c);        // Send a byte
SPI.attachInterrupt(); // Activate the interrupt to receive data

To change the order of the sent bits, we have the setBitOrder function:

setBitOrder (LSBFIRST); //Least Significant bit first 
setBitOrder (MSBFIRST); //Most Significant bit first

To change the polarity and the phase of the clock, we have the SPI.setDataMode function:

setDataMode (SPI_MODE0); // clock normally LOW, rising edge sampling 
setDataMode (SPI_MODE1); // clock normally LOW, flank sampling lowered
setDataMode (SPI_MODE2); // clock normally HIGH, rising edge sampling
setDataMode (SPI_MODE3); // clock normally HIGH, flank sampling lowered

Finally, we can change the bus speed with the SPI.setClockDivider () function divisors from 2 to 128. The bus frequency will be the clock speed divided by the chosen divisor.

setClockDivider (SPI_CLOCK_DIV2); // 8 MHz (considering a 16 MHz model)
setClockDivider (SPI_CLOCK_DIV4); // 4 MHz
setClockDivider (SPI_CLOCK_DIV8); // 2 MHz
setClockDivider (SPI_CLOCK_DIV16); // 1 MHz
setClockDivider (SPI_CLOCK_DIV32); // 500 KHz
setClockDivider (SPI_CLOCK_DIV64); // 250 KHz
setClockDivider (SPI_CLOCK_DIV128); // 125 KHz

However, these functions are obsolete since the Arduino version 1.6.0., The beginTransaction function is preferred, as the following example shows.

SPI.beginTransaction (SPISettings (2000000, MSBFIRST, SPI_MODE0)); // 2 MHz clock, MSB first, mode 0

However, being the specific data frame of each device, more often than not, we do not use these functions directly, and our use of the SPI bus is carried out indirectly through the library of the component.

You can find SPI communication examples on the Arduino IDE as you can see in the following image: 


Do you want more information?

Just fill the form!

Tell me more!