Sketch to Measure and Calculate I2C Pull-ups




Introduction: Sketch to Measure and Calculate I2C Pull-ups

Hello! This Instructable is for a software only project that anyone with an Arduino UNO can perform. It is basically a modified capacitance meter sketch and is very useful to indicate the proper range of pull-up values that you can use in your I2C communication setup.

We made this as an answer to a common question that gets asked for paralleling I2C slave devices. In our case it was for a new high performance I2C laser distance sensor module we created called tinyLiDAR. For example you can make one Arduino UNO control many of these devices running in parallel for a single robot navigation setup as shown in the picture above.

Step 1: Theory

There are basically two ways to determine the I2C pull-ups: the DC approach and AC approach.
For the DC approach, you can simply calculate the minimum pull-up resistance value based on the I2C standard and your supply voltage level. But this approach also dissipates the maximum power in your design.

The AC approach yields the maximum practical pull-up resistance for which you can run your design properly at minimum power dissipation. To use this, you will need to measure the capacitance of your wiring and add to this the actual number of devices you will be using.

Most designers either stick to the DC only approach or use a guesstimate for what their system capacitance is. Hence they are always on the low side and therefore dissipate more power than necessary in the I2C bus.

This sketch will provide both values. As mentioned above, it was designed for tinyLiDAR but you can simply set "tinyLiDAR_capacitance" to zero or change it out for your particular I2C slave devices.

Let's run through some of the theory, starting with the simplest.

The DC Approach:

The I2C standard provides limits for thresholds and rise time.

For our application at 100KHz clock rate, the important limits are as follows:

IoL, LOW-level output current = 3mA min

VoL, LOW-level output voltage = 0.4V max.

The Arduino supply voltage, VDD = 5V nominal, so we get the following for net pull-up resistance Rp:

Rp= (VDD - VoL)/IoL

Rp = (5-0.4)/3mA

Rp = 1.53K

The AC Approach:

For this method, we need to minimize the rise time (Tr) of the signal based on actual bus loading. Refer to Figure 1 for terms. Rise time is affected by the net capacitive loading of the bus and the net resistance used for the pull-ups.

The I2C standard specifies the input voltage thresholds as ViL = 0.3VDD to ViH = 0.7VDD levels. It also specifies a maximum rise time, Tr = 1000ns for a 100KHz clock rate.

Generally, the voltage on a charging capacitor is defined as shown in green in Figure 1. Hence we need to ensure the rise time is below 1000ns while the voltage rises between the two input voltage thresholds for our capacitive bus loading.

Solving for the input voltage levels, we can see that it will take a time of 0.3567RC to charge up to ViL and 1.2040RC to charge to ViH. The difference is our required rise time of 0.8473RC.

Knowing this, we can find Rp = Tr/(0.8473*C).

Step 2: Sketch

Our sketch will measure C and automatically add the parasitic capacitance as required for the number of I2C modules you have connected. Just enter how many you are using and press enter to run the sketch. It displays the results on the Arduino IDE terminal at 115200 baud as shown in the screen shot above.

Note that the above methods provide the net pull-up resistance. Each tinyLiDAR has 0603/1608 size SMD pads for two pull-up resistors - one for SDA and one for SCL, hence the sketch provides a range of pull-up resistor values for these resistors to be placed on each and every board used in your setup.

Enjoy the sketch and please visit our Indiegogo campaign for tinyLiDAR soon if you like this kind of stuff. tinyLiDAR is basically a gereral purpose laser distance sensor board that simplifies access to the VL53L0X chip and gives better performance than a software only approach. We just started the campaign on July 14th and need everyone's help to bring tinyLiDAR to life.

Thank you!

Be the First to Share


    • Organization Challenge

      Organization Challenge
    • Anything Goes Contest

      Anything Goes Contest
    • Baking Contest

      Baking Contest



    5 years ago

    Hi guys. I need some help for a design. What I want to do is build a distance scanner. I have got a 23000l round tank the length is 6meters. So what I want to do is measure the internal of the tank starting from the bottom slowly moving upwards and basically record the distances with its 360 degree turns and with the recordings generate a dipping table on Microsoft excel to tell me how many liters is in the tank with increments of 2mm. So if I use a dip stick marked in millimeters to dip the tank when it's full of fuel it will show me for example 700mm then I look on my dip table and see 700mm=3000litres. Do you guys think it's possible to design and build something like this. If yes. I will buy it immediately lol

    danderson jr
    danderson jr

    5 years ago

    Hi, please tell me where i could purchase the i2c cables and 4 port junction board above? Do they make a 6 connector board? Also where can a purchase the readout screen shown above. Have purchasrd 5 of your sensors and look forward to using them in my project. Thanks for any help you can provide.


    Reply 5 years ago

    Hi Don, thank you for the questions and for your support.
    The cable assemblies we used were the "Grove" type 4pin cables from Seeed Studio, sourced through DigiKey.
    Part numbers were 1597-1092-ND (MPN 110990210) for the Grove to 4pin male header types which can be inserted into your breadboard and 1597-1079-ND (MPN 110990031) for the Grove to Grove 4pin "un-buckled" type cables. We prefer the un-buckled type (instead of buckled) as they require less force when removing them from small boards.
    The 4 port PCB is called the Grove I2C Hub, Digikey part number 1597-1324-ND (MPN 103020006) and unfortunately is only available with 4 connectors. We just used a breadboard to connect more I2C ports in parallel with the 1597-1092-ND cables.
    The OLED display was a generic 128x64 SPI OLED display module driven with the U8g2lib. It was sourced a long time ago so can't recall exactly where we got this one from but there are a lot of nice low cost displays available online. The U8g2 library can pretty much drive all of them: Hope that helps.


    Reply 5 years ago

    Thank you Jason! Your kind words are much appreciated :)