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 Microcontroller Out Serial 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 Microcontroller In Serial 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/DragonBoard 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 DragonBoard 410c, there's only one CS pin available for the hardware SPI pins - SPI_CS - and you have to use it. (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 1 peripheral 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 SPI_CSSPI_CS 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 SPI_CS. Use whatever chip select pin you define in CircuitPython and just leave the CS pin 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 first!

Parts Used

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

Angled shot of black, square-shaped thermocouple breakout board with a green 2-pin terminal block.
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...
In Stock
Angled shot of a Thermocouple Type-K Glass Braid Insulated wire.
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...
Out of Stock

Because the DragonBoard 410c uses 1.8V logic levels, you will need a logic level converter to interface with most peripherals.

Angled shot of a 4-channel I2C-safe Bi-directional Logic Level Converter.
Because the Arduino (and Basic Stamp) are 5V devices, and most modern sensors, displays, flashcards, and modes are 3.3V-only, many makers find that they need to perform level...
In Stock

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

Angled shot of Premium Male/Male Jumper Wires - 40 x 6 (150mm)
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...
In Stock
Angled shot of half-size solderless breadboard with red and black power lines.
This is a cute, half-size breadboard with 400 tie points, good for small projects. It's 3.25" x 2.2" / 8.3cm x 5.5cm with a standard double-strip in the...
In Stock


  • Connect the DragonBoard Ground pin to the blue ground rail on the breadboard
  • Connect the DragonBoard +5V pin to the red 5V rail on the breadboard.
  • Connect the DragonBoard +1.8V pin to the LV pin on the Logic Level Converter
  • Connect the HV pin on the Logic Level Converter to the MAX3185 3Vo
  • Connect the Ground pin on the Logic Level Converter to the blue ground rail on the breadboard 
  • Connect the Vin pin on the MAX31855 to the red 5V rail on the breadboard 
  • Connect the Ground pin on the MAX31855 to the blue ground rail on the breadboard 
  • Connect the B1 pin on the Logic Level Converter to the MAX31855 DO
  • Connect the B2 pin on the Logic Level Converter to the MAX31855 CS
  • Connect the B3 pin on the Logic Level Converter to the MAX31855 CLK
  • Connect the DragonBoard SPI MISO to the A1 pin on the Logic Level Converter
  • Connect the DragonBoard GPIO 12 to the A2 pin on the Logic Level Converter
  • Connect the DragonBoard SPI CLK to the A3 pin on the Logic Level Converter
The DragonBoard 410c pin layout is different than Raspberry Pi and uses 1.8 Volt Logic Levels. Running with anything high could destroy your board.

Double-check you have the right wires connected to the right location, it can be tough to keep track of Header 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

sudo 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:

sudo 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:

# SPDX-FileCopyrightText: 2021 ladyada for Adafruit Industries
# SPDX-License-Identifier: MIT

import time
import board
import digitalio
import adafruit_max31855

spi = board.SPI()
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))

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

Change the line that says

cs = digitalio.DigitalInOut(board.D5)


cs = digitalio.DigitalInOut(board.GPIO_12)

Then in your command line run

sudo 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


This guide was first published on Jun 28, 2019. It was last updated on Jul 17, 2024.

This page (SPI Sensors & Devices) was last updated on Jul 16, 2024.

Text editor powered by tinymce.