Make a sensor interface for your computer for under a buck!

Update 6/9/08: After exploring several avenues I've concluded there is no practical manner of implementing this technique in Microsoft Windows. This is not petty OS bashing, I've really busted a nut trying! Sorry! Windows users needing I2C capabilities are best served by existing USB-based solutions.

Update 5/24/08: Linux support has been added, as well as sample code for the Nintendo Wii Nunchuk controller and the BlinkM "smart LED." See the README.txt file included with the source code for directions on compiling and setup on Linux.

I2C (short for Inter-Integrated Circuit) is a two-wire serial bus typically used in computers for low-level communication between internal components. I2C is also popular in robotics. All manner of sensors and actuators are available in an I2C-compatible form: ultrasonic rangefinders, sensors for acceleration, tilt, temperature and pressure, servo controllers, and bus expanders that provide additional general-purpose (GPIO) lines.

Most modern microcontrollers (Atmel, Microchip PIC, etc.) have support for I2C built right in. But the processing power available on microcontrollers is limited, and software development - with specialized cross-compilers and programming environments - can sometimes be a chore. With laptops and single-board computers becoming ever smaller and more affordable, it's increasingly common to see these systems used directly in robotics and electronics projects. This provides ample power for new capabilities such as vision processing and more sophisticated A.I., and it greatly expands the scope of available development tools and languages...but it also presents a new problem: interfacing these "regular" systems to peripherals is typically done through mainstream consumer-grade ports such as USB; there's no externally-available "I2C port" we can just tap into to make use of our sensors...or is there?

Step 1: Existing Options

One way of connecting I2C devices to an ordinary desktop or laptop computer is through a USB-to-I2C adapter. There are at least a dozen such options out there, ranging from do-it-yourself kits with open source software, to sophisticated commercial units with every bell and whistle.

One downside to the USB-to-I2C approach is cost. A full-featured commercial model can cost $250 or more. Even the "free" homebrew alternatives assume a collection of parts and a prior investment in a microcontroller programmer and the related knowledge to make use of it. Another downside is the relative scarcity of driver support outside the popular Windows fold. Few of these devices work natively on Macintosh or Linux computers.

Step 2: DDC Is I2C

When I said in the introduction that there's no external I2C port on most computers, I lied. Turns out there is, and it's been there all along for nearly a decade now, mostly sitting dormant.

Most modern graphics cards and monitors have support for something called Display Data Channel (DDC), a communication link within a video cable that allows the computer and display to negotiate mutually compatible resolutions and permit software control of monitor functions normally accessed with physical buttons on the display.

DDC is, in fact, simply an implementation of an I2C bus with a few established rules. By tapping into this connection between the computer and monitor (or making use of the DDC lines on an spare unused video port, such as the external monitor connection on a laptop), one can interface with some I2C devices at virtually no expense, bypassing the usual need for an adapter device entirely.

All we need to physically access this I2C bus is a hacked-up video cable...

Step 3: Dissecting the Cable

Four wires are needed for our I2C interface: +5V power, ground, serial data and serial clock. Pinouts for the various types of video ports can be found on Wikipedia or Pinouts.ru. Remember if using a VGA cable to find one with the full complement of pins; some only include a subset.

Cutting back the insulation and shielding from the outside of the cable, you'll likely find two groups of wires within. Thicker wires, or bundles of wires wrapped in additional shielding, usually carry the video signal. We're not interested in these and they can be trimmed back. Thinner, unshielded wires usually carry the DDC (I2C) signals among others. A multimeter or continuity tester can help in finding the correct four wires for your cable. Using a bare connector can be advantageous here, as you just need to solder four wires to the pins of interest.

A note on the +5V power: available current is very limited; about 50 mA according to the DDC specification. Most I2C devices sip just a tiny bit of current, so it should be possible to run several at once...but if using more than one or two LEDs (or other comparatively high-current devices), external power should be provided.

