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
- In your Pi’s terminal, run
sudo raspi-config
- Go to Advanced Options > SPI
- Choose “Yes” for both questions then select Finish to exit raspi-config
- 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 https://github.com/doceme/py-spidev.git cd py-spidev make sudo make install
Step 3: Python script
Finally, we can write and run a python script to control the SPI device.
- Create a file called spi-test.py in your favorite editor
#!/usr/bin/python import spidev import time spi = spidev.SpiDev() spi.open(0, 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: write_pot(0x1FF) time.sleep(0.5) write_pot(0x00) time.sleep(0.5)
- Make the file executable and run it
chmod +x spi-test.py sudo ./spi-test.py
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() spi.open(0, 0) spi.max_speed_hz = 976000 spi2 = spidev.SpiDev() spi2.open(0, 1) spi2.max_speed_hz = 976000
25 Comments
Use the command:
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 7629
#for example
spi.readbytes(n)
#Read n bytes from SPI device
Hey Guys! Our Skript is running but.. nothing happens.. we connectet the wires like they should.. but we measure all the time the same resistance.. can anybody help us?
How to read instead of write?
Use the command:
spi = spidev.SpiDev()
spi.open(0, 0)
spi.max_speed_hz = 7629
#for example
spi.readbytes(n)
#Read n bytes from SPI device
best Raspberry Pi SPI faq on the web
spi.open(0, 0)
FileNotFoundError: [Errno 2] No such file or directory
this is the message i get when i run spitest file
i am using mcp3008 for converting my analog values
it was working fine till dec 30 2019 the last time i tested but today it throws up this error whats happening ??
ls /dev/spi*
The “proper” Raspberry Pi Linux SPI driver is currently going through review to allow arbitrary gpios to be used as CS.
Hey! Me too. Have you solved the problem?
Hey guys,
did someone also get an error “invalid syntax” in line 12 (msb = input >> 8)?
Thank you!
I can’t reproduce that error. What version of Python are you running? You can find out via the command ‘python –version’
Hello Guys,
I need help. I have RPi 3B and use Display-O-Tron Hat, but I needed same time used EXPLORE-NFC-WW so I bought this http://rpishop.cz/907-gpio-multiplexovaci-modul.html
Now, I have problem with display. I cant use backlight (lcd work) because I get this error.
Code: Select all
Traceback (most recent call last):
File “bargraph.py”, line 5, in
import dot3k.backlight as backlight
File “/usr/local/lib/python3.5/dist-packages/dot3k/backlight.py”, line 1, in
import sn3218, colorsys, math
File “/usr/lib/python3/dist-packages/sn3218.py”, line 114, in
enable_leds(0b111111111111111111)
File “/usr/lib/python3/dist-packages/sn3218.py”, line 62, in enable_leds
[enable_mask & 0x3F, (enable_mask >> 6) & 0x3F, (enable_mask >> 12) & 0X3F])
OSError: [Errno 121] Remote I/O error
Okey this is problem NFC use SPI , when I remove NFC Board from HUB Displey work correctly, so that is conflict. But how to use both board same times without conflict?
I do not understand how I set SPI for it.
Can You help me?
Sorry for my English 🙂 and thank you for your help
Please read SparkFun’s excellent tutorial on SPI to understand how multiple SPI slave devices can be connected to the Raspberry Pi. Essentially the SCK, MOSI and MISO pins are shared between the two slave devices and there will be a different SS (slave select) pin attached to each device. If I recall correctly the Raspberry Pi can support up to two SPI devices.
https://learn.sparkfun.com/tutorials/serial-peripheral-interface-spi/slave-select-ss
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.
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.
Hi Phil, the Node-RED Raspberry Pi documentation mentions the wiring-pi module that you could use to communicate via SPI. The Wiring Pi SPI library documentation is here.
Node-RED mentions this is an “advanced” use case and requires writing a JavaScript function.
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
Minor typo: `write_put(0x00)` should be `write_pot(0x00)`
Corrected. Thanks.
The second write should be “write_pot(0x00)” rather than “write_put(0x00)”.
I get a segmentation fault after I do ‘make’ in Step 2:
cd py-spidev
make
Any idea how to resolve this issue?
Hi Takaitra, I saw your example on “Controlling an SPI device with the Raspberry Pi” but your codes only for output. Can you also show how to read an input from the SPI device. eg STEDI16Px (http://www.smarthardware.eu/manual/stedi16px_doc.pdf)
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, … “
Fixed! That bio was a couple of years out of date. Thanks for letting me know.
[…] Follow the first two steps in Controlling an SPI device with the Raspberry Pi. […]