This project was designed to help me solve a problem with the placement of sensors and the limitation that the i2c cable length introduced. As my projects were outdoors, I wanted to place the micro-controller in a protected spot but sensor placement requirements often forced me to compromise. I started looking at communications protocols like CAN that could support longer cable lengths but the increased cost and limited native CAN support for popular sensors kept bringing me back to i2c.
Note: I am a maker, not a EE. My approach here is pragmatic not theoretical. Please feel free to leave comments on how I could better explain the concepts as I am always open to learning. My goal in this application note is to share an approach and a design that has worked reliably for me.
According to the i2c specifications (see attached PDF from NXP - Table 10), the i2c Standard Mode (100kHz) specifies a load limit of 400pF. It is capacitance that determines how long your i2c cable can be not resistance (100' of CAT5 introduces only about 2.5ohms). Think of capacitance as a "tax" you have to pay before the voltage in the line will move in the direction you need it to move. That means you need move more current to keep the delay times (td) low enough to maintain the integrity of the pulses that make up the i2c data you want to send. The range extender chip increases the current available to drive this signal which enables it to work over a longer cable.
It is difficult to measure the bus capacitance of your system but you can use the following rule of thumb: 10pF for each i2c device, 10pF for the micro controller and 10pF stray capacitance plus 50pF per meter of CAT5 cable. Since i2c can accommodate 400pF at most, this gives you about a 7m limit and, in my experience, things get flaky long before that. To reliably connect sensors with longer cables, you should consider an i2c range extender.
I chose the TI i2c extender though there are other vendors offering similar (and pin compatible) options. The idea was to add an in-line adapter to use with my existing micro controller boards and sensors. I also started to put the pads for the extender on my micro controller boards as options. The TI range extender adds a buffered bus that can connect local and i2c busses. On each end, you can still make use of the 400pF capacitance limit for i2c devices. The long cable is on a "buffered bus" with a load limit of 3000pF. For CAT5 cabling, that equates to about 60m length between the local and remote i2c devices. From the TI manual, the minimal system diagram looks like this:
This gives you a significant flexibility as you can still have one or more i2c devices on either end of the buffered line AND you can connect multiple buffered lines together make a large star-topology sensor network. Very cool but, as with all things in engineering, there is a cost. Driving these long cables takes significant power. Each line over the buffered bus can sink up to 30mA so, if you are using an Arduino and some i2c sensors such as accelerometers, you will probably discover three things: 1) the i2c extender will likely be the biggest consumer of power in your system; 2) you will not be able to power this bus directly using Arduino and 3) you likely need more than just battery power. The good news is that you only have to power one end, and the long cable length means that you may well be able to have your micro controller near an outlet while your sensors are out in the world collecting data.
I have uploaded the EAGLE files and OSHPark project page so you can make or order your own boards. OSHPark will sell you three bare boards for about $2 including US shipping - and no, I do not get a commission unfortunately. For my board, I used a 6 wire connection in case your i2c sensor has a couple interrupt lines as my Sparkfun MMA8452 accelerometer did. You will need to calculate the appropriate pull-up resistors with the Buffered Pull Ups being the most important:
- Local and remote pull up value (ohms) = 1 uSec / (10*n + 20)pF - for a 100kHz bus where n is the number of i2c sensors.
- Buffered pull-up value (ohms) = 1uSec / (m * 50)pF - for a CAT5 cable where m is the number of meters
- I put buffered pull up pads on each in-line board but, you only need to put them on one end - not both.
- If your local and remote pull-up values are greater than 10k, you can experiment with leaving them off as they may not be needed.
Some notes that you will need to keep in mind as you implement one of these distributed sensor networks:
- i2c is "open drain" which means that the definition of a "high" logic level is defined relative to the pull-up voltage. The TI chip can operate from 3-12V but the performance of the extender will degrade below 4.5V. I had no problem extending my 3.3V sensor over 100' but there is a trick you can use if you are - like me - operating at lower voltages. You can use a higher voltage to power the i2c extender chips and the buffered bus. That way, you could have a 3.3V micro controller and 3.3V sensor but get better range extension by running the range extenders and the buffered bus at 5V.
- In the calculations for the pull-ups above, the 1uSec value came from the rise time needed to support a Standard-Mode 100kHz clock speed. If you run your i2c bus at Fast-Mode of 400kHz the rise time shrinks to 300uSec (see NXP manual Table 10). This will reduce the resistance of the pull-ups which will increase the current drawn by the bus. Note, the minimum resistance to stay within the per line 30mA max current is 170 ohms. So, you will need to trade off i2c clock speed with current.
- I used twisted pair CAT 5 cabling. In these cables, there are four twisted pairs with each pair color coded. It is important that the SDA is in a twisted pair with 5V and SCL is in a twisted pair with Ground for best results.
Finally, as I will be putting these sensors out in the woods and it would be a pain if they were not reliable, I thought it would be good to look at the signals with an oscilloscope and a logic analyzer to "see" if the range extender was maintaining the integrity of the signal. The results are interesting. From the perspective of the logic analyzer, the signals are idealized and look the same with and without the extender as below. This is good as the i2c data stream is what matters to your project.
However, when you look at the SCL and SDA signals using an oscilloscope, there is a different story. The pictures looks much less robust and, while it still crosses the thresholds to transmit the data, I have to imagine that this signal may have some reliability issues. I will need to think of a way to perform a long term test to see if I can see even small error rates creep up.
If you use EAGLE, I have attached the files but you can view the schematic and board images here in case you do not have that software. I tried to keep it simple and make the traces as wide a possible. You can also integrate these extender chips onto your micro controller board.
I hope you find this project helpful and the longer tether for your i2c sensors will help you build better connected and more flexible projects. Please leave comments and suggestions below.