Questions tagged [i2c]

I2C is a two-wire serial bus. It is used to interface with low-speed peripherals in embedded systems and computer motherboards.

Use this tag when asking questions concerning the I2C bus or SMBus, which is a more strictly defined subset of I2C.

Devices you can communicate with using I2C might include the temperature and voltage sensors on your motherboard. In embedded systems, a vast amount of devices ranging from memory chips to camera modules use I2C for control and data transfer.

I2C bus consists of two signals: SCL and SDA. SCL is the clock signal, and SDA is the data signal.

I2C connection schematics

The clock signal is always generated by the current bus master; some slave devices may force the clock low at times to delay the master sending more data (or to require more time to prepare data before the master attempts to clock it out). The common clock frequency of I2C bus is 100KHz (100Kbps) and 400KHz (400 Kbps). There are high speed versions with clock frequency at or greater than 1MHz (1Mbps) available which is product specific by the semiconductor manufacturers.

The bus is a multi-master bus, which means that any number of master nodes can be present. Additionally, master and slave roles may be changed between messages (after a STOP is sent).

At any given time only the master will be able to initiate the communication. Since there is more than one slave in the bus, the master has to refer to each slave using a different address. When addressed only the slave with that particular address will reply back with the information while the others keep quit. This way we can use the same bus to communicate with multiple devices.

The voltage levels of I2C are not predefined. I2C communication is flexible, means the device which is powered by 5v volt, can use 5v for I2C and the 3.3v devices can use 3v for I2C communication. A 5V I2C bus can’t be connected with 3.3V device. In this case voltage shifters are used to match the voltage levels between two I2C buses.

There are some set of conditions which frame a transaction. Initialization of transmission begins with a falling edge of SDA, which is defined as ‘START’ condition in below diagram where master leaves SCL high while setting SDA low. After this all devices on the same bus go into listening mode.

In the same manner, rising edge of SDA stops the transmission which is shown as ‘STOP’ condition in above diagram, where the master leaves SCL high and also releases SDA to go HIGH. So rising edge of SDA stops the transmission.

I2C conditions

With I2C, data is transferred in messages. Messages are broken up into frames of data. Each message has an address frame that contains the binary address of the slave, and one or more data frames that contain the data being transmitted. The message also includes start and stop conditions, read/write bits, and ACK/NACK bits between each data frame:

I2C message format

Address Frame: A 7 or 10 bit sequence unique to each slave that identifies the slave when the master wants to talk to it.

Read/Write Bit: A single bit specifying whether the master is sending data to the slave (low voltage level) or requesting data from it (high voltage level).

ACK/NACK Bit: Each frame in a message is followed by an acknowledge/no-acknowledge bit. If an address frame or data frame was successfully received, an ACK bit is returned to the sender from the receiving device.

More information:

I2C Standards Doc

I2C primer

1748 questions
3
votes
1 answer

Adafruit MMA8451 accelerometer giving my Raspberry Pi osError [Errno 121] Remote I/O error

I am running python3.5 on a Raspberry Pi 3 B+. With a display. My project is getting a simple accelerometer to print its values. I am following the following tutorial: I even added dtoverlay=spi1-3cs to the end of /boot/config.txt to activate…
Taha Arif
  • 31
  • 4
3
votes
0 answers

Magnetometer output for LSM303DLHC sensor on i2c bus is erratic. Problem writing gobot pilot

I use the Adafruit LSM303DLHC sensor. It is made of 2 sensors, an accelerometer and a magnetometer. I am currently writing a driver for this sensor to work with the gobot.io package through i2c interface on a Raspberry Pi 2. Problem: The…
Jokari
  • 43
  • 3
3
votes
1 answer

Writing and reading from a virtual i2c using C++ and i2c-tools

I am trying to write and read from the I2C bus using C++. My I2C bus is virtual and the first thing is to load the kernel module i2c_stub. I can do everything through bash and now I am porting it to C++. I can open the i2c bus, acquire the i2c bus…
Felipe
  • 7,013
  • 8
  • 44
  • 102
3
votes
2 answers

