I can't manage to put together all the fragments of information I have found on this through searches.

I have a new 3B and several I2C devices, including a PCA9685. The addresses are shown with i2cdetect and I also had some device-specific sample code running, so the hardware is fine. But I want to be able to look in the device data sheet to find what each can do, and then send the commands documented there rather than rely on someone else's abstraction.

I assume solutions for CircuitPython/MicroPython will not work. Sometimes answers aren't very explicit about the context.

What python package will allow me to do this?

gpiozero and pigpio come up frequently, but don't seem to provide this capability, or did I miss something?

  • None of the modules in the answers given below fully support I²C. smbus, smbus2, pigpio, lgpio and rgpio all limit the length of read and write payloads to 32 bytes. That limitation exists in the SMBus spec but not in the I²C spec.
    – Joooeey
    Jan 24 at 10:08

2 Answers 2


Most people will probably use the smbus Python module (import smbus). This implements SMBus but not I2C.

pigpio has a complete implementation of the SMBus and I2C commands (import pigpio).

For Python see http://abyz.me.uk/rpi/pigpio/python.html

In particular look at the commands starting with i2c, e.g. i2c_open.

I also have two new Python libraries which fully implement SMBus and I2C commands.

lgpio to access local I2C buses (import lgpio).

rgpio to access local and remote I2C buses (import rgpio).

  • Ok, now I've read up on SMBus and things are starting to make more sense. Where could I read up on the official version of SMBus that comes preinstalled? Searching turns up many variants. :(
    – adr
    Dec 5, 2020 at 12:43
  • I'm not sure. I don't use the Python smbus module. The documentation seems sparse to non-existent.
    – joan
    Dec 5, 2020 at 13:05
  • While I appreciate that you answered at all (no one else has) I do not think the answer really deserves a check mark. Sorry.
    – adr
    Dec 13, 2020 at 20:17

Low-level aspects of i2c communication are handled in hardware, in my case the Broadcom BCM2837. To use the bus directly, one would have to write to and read from several hardware registers, which could be different ones for different hardware. Luckily there is a Linux kernel driver for this, which provides a hardware-independent way of doing basic i2c communication.

The Linux package i2c-tools provides several functions that use the services of the kernel driver to perform slightly more complex operations with a single function call, for example, reading a word instead of a byte. The package also includes several command-line tools for testing or to allow these operations to be run in scripts, and last but not least, there is py-smbus the python bindings for the c functions which make the system calls to the kernel driver.

import smbus uses py-smbus from the i2c-tools package, so this seems like the most basic way to talk to the chips at the other end of my i2c bus.

The smbus in the naming appears to be a hold-over from early versions of the driver and/or tools, when the objective was to talk to smbus devices. smbus is built on i2c therefore these functions, tools and the python package are more general than their names imply.

Disclaimer: I am not an expert on this, but this is a synopsis of what I have learned the past few weeks.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.