Programação RPi Python 25 – Comunicação serial síncrona em Raspberry Pi usando protocolo I2C

RPi Python 25 Programming – Synchronous serial communication on Raspberry Pi using I2C protocol

In the previous tutorial, we discussed the basics of the I2C protocol. In most embedded devices, UART or I2C is used for console messages. In this tutorial, we will discuss serial communication on Raspberry Pi using the I2C protocol.

I2C on Raspberry Pi
For serial communication via the I2C protocol, the Raspberry Pi's Broadcom processor has a Broadcom Serial Controller (BSC). This standard mode master BSC controller is I2C compatible from NXP Semiconductor and supports a data transfer rate of 400 kbps. The BSC controller supports 7-bit and 10-bit addressing. This I2C interface is accessible on GPIO2 pins (board pin #3) and GPIO3 (board pin #5). GPIO2 is a Serial Data (SDA) line and GPIO3 is a Serial Clock (SCL) line of I2C1. These I2C pins are internally pulled up to 3.3V through 1.8 kohm resistors. This is why these pins cannot be used for general purpose I/O where pull-up is not required.

There is one more I2C BSC2 peripheral on the Raspberry Pi identified as I2C0. The BSC2 master is dedicated to the HDMI interface and cannot be accessed by users. This I2C interface is present on pins 27 (ID_SD) and 28 (ID_SC) of the board. I2C0 remains reserved for reading EEPROM from Raspberry Pi add-on boards called Hardware on The Top (HAT) boards. I2C0 can only communicate with HAT EEPROM at address 0x50 during boot time.

You can access I2C0 only if the camera interface and HDMI port are not in use. To use I2C0, add the following lines to boot/config.txt.
dtparam=i2c_vc=on

The I2C0 pins are not pulled internally, so if they are used by modifying the Raspberry Pi configuration file, external pull-ups (to 3.3V) must be used on the SDA and SCL lines. When using I2C0, the pins avoid using the HAT EEPROM address.

Even I2C1 is disabled on Raspberry Pi by default. It needs to be enabled in the Raspberry Pi configuration. Raspberry Pi's BSC controllers support multi-master and multi-slave I2C. Therefore, I2C1 is sufficient to connect multiple I2C slaves (maximum 112 slaves) and any number of master devices.

Enabling I2C1 from the Raspberry Pi GUI

On Raspbian, navigate to Pi Start Menu -> Preferences -> Raspberry Pi Configuration.

In the pop-up window, click on the 'Interfaces' tab and select the 'Enable' radio button for I2C. You can also enable or disable other interfaces as needed.

For the changes to take effect, restart the Raspberry Pi. After reboot, GPIO3 and GPIO5 can be used to connect Raspberry Pi as an I2C master with an I2C bus or to any I2C slave.

Enabling I2C1 of the Terminal
I2C support for Raspberry Pi's ARM core and Linux kernel can also be enabled in Terminal (Bash Shell on Raspberry Pi). Open Terminal and run the following command:
sudo raspi-config

In the Raspberry Pi software configuration tool, navigate to 'Interface Options'.

On older Raspberry Pi models, navigate to 'Advanced Options' and then 'I2C'.

In the pop-up window, enable the Arm I2C interface and select 'Yes' to load the I2C Kernel Module.

Now restart your Raspberry Pi by typing the following command:
sudo restart

After reboot, GPIO3 and GPIO5 can be used to connect Raspberry Pi as an I2C master with an I2C bus or to any I2C slave.