why does i2cset send extra bytes?

I've been working on PIC18F55K42 chip for a while. The PIC is setup as a slave and it's receiving bytes correctly. But I encountered a few problems. For example, when I do: i2cset -y 1 0x54 0x80 0x01 It looks correct on the controller side and I…
Unmanned Player
  • 1,109
  • 9
  • 30
3
votes
1 answer

Linux: Instantiate from user-space : eeprom new_device

Environment : x86 / Ubuntu 14.04 I want obtain something similar to &i2c0 { eeprom: eeprom@50 { compatible = "at,24c32"; reg = <0x50>; }; }; But because in x86 no Device Tree is available, I am follow…
Peio
  • 43
  • 2
  • 8
3
votes
1 answer

Cannot use write() or read() calls on I2C device, but echo and i2c-tools work

I am trying to read and write from I2C devices on embedded linux (4.6). I can use i2cset, i2cget, and i2cdetect to interact with my devices fine. I can also use echo and cat to read/write from the device driver (i2c-ocores). However, any code I…
lyraelsol
  • 31
  • 1
3
votes
0 answers

SMBus write_i2c_block_data() command

So I started a project on a microcontroler that uses I2C communication a month ago with no knowledge about anything but python. I have to talk to a peristaltic pump that uses ASCII strings for communication. So my setup currently consists of a…
Kwang2846
  • 39
  • 1
  • 5
3
votes
1 answer

I2C Writing protocol: how to write in a register?

I am programming the MAX77651 in I2c using the FT4222 device. I want to be able to write in a register. I am able to read registers so i know i dont have any hardware problems. To read in a register i proceed like this: i first send the register i…
Isymap_prog
  • 147
  • 4
  • 14
3
votes
4 answers

Written Buffer to I2C Not Returned when Read

I am trying to read one value from a memory location on the I2C bus after writing to it. I am getting strange output when I run it in the terminal. Here is my program #include #include #include
John Frye
  • 255
  • 6
  • 22
3
votes
2 answers

I2C scan with Micropython and NodeMCU 12E returns empty list

I'm trying to hook up a MPU6050 with my NodeMCU board with Micropython flashed in it. My current wiring is the following: MPU6050 Board Vcc 3.3v Gnd Gnd SDA D6 SCL D7 Through the command line, I've tried the…
magicleon94
  • 4,887
  • 2
  • 24
  • 53
3
votes
0 answers

Reading from I2C

I am reading a 24bit value using I2C in Raspberry Pi. I open the /dev/i2c-1 file and then reading from it using the os.read function in python. The transaction is being carried out correctly. But the problem is even though I can access the…
3
votes
1 answer

I2C tools, i2cdetect and i2cset works perfectly, but i2cget returns 'read failed'

I am pretty new to I2C protocol, but I managed to write to my device. I bought the ADV7630 evaluation board, which is an HDMI switch controlled by I2C. I can write to registers using I2c, also i2cDetect works showing all devices. I also tried to…
Eric Jalbert
  • 81
  • 1
  • 8
3
votes
2 answers

STM32F4 I2C without library

I have to wire a code for STM32F4 discovery and pcf8574 with I2C. I can't use any library function. I try something I didn't do it. I did write after init code. My init code RCC->APB1ENR|=RCC_APB1ENR_I2C1EN ; // enable APB1 peripheral clock for…
3
votes
0 answers

Wrong sent data on I2C Arudino UNO

I'm running the piece of code below to do a I2C loopback interface on an Arduino UNO rev3. The Arduino board acts as slave in the I2C bus and after it has received a packet it raises a line that triggers a read operation by the master. The Arduino…
Genís
  • 1,468
  • 2
  • 13
  • 24
3
votes
1 answer

Reading motherboard sensors with Java Device I/O

OpenJDK has the Device I/O (DIO) library, which can be used to read hardware sensors. One supported bus in the DIO library is I2C. I have heard that desktop motherboard sensors are behind SMBus, basically a more restricted version of the I2C bus.…
Tuupertunut
  • 741
  • 7
  • 9