Controlling an SPI device with the Raspberry Pi

The Raspberry Pi has a Broadcom BCM 2835 chip allowing it to interface with SPI devices on its GPIO pins. There are two chip select pins meaning that the Pi can control two devices simultaneously.

P1 Header Pin Function
19 MOSI – master output slave input
21 MISO – master input slave output
23 SCLK – clock
24 CE0 – chip enable 0
26 CE1 – chip enable 1

Step 1: Enable SPI on the Raspberry Pi

  1. In your Pi’s terminal, run
    sudo raspi-config
  2. Go to Advanced Options > SPI
  3. Choose “Yes” for both questions then select Finish to exit raspi-config
  4. Either reboot your Pi or run this command to load the kernel module
    sudo modprobe spi-bcm2708

Step 2: Install spidev

Spidev is a python module that allows us to interface with the Pi’s SPI bus.Watch movie online The Transporter Refueled (2015)

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install python-dev python3-dev
cd ~
git clone
cd py-spidev
sudo make install

Step 3: Python script

Finally, we can write and run a python script to control the SPI device.

  1. Create a file called in your favorite editor
    import spidev
    import time
    spi = spidev.SpiDev(), 0)
    spi.max_speed_hz = 7629
    # Split an integer input into a two byte array to send via SPI
    def write_pot(input):
        msb = input >> 8
        lsb = input & 0xFF
        spi.xfer([msb, lsb])
    # Repeatedly switch a MCP4151 digital pot off then on
    while True:
  2. Make the file executable and run it
    chmod +x
    sudo ./

Notes on spidev

Unless the spi.max_speed_hz field is a value accepted by the driver, the script will fail when you run it. The field can be set to these values on the raspberry pi:

Speed spi.max_speed_hz value
125.0 MHz 125000000
62.5 MHz 62500000
31.2 MHz 31200000
15.6 MHz 15600000
7.8 MHz 7800000
3.9 MHz 3900000
1953 kHz 1953000
976 kHz 976000
488 kHz 488000
244 kHz 244000
122 kHz 122000
61 kHz 61000
30.5 kHz 30500
15.2 kHz 15200
7629 Hz 7629

Two SPI devices can be controlled in python by creating two SpiDev objects, one for each device.

spi = spidev.SpiDev(), 0)
spi.max_speed_hz = 976000

spi2 = spidev.SpiDev(), 1)
spi2.max_speed_hz = 976000

About Takaitra

Matthew is a software engineer for Amazon's Cloud Drive team working with various technologies including web services, React Native and Android. His interests include motorcycling, camping, photography, small electronics and traveling. He lives in Seattle, Washington with his beautiful wife and two children.

12 thoughts on “Controlling an SPI device with the Raspberry Pi

  1. Thank you for this. I have a programmeable potentiometer so will try it later. However, the line:
    sudo apt-get install python-dev python3-dev

    did not allow “spidev” to be installed so I used the following:
    sudo apt-get update
    sudo apt-get upgrade
    sudo apt-get install python-spidev python3-spidev

    I cannot find “spidev” but I am using some coding that imports “spidev” and now the programme works. It is not necessary to store the programme in “py-spidev”.

    Thanks for your help.

  2. Hi, great instructions for someone like me who is in retirement years and just starting out with a rpi zero w. I don’t think I will have a problem getting the spi up and running, but after I get my information of my device, do you have any advise as how I can get that information into a node-red flow? I am trying to get the output of a max6675 thermocouple controller to the input of a nice gauge for showing the temperature of my kiln.

  3. The middle “2 byte array” part confused me but for anyone else who is also confused here’s an explanation:
    lets say we want to send the number 770 to the device (1100000010). The info needs to be sent in bytes(packages of 8 bits), and since the number is 10 bits long, we need to split it (into “11” and “00000010”).

    To get the first part we need to use the “>>” bitwise operator.”>>” takes an integer and removes bits from that integer from the end as it is represented in binary. So 770>>8 removes the last 8 bits and leaves us with a 3 (11 in binary).

    To get the 2nd part we need to use the “&” bitwise operator to leave us with the last 8 bits of our number. “&” takes two numbers, converts them to binary, compares the two, and outputs a resulting number where both bits are 1 for each position. An easy way to get only the last 8 bits of our number is to compare our number to a number that is 11111111 in binary (255 in integers or FF in hex)(0xFF = 255 in python, as does 0b11111111). So 770 & 0xFF gives us 2 (00000010 or 10 in binary)

    we can then use spi.xfer([3,2]) to send our number

  4. Great little article … thanks, it was helpful. I wasn’t sure how to contact you other than writing this post to inform you of a mistake on your about blurb. Developer is mentioned twice. “a Java EE developer developer at Cargill, … “

Leave a Reply

Your email address will not be published. Required fields are marked *