How I2C Communication Works and How To Use It with Arduino

Hello, Dejan Nedelkovski here from In this tutorial we will learn how the I2C communication
protocol works and also we will make a practical example of it with the Arduino
board and a sensor which uses this protocol. The I2C communication bus is
very popular and broadly used by many electronic devices because it can be
easily implemented in many electronic designs which require communication
between amaster and multiples slave devices or even multiple master devices. The easy implementation comes with the fact that only two wires are required for
communication between up to almost 128 (112) devices when using 7-bit addressing and up to almost 1024 (1008) devices when
using 10 – bit addressing. How is that possible? Well each device has a preset ID or a unique
device address so the master can choose with which device will be communicating.
The two wires or lines are called Serial Clock (SCL) and Serial Data (SDA). The SCL line is the clock signal which synchronize data transfer between the
devices on the I2C bus and it’s generated by the master device. The other
line is SDA line which carries the data. The two lines are “open-drain” which
means that pull-up resistors needs to be attached to them so that the lines are
high, because the devices on the I2C bus are active low. Commonly used
values for the resistors are from 2K for a higher speeds at about 400 kbps
second, up to 10 K for lower speeds at about
100 kbps. Okay now let’s see the data protocol of the
I2C bus. The data signal is transferred in sequences of 8 bits. So
after special start condition occurs comes the first 8 bits sequence
which indicates the address of the slave to which the data is being sent. After each 8 bits sequence follows a bit called Acknowledge. After the first
Acknowledge bit in most cases comes another addressing sequence but this
time for the internal registers of the of slave device. After the addressing
sequences follows the data sequences as many until the data is completely and it
ends with a speacial stop condition. Okay let’s take even closer look at
these events. The start condition occurs when the data line drops low while the clock
line is still high. After this, the clock starts and each data bit is transferred
during each clock pulse. The device addressing sequence starts with the most
significant bit first and end with the least significant bit and it’s actually
composed of 7bits because the 8th bit is used for indicating whether the
master will write to the slave (logic low) or read from it (logic high). The next bit Acknowledge is
used by the slave device to indicate whether it has successfully received the
previous sequence of bits. So this time the master device hands the control of the SDA
line over to the slave device and if the slave device has successfully
received the previous sequence it will pull the SDA line down to the
condition called Acknowledge. If the slave does not pull the SDA line
down, the condition is called Not Acknowledge and means that it didn’t
successfully received the previous sequence which can be caused by several
reasons. For example, the slave might be busy, might not understand the received data or cannot receive any more data and so on. In such a case the master device decides how it will proceed. Next is the internal registers addressing. The
internal registers are locations in the slave’s memory containing various
information or data. For example, the ADXL345 accelerometer has a unique device
address and additional internal registers addresses for the X, Y and Z axes.
So if we want to read the data of the x-axis first we need to send the device
address and then the particular internal register address for the x axis. This
addresses can be found from the datasheet of the sensor. After the addressing the data transfers sequences begin either from the master or the slave
depending on the selected mode at the Read / Write bit. After the data is
completely sent the transfer will end with a stop condition which occurs when the SDA line goes from low to high while the SCL line is high. That’s how the I2C communication
protocol works and now let’a make an example and demonstrate it using the Arduino Board and some sensors. So as an example I will use the GY – 80 breakout board
which consists five differences sensors and the GY – 521 breakout board which consists three
different sensors. So we can get data from eaight different sensors with just two wires
with the I2C bus. Here’s how we will connect the boards. The Serial
Clock pin of the Arduino board will be connected to the Serial Clock pins of the two
breakout boards and the same goes for the Serial Data pins and also we will power
the boards with the Ground and 5V pins from the Arduino board. Note
here that we are not using pull-up resistors because the breakout boards
already have. Now in order to communicate with these chips, or sensors we need to know their unique
addresses. We can find them from the datasheets of the sensors. For the GY-80
breakout board we have the following four addresses: a hexadecimal 0x53
for the three-axis accelerometer, a hexadecimal 0x69 for 3 Axis Gyro, a hexadecimal 0x1E for the 3 Axis Magnetometer and a
hexadecimal 0x77 for the barometer and thermometer sensor. For the GY-521
breakout board we have only one address and that’s the hexadecimal 0x68. We can also
get or check the addresses using I2C Scanner sketch which can be
found from the Arduino official website. So if we upload and run that sketch we will
get the addresses of the connected devices on the I2C bus. Ok so after
we have found the addresses of the devices we also need to find the addresses of
their internal registers in order to read the data from them. For example if
we want to read the data for the X axis from the 3 Axis accelerometer sensor of the GY-80 breakout board we need to find the internal register address where
the data of the X axis is stored. From the datasheet of the sensor we
can see that the data for the X Axis is actually stored in two registers, DATAX0 with a hexadecimal address 0x32 and DATAX1 a hexadecimal address 0x33. Now let’s make the code that will get the data for the
X axis. So we will use the Arduino Wire library which has to be included in the
sketch. Here first we have to define the sensor address and the two internal register addresses that
we previously found. The Wire.begin() function will initiate the Wire library
and we also need to initiate the serial communication because we will use the
serial monitor to show the data from the sensor. In the loop() we will start
with the Wire.beginTransmission() function which will begin the
transmission to the particular sensor the 3 Axis accelerometer in our case.
Then with the Wire.write() function we will ask for the particular data from the two
registers of the X axis. The Wire.endTransmission() function will end
transmission and transmit the data from the registers. Now with the Wire.requestFrom() function we will requires the transmitted data or the two bytes from
the registers. Wire.available() function will return the
number of bytes available for retrieval and if that number match with our requested bytes, in our case two bytes, using the function we will
read the bytes from the registers of the X axis. At the end we will print the data
in the serial monitor. Here’s that data but keep in mind that these is raw data
and some Math is needed to be done in order to get the right values of the X
axis. You can find more details for that in my next tutorial for using
accelerometers with the Arduino Board because I don’t want to overload this
tutorial because its main goal was to explain the I2C communication