Testing I2C port
After enabling the I2C user port and restarting the Raspberry Pi, we can test whether the port is available as a Linux device or not. In the Terminal window, run the following command:
ls /dev/
Or
ls /dev/*i2c*
I2C1 should appear as one of the available Linux devices as shown in the image below.

Note that in older versions of the Raspberry Pi, the I2C user port is identified as I2C0 instead of I2C1. On all Raspberry Pi 256M models, the I2C user port is 0, and on the rest it is 1.

Checking I2C slaves on Raspberry Pi
After enabling the I2C user port, connected I2C slaves can be detected using i2c-tools. Firstly, install i2c-tools by running the following command on the Raspberry Pi Terminal:
sudo apt-get install -y i2c-tools

Now run the following command to check the connected I2C slaves:
sudo i2cdetect -y 1

As already mentioned that in older versions of Raspberry Pi the I2C user port is 0, in older versions change the port number to 0 as follows:
sudo i2cdetect -y 0

i2c-detect is a tool that checks the I2C user port and returns the I2C addresses of connected slave devices. The tool returns a table of addresses of connected I2C slave devices as shown in the image below:

Accessing I2C devices using the SMBus library
On Raspberry Pi, the I2C bus can be accessed in a Python script using the SMBus library. SMBus is a subset of the I2C interface. The Python library for SMBus can be used to communicate with I2C based devices. The SMBus library can be installed on the Raspberry Pi by running the following command:
sudo apt-get install python-smbus

In a Python script, the SMBus library can be imported using the following statement:
import smbus

After importing the SMBus library, an SMBus class object must be created using the SMBus method. The SMBus method takes the I2C port number as a parameter and must be used in an assignment statement to create an SMBus object. It has the following syntax:
= smbus.SMBus(I2C_Port_Number)

The following is a valid example of creating an SMBus object:
i2c bus = smbus.SMBus(1)

Note that on older versions of Raspberry Pi, the I2C user port is 0, and on all versions of Raspberry Pi above 256M RPi, it is 1. To use the newer SMBus2 library, it can be installed using pip by running the following command:
pip install smbus2

In a Python script, the SMBus2 library can be imported using the following statement:
from smbus2 import SMBus, i2c_msg

An SMBus class object can be created using the smbus2.SMBus method as follows:
i2c bus = smbus2.SMBus(1)

The smBus2 library has two classes – SMBus and i2c_msg. The SMBus class supports the following methods:
smbus.SMBus /smbus2.SMBus – To create an SMBus object in Python script.
open (bus) – To open a given i2c bus.
close – To close the I2C connection.

Serial data from an I2C slave can be read in bytes, words or blocks of bytes. In some I2C slave devices, the master needs to access serial data from specific registers. The following methods are available in the SMBus2 library for reading I2C serial data from slave devices:
read_byte(i2c_addr,strength=None) – To read a single byte from a device.
read_byte_data(i2c_addr,registrar,force=None) – To read a single byte from a designated register.
read_block_data(i2c_addr,registrar,force=None) – To read a block of up to 32 bytes from a given record.
read_i2c_block_data(i2c_addr,record,length,strength=None) – To read a block of byte data from a given record.
read_word_data(i2c_addr,registrar,force=None) – To read a single word (2 bytes) from a given record.

Likewise, data can be written to I2C slaves in bytes, words or blocks of bytes. On some I2C slave devices, data must be written to specific registers. The following methods are available in the SMBus2 library to write serial I2C data from slave devices:
write_byte(i2c_addr,value,strength=None) – To write a single byte to a device.
write_byte_data(i2c_addr,record,value,force=None) – To write a byte to a given record.
write_block_data(i2c_addr,record,data,strength=None) – To write a data block of bytes to a given record.
write_i2c_block_data(i2c_addr,register,data,strength=None) – To write a data block of bytes to a given register.
write_word_data(i2c_addr,record,value,force=None) – To write a byte to a given record.
write_quick(i2c_addr,strength=None) – To perform fast transactions. Throws IOError if unsuccessful.

The following methods are available to manage SMBus processes and combine I2C bus read/write operations:
process_call(i2c_addr,register,value,strength=None) – To execute an SMBus process call, sending a 16-bit value and receiving a 16-bit response
block_process_call(i2c_addr,record,data,force=None) – To send a variable-sized block of data and receive another variable-sized response.
i2c_rdwr(*i2c_msgs) – To combine a series of i2c read and write operations into a single transaction.

In the next tutorial, we will discuss interfacing the ADXL345 accelerometer sensor with Raspberry Pi via I2C port.

Conteúdo Relacionado

A network of sensors is embedded in every vehicle,...
The motor controller is one of the most important...
ESP32-CAM is a compact camera module that combines the...
A evolução dos padrões USB foi fundamental para moldar...
A SCHURTER anuncia um aprimoramento para sua conhecida série...
A Sealevel Systems anuncia o lançamento da Interface Serial...
A STMicroelectronics introduziu Diodos retificadores Schottky de trincheira de...
Determinar uma localização precisa é necessário em várias indústrias...
O novo VIPerGaN50 da STMicroelectronics simplifica a construção de...
A Samsung Electronics, fornecedora de tecnologia de memória avançada,...
O mercado embarcado tem uma necessidade de soluções de...
You have probably come across the term ' drag...
You probably have a support insulator if you've noticed...
You've probably seen stand an insulator sit on power...
You've probably seen shackle insulators enthroned on electricity poles,...
You have probably experienced situations where controlling a circuit...
Back to blog

Leave a comment

Please note, comments need to be approved before they are published.