The I2C bus is available on all Raspberry PLC models and is compatible with a wide range of sensors and peripheral integrated circuits. Before using a connected I2C device, you need to know its address on the bus. This article shows how to write an I2C address scanner in Python using the Adafruit Blinka library, which runs directly on the Raspberry PLC without any additional hardware configuration.
Requirements
- Raspberry PLC with an I2C device connected to the SDA and SCL pins
- Ethernet cable or monitor and keyboard to access the PLC
- Internet connection to install the library
The I2C communication protocol
Inter-Integrated Circuit (I2C) is a two-wire serial protocol developed by Philips in the 1980s and widely used in embedded systems, robotics, and industrial automation. It uses a serial data line (SDA) and a serial clock line (SCL). Multiple devices share the same two wires in a bus topology, and each has a unique 7-bit address that the master uses to address it individually.
I2C supports master and slave roles. The master initiates all transfers and controls the clock. The slave responds when addressed. After each byte, the receiving device sends an acknowledge signal (ACK). Typical speeds are 100 kHz (standard mode) and 400 kHz (fast mode), with 3.4 MHz available in high-speed mode.
A practical advantage of I2C is that it only needs two GPIO pins and two pull-up resistors, making it easy to connect multiple sensors to the same bus. The main limitation is throughput: for high-speed data streams, SPI or UART are better options.
Installing the Adafruit Blinka library
Adafruit Blinka provides a CircuitPython-compatible hardware abstraction layer for single-board computers such as the Raspberry Pi. Install it with:
pip3 install adafruit-blinka
Make sure the PLC has an internet connection. If you need to set that up first, see the Raspberry PLC Wi-Fi guide.
To use specific I2C devices, install the corresponding Adafruit CircuitPython library. For example, for the MMA8451 accelerometer:
git clone https://github.com/adafruit/Adafruit_CircuitPython_MMA8451.git
Note: if copying the command from this page produces an error, type it manually.
I2C functions in Blinka
The main I2C functions available through the Adafruit Blinka library are:
i2c = board.I2C() # Crea un objeto I2C usando board.SCL y board.SDA i2c.try_lock() # Intenta adquirir el control exclusivo del bus i2c.scan() # Devuelve una lista de direcciones que respondieron i2c.writeto_then_readfrom(addr, write_buff, read_buff) # Escritura y lectura en una sola transacción # write_buff y read_buff deben ser de tipo bytes o bytearray.
In practice, most sensor libraries built on Blinka encapsulate these low-level calls, so they are rarely used directly. Use i2c.scan() when you need to discover what is connected to the bus.
I2C address scanner example
The script below continuously scans the I2C bus and prints the hexadecimal address of each responding device, with a 5-second interval between scans.
import board
import time
i2c = board.I2C() # Usa board.SCL y board.SDA
try:
i2c.unlock() # Desbloquea si el bus quedó bloqueado por un programa anterior
except ValueError:
print("I2C not locked, proceeding to lock")
while not i2c.try_lock():
pass
try:
while True:
print("I2C addresses found:",
[hex(device_address) for device_address in i2c.scan()])
time.sleep(5)
except KeyboardInterrupt:
print("Unlocking I2C bus and exiting...")
i2c.unlock()Ejecuta el script con python3 scanner.py. Cada 5 segundos imprimirá la lista de direcciones detectadas. Usa esas direcciones al inicializar la librería del dispositivo o al llamar a las funciones I2C directamente.

How to test the I2C communication protocol with Raspberry PLC