100 Replies to “How I2C Communication Works and How To Use It with Arduino

  1. sir i have little confusion in Sensor device address, how did u find the hexadecimal value of sensor, please explain

  2. Thanks man, I appreciate the video. I wonder what kind of issues you could run into if you ran 1024 10 bit devices on the same line. Electromagnetic interference may become a concern.

  3. OMG dude that was perfect. I have been struggeling with i2c for a while now but this made it click. THANKS! 😀

  4. There is a mistake. All power source wires are connected to the ground of an Arduino Mega shield on the wiring diagram.

  5. Where do you get data sheets? I never heat any documentation with components we buy. I need a data sheet for CJVL53L0XV2.

  6. I remember when we had to write this entire protocol in bit-wise format, now you just call a couple pre-written functions in the 'wire.h' library.
    Life is getting a little too easy 🙂

  7. For connecting, how long can the 2 wires be that join 2 Megas?

    Can the wires be straight (like in a telephone cable) or do they need to be a twisted pair, like in a network cable?

    If I don't use wireless for my project and if I can get this working the way I want it to, there is already 2
    available wires going from the basement where the furnace is to the 1st floor where the thermostat is.

    I'd say, it's probably less than 10 feet.

    The line I speak of, that goes to the thermostat has 4 wires in it. Two of the wires are the 24VAC for the thermostat. The other 2 are not used. Not shielded.

    Should that work?

  8. Hi dear. I m working in electronics services we use to do customization for some electronics board. Here I need one help on I2C touch enabled board.
    Normally Touch board will come with only USB +/- and SCL SDA. But how to control the I2C enabled touch board

    Pls suggest
    Pins in I2C

    My Skype : SHRIDHAR.B3

  9. How does one get an account on digitalintercept? I'm working on a project that would really benefit from an xbee arduino sniffer.

  10. I always like tutorials that show how to use sensores without relying on 3rd party libraries other than the wire one. Very useful for learning.

  11. 9:11 You have a bug in your code. You check if Wire.available() is equal to or less than 2. This would also result in true if Wire.available() returns 1. Then you read 2 bytes in any case. In the case 1 byte was received, you are reading one other random unknown byte.

  12. There is an extremely annoying but hardly audible thumping noise in the background.. I just can't watch this video with that sound..

  13. Can you please make tutorial on integration of Mpu6050 with ble ic cc2650 or cc2650 launchpad
    Because there is very few information available on it

  14. This is a great video, thank you. my only criticism is, would it be possible for all the level changes to be to vertical? I know its not "real" but I find it much easier to see where the state changes line up of the clock and data lines….
    But definitely the best video i've seen explaining this.

  15. Good vid spoiled by music over your voice.
    I know I'm going to explain a complex topic and then add background music to break the students/ viewers concentration.
    If that doesnt make learning more difficult I dont know what else would.
    Thumbs up for content, thumbs down for adding music.
    Positive + negative = negative
    Sorry overall thumbs downn because of music over voice.

  16. Waddup guys. I have a question. What do I do if I want to read a sensors data, even though I don't know the internal register? The Sensor I'm struggling with OWLG 4012 AE S2.

  17. Hi. Can you help me edit this code?
    I want to add a library I2C
    When you press boutron ON .Sand 1.if When you press boutron off . Sand 2
    thank you so match

  18. this information is totally wrong… you do not need to put any resistors at the end of the line. adding resistors will cause the lines to malfunction and short circuit the chip…

  19. This was an informative and helpful video. I also liked how you explained with graphics. It made things easier to understand.Thank you and please keep doing more videos like this for beginners like me. Best regards.

  20. Thanks for a great explanation. Would it be possible that you do a video of how the arduino commands on the IDE are converted to signals on the wires. I feel there is a disconnect between the protocol explanation at the beginning and the arduino program. Also if you can add a link to the other video that you mentioned as completion to this one

  21. at the end u need 4 wires, ground, power, SCL and data. bewatre of voltages, couse recent sensors and some different arduino version need 3.7 and not 5v as powersupply. nice video|

  22. Can you please explain what is going on in the void setup in a bit more detail. Didn't understand it properly. Like what with the Power_Register and Wire.write(8)

  23. 2 hours of reading and then here comes this video where everything is well explained in under 10 minutes… You tube is spoiling me…

  24. What assigns the address to each device? is it assigned at the time of the manufacturing or the master assigns the address to each slave?

  25. Can someone help me to figure out how to build own nanoleafs? I want to detect with a esp32 automatic how much own panels are connected and set individual colors and animations. But how can it set automatically number up the IDs for every panels? Every panel should have 18 rgbw LEDs. I don't know which LEDs I have to choose.

Leave a Reply

Your email address will not be published. Required fields are marked *