SPI Serial Peripheral Interface Bus in Raspberry pi:
SPI Serial Peripheral Interface:- A bus system, or bus (Binary Unit System) for short, is used to transfer data between several participants. In contrast to switching a GPIO pin on and off manually much, more data can be transmitted via bus systems. Dependent from the system used, the data are serial (i.e. one after the other) or parallel (at the same time) sent via the bus. This may be necessary if you want to communicate with your Raspberry external modules, e.g. with Microcontrollers, EEPROMs or digital/analog converters.
The five bus systems mentioned above are standard in many applications and offer an excellent opportunity to use the functionality of the Raspberry Pi to expand.
Amazon Purchase Links:
Other Tools and Components:
*Please Note: These are affiliate links. I may make a commission if you buy the components through these links. I would appreciate your support in this way!
SPI serial peripheral interface:
The SPI serial peripheral interface bus is a serial bus that has three lines for communication needs. SPI is based on the master-slave principle. That means that there is a master that requests the slaves to output their data. Independent the slaves cannot communicate with each other. The master in our case is the Raspberry Pi, the slave can use any component with an SPI interface (see Figure 1).
The figure clearly shows that there is an additional line per subscriber it is possible to connect several participants to the same bus. The fourth line is the chip select signal. This allows the master to select the participant to be communicated with.
This is easy to understand: All participants are on the same bus in parallel. So, all participants see the complete communication that takes place on the bus. If information is only intended for one participant, then all will others are forced to listen away by the chip select signal and ignore them Information on the bus. Only the participant who is supported by the chip select signal is controlled, reacts to the data sent over the bus. The Chip Select signal is usually low-active, which means that there is a negative edge needed to be recognized as active. You can recognize low-active inputs in the Datasheet on the line above the designation. All pins required can be found on the Raspberry Pi’s GPIO bar (equally for models A, B, and B +):
- MOSI (Master Out Slave In): Pin 19 of the GPIO connector strip
- MISO (Master In Slave Out): Pin 21 of the GPIO connector strip
- SCLK (Serial Clock): Pin 23 of the GPIO connector strip
- CS / CE (Chip Select or Chip Enable): Pins 24 and 26 or any free one
- The output of the GPIO connector strip
Set up SPI serial peripheral interface via raspi-config:
In the current version of raspi-config the activation of the SPI(serial peripheral interface) done quickly (see Figure 2 and Figure 3). Update if necessary first your system files via
sudo apt – get update
sudo apt – get upgrade
and then start the configuration menu via sudo raspi-config. Navigate Go to Advanced Options, select SPI serial peripheral interface and confirm Query in the following window with Yes. The SPI serial peripheral interface module is now activated. Then you will be asked in another window whether you want to use SPI serial peripheral interface) directly at system start want to make them available. Again answer Yes to confirm this. After a restart, the SPI interface is now available at all times.
Set up SPI serial peripheral interface manually:
This section describes the manual setup of the SPI interface, e.g. for distributions, in which raspi-config is not available. Since the kernel version 3.18, some bus systems are managed via the device tree. You will be in many Sources can still find instructions that say you can use SPI and I2C through a Adapt the files blacklist.conf and activate / etc / modules. This is no longer necessary. A manual setup of SPI takes place in the file / boot /config.txt. Open this with an editor:
At the end of the file, add the following line and save the file:
dtparam = spi = on
After a restart, the SPI serial peripheral interface is available to you. This step is carried out in exactly the same way if you use the raspi-config menu described above use. Only one of the two methods is necessary. To access the SPI interface with Python, you need the Python Library spidev:
git clone https://github.com/gadgetoid/py-spidev
cd py – spidev
sudo python3 setup.py install
sudo shutdown -r now
To install for Python 2, change the penultimate line to sudo python
The digital potentiometer:
A potentiometer, also known as a potentiometer for short, is an adjustable resistor. The Pots are usually known as components with mechanical rotary control. Go berserk the desired resistance can be set on the controller. A digital one Poti, on the other hand, cannot be recognized optically as a pot, because the design is typical IC (see Figure 4). For this example, we use the digital potentiometer MCP4132-502. This is an adjustable resistance up to 5k. The component is controlled via SPI SERIAL PERIPHERAL INTERFACE. The addition 502 in the component name stands for the maximum resistance value. This component is available in versions for 10k, 50k, and 100k. Give it the first two digits of the component number the base value, the last digit the Power of ten:
502: 50 X 102= 5000 (5 kΩ)
104: 10 X 104 = 100.000 (100 kΩ)
You now have to connect the component to the Raspberry Pi (see Figure 5). The MCP4132 version used in this example has two legs of the adjustable resistance: the fixed output P0B and the Slider (or wiper) P0W. Measure the set one between these two pins Resistance. If you use the component with the MCP41X1 version, please find this As with a conventional potentiometer, you have three pins in front of which you connect the resistor can tap.
Send data via SPI serial peripheral interface:
We assume that you have already installed the python-dev and python-spi packages. SPI library can be integrated in Python with import spidev.
#! / usr / bin / python3
import RPi.GPIO as GPIO
spi = spidev.SpiDev ()
spi.open (0, 1)
spi.xfer ([0 x00, 0x80])
To understand the program you need to read the spiDev documentation and the Read the data sheet of the component. We will now show you the functions step by step of the individual lines of code: First the previously installed spiDev library imported. spi = spidev.SpiDev () creates a spiDev object and stores it in the Variables spi. The open method defines the chip select pin. The Raspberry Pi has two fixed chip select and chip enable outputs: Pin 24 is CE0, pin 26 is CE1. Use spi.open (0,0) when using the component connected to CE0, or spi.open (0,1) if the chip select output CE1 is used. The first number before the comma determines the SPI channel, in ours Case channel 0. Channel 1 is available at pins 11, 12 and 13, but we stay with channel 0.
In the line spi.xfer ([0x00, 0x80]), data is finally sent to the component, namely exactly two bytes. After executing this command, the potentiometer set to its maximum value. A look into why this happens Data sheet visible. Below you will find some tables from the datasheet of the component, which are necessary to interpret the Python line.
The component understands different command bits (see table 1). In our case, we use the write data command as the first byte, which has the value as a hex value Represents 0x00. This means that the component knows that we have a value in the following byte want to write. In the Python code, we send the byte 0x80 afterwards. That’s the Value for the maximum possible resistance value (see table 2). Note that the MCP4132 is a 7-bit potentiometer, so take the appropriate into account Column. You can see that 0x40 is the middle position, i.e. 2.5 k, represents, 0x00 against it the minimum possible value of the potentiometer.
|C1 / C0 bit status||command||Number of bits|
|00||Write Data||16 Bits|
|11||Read Data||16 Bits|
Table 1:Overview of the command bits (source: data sheet MCP4132)
|7-bit potentiometer||8-bit potentiometer||Characteristics|
|3FFh, 081h||3FFh, 101eh||3FFh, 101eh Reserved (full-scale, W = A), increment and decrement commands ignored|
|080h||100h||Full-scale (W = A), increment commands ignored|
|07fh, 041h||0FFh, 081h||W = N|
|040h||080h||W = N (mid-scale)|
|03Fh, 001h||07Fh, 001h||W = N|
|000h||000h||Zero Scale (W = B) decrement command ignored|
Table 2: Position of the wiper in relation to the bytes sent (Source: data sheet MCP4132)
So that you can now freely set any resistance value, you have to do a little math. The potentiometer has a resolution of 7 bits at 5000Ω maximum Resistance value. 27 corresponds to 128 possible steps: 0 to 127. Now divide 5000Ω through 128 steps, you get a value of approx. 39Ω per step. You can use the potentiometer in 39Ω steps up to 5k adjust. In our experiments was the smallest possible value of potentiometer 144Ω, the maximum value was 4.99kΩ. You now know the number of steps, the minimum, middle and maximum positions of the potentiometer. In order to achieve the values in between, it is best to calculate the hex values in decimal values. A few examples make this clear (see Table 3).
Table 3:Examples of hex value conversion
The component also understands a few other commands, including increment and Decrement (see table 1): With this, you can change the value of the potentiometer change one step up or down. The datasheet shows the hex value, which is necessary for access to all available registers. The MOSI column contains the bit sequence for writing to one of the registers. The MISO column indicates the bit sequence with which the block reacts to a change in the register will answer. The increment command requires the binary value 0100, which corresponds to the hex value of 0x04 corresponds. If you build a loop with this command, the resistance value will be every second increased by the value of a single step:
spi. xfer ([0 x04])
time. sleep (1)
If you use the value 0x08, the bit sequence 1000 for the decrement command the resistance value decreases with each loop pass the value of a single step.
Read data via SPI serial peripheral interface:
Another command is reading the SPI serial peripheral interface subscriber. In the case of the MCP4132, the Command bit sequence 1100 required (see table 1). The corresponding hex value is 0x0c. Now it is necessary to know that with the SPI serial peripheral interface protocol every transmission is accompanied by a reception process. That means: If a byte is sent from Master sent, the slave automatically sends back a byte. For writing the response byte was irrelevant for the resistance values. But now you want a byte read from the component, so you must send one in beforehand. To do this, simply replace the previous while loop with the following:
spi. xfer ([0 x04])
print ("Increase by one step")
answer = spi. xfer ([0x0c, 0x00])
print ("Current position:", answer )
time. sleep (1)
So in order: The line spi.xfer ([0x04]) asks the device, the resistance to increase in single steps. The following assignment response = spi.xfer (…) sends the bit sequence of the read command and a dummy byte and stores the received Data in the variable answer. The response of the potentiometer is now instead of the Dummy bytes returned.
Now print the content of the answer, so should – depending on the current position of the wiper – the following output appears: [254, 128]. The first byte is the acknowledgment for the read command, which we are not interested in. The second Byte has taken the place of the dummy byte and shows the current position of the Wipers as a decimal number. Now filter the relevant information from the variable, by modifying the output as follows:
print (answer )
Now you can see directly at which position the wiper is currently located. The result of the loop after a few runs should look like this, provided you start at a position of 0:
Take a step up
Current position: 1
Take a step up
Current position: 2
Take a step up
Current position: 5
You have now learned the most important commands you need to be able to use to communicate with external SPI serial peripheral interface modules. However, each component needs different ones Address and command bits and therefore cannot be explained universally. So it is It is always necessary to look into the datasheet of the module used and there to filter out the necessary information for the control.
xfer () versus xfer2 ()
These two functions are used to send and receive bytes. For each byte sent is received and can be output. Besides these two functions use the CE0 and CE1 pins of the Raspberry Pi.xfer() toggles The chip select signal applies after each block sent. xfer2(), however, holds that Chip select signal active until all blocks have been sent. Depending on the component type, it can it may be necessary to confirm a transaction with a CS edge. See this also in the datasheet of the component. Using these two functions assumes that you absolutely have one of the two CE0 or CE1 pins as a chip select Use the signal and set it with spi.open(0, X).