SPI Sensors & Devices

SPI is less popular than I2C but still you'll see lots of sensors and chips use it. Unlike I2C, you don't have everything share two wires. Instead, there's three shared wires (clock, data in, data out) and then a unique 'chip select' line for each chip.

The nice thing about SPI is you can have as many chips as you like, even the same kind, all share the three SPI wires, as long as each one has a unique chip select pin.

The formal/technical names for the 4 pins used are:

  • SPI clock - called SCLK, SCK or CLK
  • SPI data out - called MOSI for Master Out Slave In. This is the wire that takes data from the Linux computer to the sensor/chip. Sometimes marked SDI or DI on chips
  • SPI data in - called MISO for Master In Slave Out. This is the wire that takes data to the Linux computer from the sensor/chip. Sometimes marked SDO or DO on chips
  • SPI chip select - called CS or CE

Remember, connect all SCK, MOSI and MISO pins together (unless there's some specific reason/instruction not to) and a unique CS pin for each device.

WARNING! SPI on Linux/Raspberry PI WARNING!

SPI on microcontrollers is fairly simple, you have an SPI peripheral and you can transfer data on it with some low level command. Its 'your job' as a programmer to control the CS lines with a GPIO. That's how CircuitPython is structured as well. busio does just the SPI transmit/receive part and busdevice handles the chip select pin as well.

Linux, on the other hand, doesn't let you send data to SPI without a CS line, and the CS lines are fixed in hardware as well. For example on the Raspberry Pi, there's only two CS pins available for the hardware SPI pins - CE0 and CE1 - and you have to use them. (In theory there's an ioctl option called no_cs but this does not actually work)

The upshot here is - to let you use more than 2 peripherals on SPI, we decided to let you use any CS pins you like, CircuitPython will toggle it the way you expect. But when we transfer SPI data we always tell the kernel to use CE0. CE0 will toggle like a CS pin, but if we leave it disconnected, its no big deal

The upshot here is basically never connect anything to CE0 (or CE1 for that matter). Use whatever chip select pin you define in CircuitPython and just leave the CE pins alone, it will toggle as if it is the chip select line, completely on its own, so you shouldn't try to use it as a digital input/output/whatever.

Don't forget you have to enable SPI with raspi-config!

Using the Second SPI Port

The Raspberry Pi has a 'main' SPI port, but not a lot of people know there's a second one too! This is handy if you are using the main SPI port for a PiTFT or other kernel-driven device. You can enable this SPI #1 by adding

dtoverlay=spi1-3cs

to the bottom of /boot/config.txt and rebooting. You'll then see the addition of some /dev/spidev1.x devices.

Here's the wiring for SPI #1:

  • SCK_1 on GPIO #21
  • MOSI_1 on GPIO #20
  • MISO_1 on GPIO #19
  • SPI #1 CS0 on GPIO 18
  • SPI #1 CS1 on GPIO 17
  • SPI #1 CS2 on GPIO 16

like the main SPI, we'll use CE0 as our default but don't connect to it! Use any other pin and leave that one unused. Then update your scripts to use

spi = busio.SPI(board.SCK_1, MOSI=board.MOSI_1, MISO=board.MISO_1)

Parts Used

OK now that we've gone thru the warning, lets wire up an SPI MAX31855 thermocouple sensor, this particular device doesn't have a MOSI pin so we'll not connect it.

Thermocouple Amplifier MAX31855 breakout board (MAX6675 upgrade)

PRODUCT ID: 269
Thermocouples are very sensitive, requiring a good amplifier with a cold-compensation reference. The MAX31855K does everything for you, and can be easily interfaced with any...
$14.95
IN STOCK

Thermocouple Type-K Glass Braid Insulated

PRODUCT ID: 270
Thermocouples are best used for measuring temperatures that can go above 100 °C. This is a bare wires bead-probe which can measure air or surface temperatures. Most inexpensive...
$9.95
IN STOCK

We recommend using a breadboard and some female-male wires.

Premium Female/Male 'Extension' Jumper Wires - 40 x 6" (150mm)

PRODUCT ID: 826
Handy for making wire harnesses or jumpering between headers on PCB's. These premium jumper wires are 6" (150mm) long and come in a 'strip' of 40 (4 pieces of each of ten rainbow...
$3.95
IN STOCK

You can use a Cobbler to make this a little easier, the pins are then labeled!

Adafruit Pi Cobbler + Kit- Breakout Cable for Pi B+/A+/Pi 2/Pi 3

PRODUCT ID: 1990
The Raspberry Pi B+ has landed on the Maker World like a 40-GPIO pinned, quad-USB ported, credit card sized bomb of DIY joy. And while you can use most of our great Model B accessories...
OUT OF STOCK

Assembled Pi T-Cobbler Plus - GPIO Breakout

PRODUCT ID: 2028
This is the assembled version of the Pi T-Cobbler Plus.  It only works with the Raspberry Pi Model Zero, A+, B+, Pi 2,Pi 3! (Any Pi with 2x20 connector)
$7.95
IN STOCK

Wiring

  • Connect the Raspberry Pi 3.3V power pin to Vin
  • Connect the Raspberry Pi GND pin to GND
  • Connect the Pi SCLK pin to the MAX31855 CLK
  • Connect the Pi MISO pin to to the MAX31855 DO
  • Connect the Pi GPIO 5 pin to to the MAX31855 CS

Double-check you have the right wires connected to the right location, it can be tough to keep track of Pi pins as there are forty of them!

Install the CircuitPython MAX31855 Library

OK onto the good stuff, you can now install the Adafruit MAX31855 CircuitPython library.

As of this writing, not all libraries are up on PyPI so you may want to search before trying to install. Look for circuitpython and then the driver you want.

Once you know the name, install it with

pip3 install adafruit-circuitpython-max31855

You'll notice we also installed a few other dependancies called spidev, adafruit-pureio, adafruit-circuitpython-busdevice and more. This is a great thing about pip, if you have other required libraries they'll get installed too!

We also recommend an adafruit-blinka update in case we've fixed bugs:

pip3 install --upgrade adafruit_blinka

Run that code!

The finish line is right up ahead. You can now run one of the (many in some cases) example scripts we've written for you.

Check out the examples for your library by visiting the repository for the library and looking in the example folder. In this case, it would be https://github.com/adafruit/Adafruit_CircuitPython_MAX31855/tree/master/examples

As of this writing there's only one example. But that's cool, here it is:

import time
import board
import busio
import digitalio
import adafruit_max31855

spi = busio.SPI(board.SCK, MOSI=board.MOSI, MISO=board.MISO)
cs = digitalio.DigitalInOut(board.D5)

max31855 = adafruit_max31855.MAX31855(spi, cs)
while True:
    tempC = max31855.temperature
    tempF = tempC * 9 / 5 + 32
    print('Temperature: {} C {} F '.format(tempC, tempF))
    time.sleep(2.0)

Save this code to your Pi by copying and pasting it into a text file, downloading it directly from the Pi, etc.

Then in your command line run

python3 max31855_simpletest.py

The code will loop with the sensor data until you quit with a Control-C

Make sure you have a K-type thermocouple installed into the sensor breakout or you will get an error like the one below!

That's it! Now if you want to read the documentation on the library, what each function does in depth, visit our readthedocs documentation at

https://circuitpython.readthedocs.io/projects/max31855/en/latest/

This guide was first published on Jun 30, 2018. It was last updated on Jun 30, 2018. This page (SPI Sensors & Devices) was last updated on Aug 22, 2019.