Step 4: The Completed Adapter

Here's the finished adapter. That's all there is to it! I made mine extra stubby so it could fit easily in my laptop bag, and added a four-pin plug that connects directly to an I2C servo controller that I have.

Step 5: Software and Projects

Mac OS X and Linux source code for working with the adapter can be downloaded from my web site (download link is at bottom of page). It's written in C, and you'll need to have gcc installed (Linux usually includes this by default, while Mac users will need to install the developer tools that are an optional installer on your original OS disc, or downloadable free from Apple). Example code is included for reading a temperature sensor, flashing a BlinkM "smart LED," writing and verifying a serial EEPROM, reading a Nintento Wii Nunchuk controller (Linux only), and communicating with a servo controller board.

Unfortunately this adapter scheme is not compatible with all systems. Support for DDC is not mandated, so not all video cards support this capability. I've had good luck thus far with Mac systems that have ATI or Intel graphics chips, but NVIDIA-based systems are out of luck. On the Linux side I've only successfully tested an IBM ThinkPad A31p (ATI graphics), but it would not work with an Asus EeePC (Intel).

The images here show a test rig that demonstrates various I2C devices in action. The computer continually reads the ambient temperature from an I2C temperature sensor, periodically logs this data to an I2C serial EEPROM chip (yes, it could just print to a file, but this was to further demonstrate I2C applications), and then a servo (through an I2C controller) serves as a makeshift indicator dial. With the library and sample code for these devices already in place, it only took a few minutes to put together this demo (and most of that was in making the indicator dial).
<p>how about an arduino and a small bit of software on it.. then serial to PC? less than $20 </p><p>The arduino recieves commands from the PC and handles the read/write etc to the IC2?</p>
<p>couldn't you use the Bus Pirate as a cheap/simple adapter?</p><p>http://dangerousprototypes.com/docs/Bus_Pirate</p>
Can most PC's and video cards act as an I^2*C slave?
<p>only if software is already on the pc.</p>
<p>also i noticed they are using a vga to usb or something? may be completely different then strait from vga.</p>
<p>okay i have messed with this for some time now. i have a human interface to i2c bread board made with an accelerometer on it and now i have added my monitor's eprom at i2c address 10100000 which is standard for ddc or edid. all of these things i can access now via the human interface or basically push buttons i made. i can input the 2 address and the devices will hold the data line low in an ack. what i dont get is that the hdmi has a i2c 5+v line which is used to provide power to the eprom and originally i figured that would not need to be powered cause the pc will power it, well it doesnt or at least not for more than a few micro seconds that it uses the eprom to get edid of which i am blind to. so i had to power it but the monitor's eprom responds. also i am powering the open drain i2c bus. i believe when the display adapter is on then i will no longer need to as it will. the problem is how do i turn it on in windows and use the lines? i have been looking into i2c callbacks i believe interfaced by the video port driver in it's videoprt.sys files. i can get it to compile but it does not seem to work with the actual hdmi ports i2c lines? msdn documents that all for callback routines require the HwDeviceExtension as arguments and then the 2 write routines require an additional data value that is either 1 or 0 for what to actually write the line. everything compiles however i do not have a pointer to the hwdevice extension so i just leave it empty and it compiles, however in visual stuidio it will not accept 2 arguments which is weird cause msdn says 2? now i know these are not probably supposed to be functions accessed from outside the driver in a manner that i am accessing them however my code seems to compile which it shoudnt if they were not actually accessable? i wonder now if i use vidgetassociatedriverextension(device_deviceobject) and device object the monitor currently on, could i use that device extension? i also tried holding say the clock line low and then a for looping going through integers for device extension hopping that one would actually read the line low and then stop and tell me the integer reference to the device extension but that doesnt seem to work. im not even sure if these functions are even being acccessed write from the .sys file or if they are just defaulting to something useless like it just returns my argument that i inputed?? if anyone gets further should comment as this is the best source really for this. i will try posting a youtube vid of what i have so far maybe.</p>
<p>Derin, </p><p>Aquarela Systems designs and manufacturers i2c adapter in USB stick.</p>
Do you seriously think that you can't get away without the voltage pin?
Dormant? Quite not. It's used to get the name and supported modes of the monitor.
hmm that's wrong.. on windows there are several options to access i2c on nvidia, amd or intel cards. For example, google for WinI2C. Also, usingi NVAPI (again, google is your friend) is possible to use I2C on any nvidia card (I coded a small program to do that!).
I have not tried this but it looks interesting.<br>http://www.maxim-ic.com/app-notes/index.mvp/id/3230
When you say that it doesn't work on the Eee PC, which one are you referring to? I have the 1000HE.
AHHHHHHHHHHHH!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!THEY DONT SELL USB TO I2C ADAPTERS HERE AND IM NOT ALLOWED TO USE LINUX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
what do you mean by"IM NOT ALLOWED TO USE LINUX!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" who cares if they don't want you to use linux...setup your own in a usb thumb drive
There are several options. First you can install Cygwin and probably with some minor tweaks in the code get it to compile and run under Cygwin. Second, you can just replace the platform specific code (which there probably isn't much of being a Linux program) with Windoze code (I'm assuming the source is OSI, MIT or some other similar license).
do you have a schematic for this, as i was interested in making a PCB for one thanks good i'ble
So, there is no way to do this with a macbook pro since it uses an Nvidia graphics card?
will ati cards on a pc work?
Howdy! This should work with most ATI cards if you're running Linux (I don't have any Windows code yet). If you download the source from my site (www.paintyourdragon.com/uc/i2c) and look in the README.txt file, there are some instructions specific to Linux (regarding 'modprobe' and whatnot) that will give a pretty good indication of whether a particular card can support this or not.
Unfortunately no, unless it's an older (2006) ATI-based MacBook Pro. Or at least that's been my experience so far with a couple of other NVIDIA-based Macs I've tried thus far; I've not tested this exact configuration yet. Sorry!
And a page on linux:<br/><a rel="nofollow" href="http://sourceforge.net/projects/ddccontrol/">http://sourceforge.net/projects/ddccontrol/</a><br/>
Shareware version of software for windows:<br/><a rel="nofollow" href="http://www.nicomsoft.com/">http://www.nicomsoft.com/</a><br/>
This isnt really a robot, so why is it entered in the robot contest?
Because it is both brilliant, and robotic control related. So far, it gets my vote.
From the contest rules: &quot;we're asking you to document specific <em>parts</em> of your robot for this contest.&quot;<br/>
ah i missed that. just realized the servo too. Hope to see more soon.
Great stuff! you should definitely get a wiimote, tear it apart, and look into getting your code to talk directly to the wiimote's camera module, which speaks I2C - doing this increases the tracking rate to 200Hz: <a rel="nofollow" href="http://procrastineering.blogspot.com/2008/03/tracking-multiple-laser-pointers-200hz.html">http://procrastineering.blogspot.com/2008/03/tracking-multiple-laser-pointers-200hz.html</a><br/>
Any 1 got an example for windows driver source code?
I did some googling around and it appears that nvidia does have a ddc bus and that it can be configured in x configuration, this is in linux. Why do you say that it can't be done with nvidia cards?
Greetings! My "doesn't work with NVIDIA" remarks were intended to be specific to Mac OS X. I'm sure the situation will be different on other platforms, just haven't delved deeply enough on the Linux or XP sides to be able to quantify this yet. The pointers are appreciated. I'll have a look at the X server code for ideas when I have time to get this going in Linux.
were can i buy a I2C temperature sensor. Thanks for the help
The example temperature program uses a Microchip TCN75A, which I ordered from the manufacturer at <a rel="nofollow" href="http://www.microchipdirect.com/">Microchip Direct</a> (mind you, this particular sensor is only available in a surface-mount version, so if you're going to use it on a prototyping board, for instance, you'll have to add &quot;spider legs&quot; or use a socketed adapter). If you're persistent, sometimes components turn up from time to time on eBay.<br/>
there appears to be an arduino clone that has a USB bootloader that can connect direct to the usb with no ftdi chip or usb to ttl board. its on the arduino.cc forums somewhere.
There are AVR USB hacks (probably converted for use with the Arduino), but they have sever limitations: USB 1.1 only, they need a specific xtal (so they are useless if you need a different clock source), sometimes require "overclocking" the AVR, take up valuable programming memory, IRQs, etc. There are a couple USB-capable AVRs, but PIC seems to do USB better. But the i2c interface is directly supported by the AVR hardware (it's hardwired logic, not software.)
A lot of PICs have hardware I2C! :)
Sorry, I didn't mean to imply that they didn't. Both have several comm protocols in hardware....
i have only just heard of i2c. i already knew that the atmega168 and 8 had ttl serial, but this i2c is something i am gonna look into :)
Atmel calls i2c a "two-wire serial interface." I guess they didn't want to pay for licensing the "i2c" name or technology--just create a compatible version. Could be why you hadn't heard of it....
i2c has a thousand names as phillips didn't actually patent it but only holds the trademark. It's probably not a matter of cost but rather ability, from what I've heard phillips is pretty picky about who they let in on their licensing of i2c. 2wire is a pretty common name for it though that tends to show up anywhere the other names are mentioned.
Great instructable! I'll test it soon, I hope to find some info on how to use the DDC in win XP.
Let me know when you make any progress with the I2C adapter on XP - I too have an XP and would love to try this, but I'm busy on another project right now.
what's the bandwidth on this port? I ask because I'd like to consider using this as an oscilloscope channel, but I'd like to know what the top end of the frequency range is that I'd be able to measure. I can handle voltage scaling by putting in my own external opamp.
Howdy! It's either 100 or 400 KHz; I've read contradictory figures online, and unfortunately the official DDC specification costs a fair chunk of change. The bandwidth I'm seeing when reading/writing an I2C serial EEPROM leads me to believe it's the 100 KHz figure.
Thanks! I appreciate your prompt reply. 100 KHz could be helpful in some apps (I'm not working in RF just now, and more important to me just now is audio and logic pulses in automotive electronics systems - I need more than anything else to be able to sort signal from noise. Looks like that bandwidth might be of real help. Cheers again.
niiice. now I just have to look behind my PC to see if it has one of these DV thingys. does it work on Lunix?
In theory this could work on just about any video port; doesn't need to be DVI, both VGA and HDMI ports can support this capability as well. Haven't adapted the code to Linux yet, but that's something I'd like to do with it at some point. This recent rash of mini laptops like the Eee PC might make great and affordable 'bot brains.
Have you stole my batteries?;S
I think they could be anyone of half the worlds population... Same as mine too... ;)
Great stuff. With rs-232 and parallel ports disappearing, and USB not directly supported by most micros, this is an excellent alternative.
Thanks! I sure hope so. What remains to be seen is just how compatible this is with different I2C devices. I've only tested it with a few thus far, and while most have been rock-solid, communicating with the all-important servo controller has been a bit dodgy. My suspicion is that it's something peculiar to this specific controller, which was designed Lego Mindstorms use and might not like the full speed I2C being used here. With a device data sheet in hand, writing the code to talk to something new and untested only takes a few minutes. What I may do is bring my laptop and the adapter to the Maker Faire in a couple weeks and ask folks and vendors there if I can have a quick go at writing code for their I2C devices (which I'll then roll back into the sample code for the project).

About This Instructable




More by pburgess:Throbbing Apple Logo Sticker World's Cheapest I2C (I-Squared-C) Adapter 
Add instructable to: