How to use native I2C on Linux (SMBUS2)
Related Config File Sections:
MPF can control I2C devices on Linux using the Python smbus2_asyncio extension.
1. Install the smbus2_asyncio extension
smbus2_asyncio via pip:
pip3 install smbus2_asyncio
2. Figure out which bus to use
- Some boards such as the Raspberry Pi have native I2C buses. Figure out which bus to use and make sure MPF has sufficient permissions to use it (Alternatively, you can also controll the I2C on the RPi remotely using the RPi platform).
- You can build an adapter to tap I2C out of a spare VGA, DVI or HDMI port: http://www.instructables.com/id/Worlds-Cheapest-I2C-I-Squared-C-Adapter/
- Commercial USB-I2C adapters exist but are usually very expensive
- You can build your own USB-I2C adapter. Hardware can be bought ready-made for less than 10 bucks. Atiny85 based boards can be bought at Adafruit as Trinket (and elsewhere just google it).
This is an adafruit trinket used as USB-I2C adapter for an MMA8451-based accelerometer:
3. Connect your hardware
Connect the hardware to the bus. This will be at least SDA, SCL and ground. Usually, you have to power your device somehow and in a lot of cases this power can be provided from the controller.
4. Set your I2C devices to use the "smbus2" platform
Next you need to configure I2C in MPF to use the
smbus2 platform. By
default, all types of devices are assumed to be using the same platform
that you have set in the hardware: of your machine config file. So if your platform is set to
fast, MPF assumes your I2C devices are connected to a FAST controller,
and if your platform is set to
p3_roc, MPF assumes your I2C devices
are connected to the P3-Roc board.
To configure MPF to use native I2C, you can add an entry to the
hardware: section of your machine config to tell it to override the
default platform for your I2C devices and to instead use the
platform, like this:
hardware: i2c: smbus2
See the Mixing-and-Matching hardware platforms guide for more information about setting device-specific default platforms versus overriding the platform for individual devices.
5. Understanding I2C numbering
When using I2C addresses in I2C devices smbus2 will interpret those as bus-address. If you only provide an address it will use bus 0. On Linux bus 0 will ususally be /dev/i2c-0, 1 will be /dev/i2c-1 and so on.
6. Add udev rules if you have multiple i2c devices
If you have more than one i2c device connected to your PC via USB you can assign a name to your ports based on the USB port they are connected to.
First identify the port of your I2C hardware. Usually it should be
udevadm info on your port:
udevadm info /dev/i2c0
This will show you the
DEVPATH. Now replace the last part
an asterisk and add an udev rules like this in
SUBSYSTEM=="i2c-dev", ACTION=="add", DEVPATH=="/devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3.1/1-3.1:1.0/*", SYMLINK+="i2c-front", GROUP="adm", MODE="0660
After a reboot you should get a
/dev/i2c-front device if you connect
an i2c device to that specific USB port. You can use that port in your
What if it did not work?
Have a look at our hardware troubleshooting guide.
Something missing or wrong? You can fix it!
This website is edited by people like you! Is something wrong or missing? Is something out of date, or can you explain it better?
Please help us! You can fix it yourself and be an official "open source" contributor!
It's easy! See our Beginner's guide to editing the docs.
Page navigation via the keyboard: < >
You can navigate this site via the keyboard. There are two modes:
General navigation, when search is not focused:
- F , S , / : open search dialog
- P , , : go to previous page
- N , . : go to next page
While using the search function:
- Down , Up : select next / previous result
- Esc , Tab : close search
- Enter : go to highlighted page in the results