I²C bus, also called TWI is a popular electronic bus designed for low-speed communication between different peripherals. As an MLAB's component it is mostly used to ensure communication between microprocessor and sensors. I²C derivative SMBus differs from it in that it contains timeouts' definitions and Packet Error Checking and therefor is, in sense, more robust than the original I²C.
Thanks to an advancement in computer technologies new possibilities arise allowing the use of the bus for direct communication between sensors and Linux systems. Furthermore, with the help of I²C adapter the bus can be connected to PC as well.
Although the I²C bus was originally designed to link devices on small scales (within the dimensions of PCB), using certain techniques it is possible to enlarge its range to tens of meters 1). However, it must be noted that such approach may not be safe because over long wires a high voltage can be electrostaticilly and electormagnetically induced and can cause damage to connected devices. The exact distance over which it is safe to use the I²C bus depends on the surrounding environment and the required reliability of the system.
Linking of I²C devices within MLAB is implemented on several levels according to extent of a network. Locally (on scale of several meters), the modules are connected by MLAB cables and separated by i2chub. This module also solves the conversion between logic 3.3V and +5V.
Over more extensive distances the bus is linked through shielded signal cables ending in female connectors and connected to UniSerial module. This module also contains a basic surge protection and most importantly acts as a mechanical bridge between 'heavy external wiring' and fine internal linking of devices.
In the case of extensive networks I²C is replaced by other physical layer (CAN, Ethernet) that interconnects individual I²C network segments.
Pymlab represents a software package that enables a creation of network made of I²C devices and modules, which serve as routing points. It defines the structure of a network and addresses of individual nodes in a source file of a control program. Individual points in the network can than be accessed using simple python commands.
The installation of the pymlab packed can easily be done using following command:
sudo pip install pymlab
In case of having some older version of pymlab already installed, it is enough to run:
sudo pip install --upgrade pymlab
Both commands are equivalent and use the python package manager that contains the pymlab. This procedure should also download other packages used by pymlab such as cython-hidapi (reffered only as hid module in python). However it does not install alelibusb, which must still be done manually using:
sudo apt-get install libudev-dev libusb-1.0-0-dev libhidapi-dev python-setuptools python-smbus cython
Although I²C is quite popular bus suitable to connect different sensors over short distances, it is not usually found and readily available on regular computers. 2)
These share a common problem with a quality of drivers. Furthermore, i2c-tiny-usb does not fully meet the I²C specification, completely fails to comply with USB physical layer specification and only has maximal communication speed of 50Kbps. MLAB replaces these constructions with I2C AVR USB device that is equivalent to i2c-tiny-usb design, but made of MLAB modules. I²C to USB with PIC connector represent another, yet unfinished, alternative.
For connections without the need for drivers designed for specific hardware USB HID specification can be used. MLAB has only one module that complies with this particular specification - USBI2C01A. It can be operated using python or HIDAPI - see below.
NXP manufactures konvertor UART na I²C SC18IM700IPW, which can possibly become the basis for construction of another conversion module.
There exists a package of tools for working with I²C bus for Ubuntu that can be installed through:
sudo apt-get install i2c-tools
Due to the usual absence of i2c-dev 3) module in kernel, we need to add it manually:
sudo modprobe i2c-dev
Modprobe command adds the module only to the kernel instance that is already running. Therefore, after reboot, the module will probably still be missing. If we do not want to use modprobe command on next computer start, we need to add following line to /etc/modules:
It is now possible to list available I²C buses:
$ sudo i2cdetect -l i2c-0 i2c i915 gmbus ssc I2C adapter i2c-1 i2c i915 gmbus vga I2C adapter i2c-2 i2c i915 gmbus panel I2C adapter i2c-3 i2c i915 gmbus dpc I2C adapter i2c-4 i2c i915 gmbus dpb I2C adapter i2c-5 i2c i915 gmbus dpd I2C adapter i2c-6 i2c i2c-tiny-usb at bus 001 device 030 I2C adapter
Using i2cdetect software we can further search for I²C buses for example on Odroid-X2, which has I²C output through GPIO.
kaklik@radio-arm-0:~$ sudo i2cdetect -y 1 0 1 2 3 4 5 6 7 8 9 a b c d e f 00: -- -- -- -- -- -- -- -- -- -- -- -- -- 10: UU -- -- -- -- -- -- -- -- -- -- -- -- -- 1e -- 20: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 30: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 40: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 50: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 60: -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- 70: 70 -- -- -- -- -- -- -- kaklik@radio-arm-0:~$
The bus can be controlled either by using system kernel interface or a service utility that is a part of i2c-tools package:
$ apropos i2c i2cdetect (8) - detect I2C chips i2cdump (8) - examine I2C registers i2cget (8) - read from I2C/SMBus chip registers i2cset (8) - set I2C registers
Writing is executed by i2cset command. A following I²C rozbočovač I2Chub02B setting provides a specific example as the IO has only one register that is not addressed. Data is therefore written directly:
~$ sudo i2cset -y -r 1 0x70 0xff Value 0xff written, readback matched
The command triggers all I²C channels on I²CHub 4).
Reading from I²CHub is atypical as well, because the data registry is not addressed:
$ sudo i2cget -y 1 0x70 0xff
Some I²C devices have their drivers directly in the linux kernel allowing an access directly through file system. It applies to following MLAB modules:
Due to the fact that, in principle, I²C is not a plug-and-play bus, every connected device must be explicitly reported to the kernel. A general procedure of such connection is via a following command:
echo driver's_name i2c_adresa > /sys/bus/i2c/devices/i2c-X/new_device
Linux kernel will take control of I²C device - such state can be seen in i2cdetect list labeled as UU. Details concerning the initialisation can be further found in dmesg.
On other OS (like Windows or Mac OS), where we cannot or do not want to use kernel I²C interface support, we may use Python programming environment that is multi-platform.