Important note: the steps below have been checked on the Raspberry Pi 2, but might differ on other versions of the Pi. For instance the Raspberry Pi 3 features a Bluetooth chip that might need to be configured on a different UART to avoid conflicts.
One great thing about the Raspberry Pi is its GPIO header, which allows us to connect it to custom electronics. It allows us to easily venture from the software to the hardware world, and opens up a lot of possibilities, that are just not available on a standard computer.
But to interact with the hardware we plug on the GPIO header, we need the right software: depending on the type of interface we want to use, this can involve just the Linux file system (for generic GPIO or UART interfaces), or Python and dedicated libraries (for I2C and SPI): that’s what we will look at in this article, on a Raspberry Pi 2 model B.
However, before abruptly diving into custom applications, we must look at the GPIO header to know the different pin’s functionality. Some of them can be used as GPIO but some of them are restricted to a specific function. Let’s look the Raspberry Pi pinout :
Power supply pins:
There are several available pins for power supply purpose. Depending on your need, you can use the 3.3V or 5V pins and the ground pins scattered across the header.
I2C interface pins:
SDA1, SCL1, ID_SD and ID_SC are all pins related to the I2C interface. SDA1 is the pin which must be used for the I2C datas and SCL1 is the I2C Clock pin. These are the two commonly used I2C pins but ID_SD and ID_SC are generally reserved for i2c communication with an EEPROM. As indicated by their other names, these pins can also be used as generic GPIO.
UART interface pins:
TXD0 and RXD0 are the pins related to the Serial UART interface. TXD0 is the transmit UART pin and RXD0 is the receive UART pin. As indicated by their other names, they can also be used as generic GPIO.
SPI interface pins:
There are multiple available pins for the SPI interface: the header comes with 2 MOSI pins, 2 MISO pins, 2 SCLK pins, 3 chip selects (noted as CE0#, CE1# and CE2#). All these pins can also be used as generic GPIO.
The other pins named GPIOX are all free to be used as generic GPIO. However, they cannot be used as interface pins, meaning that you cannot choose GPIO6 for the I2C data pin, for example.
1/ Using a pin as a generic GPIO
We can interact with the GPIOs available on the Raspberry Pi, directly via the Linux file system, without a single line of code. To do that, go to the GPIO directory of the Raspberry Pi :
To use a GPIO, find its BCM pin number (some GPIOs are reserved so they are not available for use).
And export it by running:
echo <GPIO_BCM_NUMBER> > export (replace <GPIO_BCM_NUMBER> by the GPIO you would like to use).
Go to the newly created directory:
cd gpio<GPIO_BCM_NUMBER> We can change the GPIO’s behaviour by writing into the different files.
To change the pin’s direction :
echo <DIRECTION> > direction (<DIRECTION> must be replaced by either “out” or “in”).
To change the pin’s value :
echo <VALUE> > value (<VALUE> must be replaced by either “0” or “1”).
Once we are done using the GPIO, we must free its use by entering:
echo <GPIO_BCM_NUMBER> > unexport (<GPIO_BCM_NUMBER> must be the same pin’s number you previously exported).
We can also configure and use GPIOs more efficiently with Python programming. In order to use GPIOs inside a script, we must install the RPi.GPIO package. Simply run the following command:
sudo apt-get install RPi.GPIO.
The first thing we should do to use this module is to import it :
import Rpi.GPIO as GPIO (we import the module as GPIO so we don’t need to type the full module’s name everytime).
The common setup to use is to write the following lines:
The first line disables the warnings related to GPIO’s use that we may see during programming. But, this should not be an issue if we know what you are doing and seeing them everytime can be tedious. The second line chooses the mode which will be used for pins. In our case, it indicates to the module that we want to use the BCM mode. BCM can be replaced by BOARD but remember that the pin number are different depending on the chosen mode (see previous image).
We can now use the GPIOs available on the Raspberry Pi. For more information on how to use them with RPi.GPIO, check out the sourceforge’s wiki.
At the end of the script, we must clean all the ports we used by calling this function : GPIO.
2/ Using the UART interface
First of all, we must free the serial port by making sure the console is not listening on this port (default behaviour in Raspberry Pi).
Enter the command :
In the menu, choose Advanced Options then Serial and to the question “Would you like to login shell….”, choose No. Reboot the Raspberry Pi by running:
sudo reboot -n (the -n flag means that the reboot will start immediately).
Then, we must enable the UART in the config file. Check with:
sudo nano /boot/config.txt that this line is in the file: enable_uart=1. Otherwise, add it manually.
Port name : /dev/ttyUSB0 if connected to Raspberry Pi USB port (The number can change depending on the port used).
Port name : /dev/ttyAMA0 if connected through the connectors (Tx and Rx pins).
To check if the port is active, enter the following command
dmesg | grep tty
To use the UART bus from the linux file system, we can enter the following commands:
cat <PORT_NAME> to display the serial monitor in the Linux terminal.
echo "test" > <PORT_NAME> to write “test” through the serial connection.
Note : <PORT_NAME> must be replaced by the serial port we want to use (written above).
To use the UART bus inside a Python script, we must install the PySerial package :
sudo apt-get install python-serial
In the Python script, we can now import serial module and use UART functionalities. First, we must declare the serial object by writing:
ser = serial.Serial(port="<PORT_NAME>", baudrate = 9600, timeout = 1)
Then, we can call the module’s functions like readline() or write() to perform UART transactions.
Note: The baud rate value can be changed.
Python bonus: miniterm
The PySerial package includes a very handy tool called miniterm, which opens a terminal so that we can directly send messages to / receive messages from the UART peripheral. To open the terminal, we just type:
python -m serial.tools.miniterm -e -p <PORT_NAME> -b <baudrate>
Where <PORT_NAME> and <baudrate> must be replaced with the relevant value, for instance if talking to a RN2483 LoRa module connected to the TX and RX pins:
python -m serial.tools.miniterm -e -p /dev/ttyAMA0 -b 57600
Then we can just sent messages (‘sys get ver’ in the screenshot below) and the reply is displayed (‘RN2483 1.0.3 Mar 22 2017 06:00:42’ in this case).
3/ Using the I2C interface
First of all, we must install the i2c-tools :
sudo apt-get install -y python-smbus
sudo apt-get install -y i2c-tools
Then, we must also install the I2C kernel support. Run:
Go to Advanced Options then I2C and choose <Yes>. Reboot your Rasperry Pi:
sudo reboot -n
Check manually that the changes were applied by following these steps:
Enter the command
sudo nano /etc/modules and make sure these two lines are written :
There might be a file called /etc/modprobe.d/raspi-blacklist.conf. If there is not, we don’t need to do anything else. Otherwise, we need to edit it and comment those two lines :
- blacklist spi–bcm2708
- blacklist i2c–bcm2708
sudo nano /boot/config.txt. Make sure the following two lines are in this file and are not commented. If they are not, add them manually.
We can now check if the i2c setup is functional by running:
sudo i2cdetect -y 1.
This command shows the I2C addresses which are currently used.
Real application with TSL2591
Once we have finished the wiring the Raspberry Pi with the TSL2591, we can display the i2c addresses and see if 0x29 address is in use. This means that the TSL2591 is recognized and ready to be used. You can use this script to test the TSL2591 functionality.
4/ Using the SPI pins
First of all, we need to enable the SPI kernel support. Run:
Go to Advanced Options then SPI and choose <Yes>. Reboot your Rasperry Pi :
sudo reboot -n.
Check in /boot/config.txt that dtparam=spi=on is not commented. If it is not written in this file, add it by typing manually.
There may be a file on this path : /etc/modprobe.d/raspi-blacklist.conf. If not, there’s nothing to do. Otherwise, we need to edit it by entering
sudo nano /etc/modprobe.d/raspi-blacklist.conf and comment this line :
- blacklist spi-bcm2708
Check if the spi module is correctly setup by entering the following command :
lsmod. In the module’s list, there should be a line with: spi_bcm2835.
Now, check if you can see the spi busses by running
ls -l /dev/spidev*. The two busses should be displayed like this:
The SPI configuration is now complete and we can start using it.
Installing the spidev library/module for Python.
To use the SPI functionalities within Python scripts, we need to install a utility module called spidev, which is used to interface SPI devices with the Raspberry Pi. First, we need to get the library’s sources by cloning this github repository.
To do that, run
sudo git clone https://github.com/doceme/py-spidev.
If the “git” command doesn’t exist, we need to install the git package:
sudo apt-get install git.
Once the download is complete, move to the new folder:
Install the library :
sudo python install setup.py install.
We can now import the spidev module from Python scripts and communicate with SPI devices.