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
2
votes
0 answers

how to add Device Tree Node for I2C device PCF8574A

We are using PCF8574A i2c device in our project. We enabled pcf857x & pcf8574_keypad device drivers in the kernel. And in .dts file we added i2c sub-node for this pcf8574a i2c device is as follows: &i2c4 { clock-frequency = <100000>; …
Rajesh D
  • 63
  • 3
2
votes
1 answer

MPU-9250 sample rate lower than the one selected in register map

I'm using Arduino UNO and I2C protocol to read data from MPU 9250 in arduino IDE. But the sampling rate is lower than the one I selected, indeed, I try to use 1KHz but the maximum speed I can reach is by reading only one of the sensors and is 25 Hz.…
2
votes
1 answer

Multiple I2C devices with the same address

Currently working on a project that requires me to use two I2C devices on the Raspberry Pi, but both devices use the same address. Does anyone have an easy fix to changing the address of 1 of the devices? :)
slowmoocow
  • 49
  • 5
2
votes
1 answer

Raspberry Pi Pico DMA to a I2C device

I'm using the C/C++ SDK of the Pi Pico and trying to use the DMA to read I2C data in the background. However, there is no example script in Pico-Examples that shows how to use the DMA to read from I2C. There is one for SPI, called spi-dma. But It…
SKrish
  • 43
  • 6
2
votes
0 answers

can data from a sensor be read in a function

I am using the icm 20948 sensor, programming on MPLABx running harmonyV3.i2c is communication mode. Can I read and write in a function, does it have to be in a while loop? For example would: while(SERCOM1_I2C_IsBusy())…
2
votes
0 answers

MSP430 I2C SCL line idling high (when it should be idling low)

I have the MSP430 configured as an i2c master device and it is talking with two slave devices: a battery fuel gauge (LTC2943) and a battery charger (LT8491 evaluation board). I noticed that when talking with the battery charger, a duplicate byte…
2
votes
1 answer

Connecting Waveshare LCD1602 RGB to Raspberry using C#

I am trying to connect LCD1602 RBG Waveshare to the Raspberry using C#. I connected it to the Raspberry and set the permissions, now trying to pass some data. The code below run all lines, but the LCD is not reacting. If anyone can advise me. using…
Darkk L
  • 889
  • 1
  • 4
  • 14
2
votes
0 answers

How to receive an unknown quantity of I2C data as a slave on STM32F105?

I'm using ST's HAL to receive I2C data as a slave on an STM32F105. The data is read with the code: // Called when an initial I2C address packet is found. void HAL_I2C_AddrCallback(I2C_HandleTypeDef *hi2c, uint8_t TransferDirection, uint16_t…
fadedbee
  • 42,671
  • 44
  • 178
  • 308
2
votes
2 answers

I2C temperature read from BMP085 reading back 0xffff

I'm interfacing a Rabbit 5760 CPU to a Bosch BMP085 sensor via I2C. Everything is fine except reading the temperature register is reading back 0xffff (see BP_FINISHTEMP case in switch). I can't see why it isn't working. The code is below. Can…
fred basset
  • 9,774
  • 28
  • 88
  • 138
2
votes
1 answer

I2C not reading

I'm trying to interface with a BNO055 breakout board from a Teensy 2.0, but I'm having trouble reading from the BNO055. It has different registers that you can access to read data from the chip. To start, I'm just trying to read the IDs of some…
CaseyB
  • 24,780
  • 14
  • 77
  • 112
2
votes
1 answer

Reading a 32k i2c eeprom from userland

I need to read an eeprom in an embedded device. So far this "almost" worked: #include #include #include #include #include #define READ_SIZE (256) #define NB_PAGES (128) void…
Zibri
  • 9,096
  • 3
  • 52
  • 44
2
votes
1 answer

access uino variable when union name is not defined

I am working with esp32 and trying to use the i2c library. There is a config struct. typedef struct{ i2c_mode_t mode; /*!< I2C mode */ int sda_io_num; /*!< GPIO number for I2C sda signal */ int scl_io_num; /*!< GPIO number for I2C scl…
kyrpav
  • 756
  • 1
  • 13
  • 43
2
votes
1 answer

I²C Communication from Scratch in C on Raspberry Pi in Linux

I want to create a small library for communication with I²C devices, especially the MPU6050 accelerometer / gyroscope module from scratch in C. Technically, I could use a library like wiringPi, but.. where is the fun with that. Right now I'm trying…
Merlin0216
  • 317
  • 2
  • 12
2
votes
1 answer

I2C, pullup resistors (STM32 discovery)

I am sending my data trought I2C (using DMA every 1s). I´ve added two pullup-resistors to SCK and SDATA. There are now slaves, so because no respond, master send only slave adress and thats all. Its testboard so sometimes happend thats I loose these…
Meloun
  • 13,601
  • 17
  • 64
  • 93
2
votes
2 answers

I2C linux drivers

I will need to write my own drivers for few controllers in my chipset.I work on SoC with SDK, that doesn't provide "linux i2c compatible" driver. It has simple char driver for i2c. I would like to use some standard i2c RTC drivers. I assume I will…