Advertisement

Helvetica 'Foofers' Bold - Any Port in a Storm

Apr. 1st, 2008

02:35 am - Any Port in a Storm

Previous Entry Add to Memories Tell a Friend Next Entry

Macs, microcontrollers, embedded systems and assorted hacking.

If you’ve been reading this journal for like a billion years, you might recall some incidents a long while back where I was wanting do to some work with resins and silicones and whatnot, but my efforts were foiled by cool winter temperatures and an unheated garage. The matter was partially solved with the acquisition of propane and electric heaters…but as it was a struggle against the elements, I knew even these were a fix suitable for only the mildest winter days. The more practical other half of the solution was to simply adopt a cyclical annual hobby schedule: I would “play with chemicals” for the warmer part of the year and find something else constructive to do with myself for those months where epoxy will never cure.

This year it’s been electronics and microcontrollers. Partly it seemed a good complement to the chemical work; there are some applications for animatronics and costuming here. And partly was a dissatisfaction with a significant chunk of what I’ve seen from animatronics, especially at the hobbyist level: all canned sequences, straight lines and perfect interpolation. I’ve wanted to apply some methods of traditional animation here, such as anticipation and follow-through, ease in/out, etc. so as to achieve a more organic effect. I’m nowhere near the goal yet…in fact, most of the season has been spent just learning and tooling up.

We’ve hit spring and warmer temperatures are imminent, so a lot of this stuff will soon be shifting to the back burner as the chemistry season returns. I’d planned on making a post summarizing my findings with regards to various embedded systems and microcontroller platforms (with some emphasis on how they relate to the Mac) in order to have closure, but something came up last night…something so simple yet epic at the same time. I was going to work on my income tax today but this derailed everything.

In the fields of computers and robotics, one of the most fundamental interconnections between devices is something known as the I2C bus (“I-squared-C” — the 2 is supposed to be an exponent, but I’m too lazy for all the markup ahead). Yet there’s a good chance you’ve never heard of it…it’s not exactly like there’s an “I2C port” on the back of your machine next to the USB ports. This is something that’s primarily used internally as a lowest-level interconnect between system components. Your memory DIMMs, for instance…that odd tiny chip that’s on there in addition to the RAM chips? When you first flick on your system, before anything even boots, the CPU can’t so much address this RAM until the BIOS and that little chip have a conversation wherein the specifications for each and every DIMM (and many other system components) are conveyed. That little chat takes place across an I2C bus. That sort of low-level.

I2C is huge in robotics. Mostly because it’s dead nuts simple, requiring just two lines (aside from power and ground) and minimal coding, and also mostly because nearly every sensor, actuator and microcontroller in the known universe speaks the language. Ultrasonic range sensors, temperature sensors, pressure sensors, RC servo controllers, even the tiny infrared camera that’s inside the Wii remote…nearly all of that stuff intercommunicates at a very low internal level via I2C. It’s not especially fast, nor robust, nor feature-filled…but fast enough and robust enough for the task it’s being asked to do. And most importantly, omnipresent. If it’s a component and has pins, there’s a very good chance it’s I2C compatible.

I’ve wanted to make my own I2C servo controller as something of an exercise in microcontroller programming, and with obvious applications toward the animatronics goals. I’m not quite at that level yet…I’ve twiddled a couple of servos, and on other occasions have sort of willy-nilly almost talked across I2C…but haven’t brought it all together yet in anything that would be considered production quality. So as a shortcut in the interim I bought an existing I2C servo controller to play around with…that way I could mess around with the higher-level code right away and then come back to the nitty-gritty stuff when I had a better handle on it.



So there’s the controller…now I just needed the higher-level “brains.” I could just take a PIC chip and throw some commands out at it, but that wasn’t the point of the exercise; I needed something bigger and smarter (but that could still easily interface to and render I2C commands), and to that end also acquired a Gumstix embedded system along with the breakout board that would give me physical access to the I2C lines.

The Gumstix is adorable, reasonably well powered, very well-connected. But it’s also turned into a big clusterfuck of its own, which is one of the things I was going to write about in my survey of this stuff until today’s derailings. I know for a fact it can do the I2C things needed, I just haven't gotten to that stage yet amidst many thousands of other little projects and moving parts.

There’s probably a dozen different microcontroller platforms and embedded systems of all sizes that I’ve looked into, bought, dabbled with, whatever. At the bigger and beefier end, one such system being evaluated for possible higher-level-controller hack value was the Apple TV. No wait, seriously, hear me out. This actually has quite a few things going for it: it’s cheap (I got mine secondhand for $190, but even new they’re only $230 now), readily available if it needs replacing (just hop over to Best Buy, Fry’s, etc.), is running a full-fledged operating system (an only mildly castrated version of Mac OS X—which gosh, just happens to be my OS of preference…so no virtual machines, no cross-compilers), and is actually pretty well spec’d by embedded systems standards: 1GHz Pentium-M, 256 MB RAM, 40 GB disk, Ethernet and 802.11b/g/n connectivity. Sure, a Mac mini isn’t much bigger and has more horsepower…for $600! Oof. (And “quantity one” PC104 embedded systems are usually even worse!)

Downsides include power consumption (about 15 watts) and the USB port is pretty much disabled (there are some kernel hacks to get this working, but done wrong risk “bricking” the unit, so I’m holding off until I have a better understanding). Which is a real pity, as there are a lot of USB peripherals that could also have some applications for what I want to do; joysticks and other input devices, cameras (possibly for eye and face tracking), a few sensors and actuators that use USB instead of I2C…and for everything else, a USB to I2C adapter.

I've goofed around and done just about everything that could be done to the Apple TV without getting into the warranty-voiding realm of actually cracking the case open. But I was out of ideas for connecting to the things I wanted to connect to, so had just about reached that stage. Installing full OS X was one possibility (it's doable, and enables the precious USB port…in fact, it's possible to boot full OS X from an external drive without any case-cracking, but it’s such a pain in the rear that I only goofed around with it a handful of times). Or perhaps, as some folks have done in their hacking of the Linksys NSLU2 (a Linux-based NAS adapter), go rooting around for I2C lines on the motherboard to which things could be connected, and see if there’s any means of accessing these lines programmatically.

And it was in my research for the latter (which further reading indicates would’ve been a dead end anyway) that I stumbled upon that simple yet epic thing; a simple hack that obviates the need for the USB to I2C adapter, saving a good chunk of change for a commercial unit. Tested and confirmed today. There's no need for case-cracking, and the technique should be equally applicable to Mac, Windows or Linux. Oddest of all though…searching around the net, I haven’t seen anyone else doing this for robotics and sensor projects. This might be a first.

That bit where I said there’s no “I2C port” alongside the USB ports and other standard connections? I lied. It’s there, and it’s been there all along for about a decade now. Most modern graphics cards and monitors have support for something called Display Data Channel (DDC), an interface by which the monitor may communicate allowable operating frequencies to the graphics card so as to avoid “Out of Range” errors on the display. VGA, DVI, HDMI, they all have it. And it turns out DDC is nothing more than an I2C bus. Not even a fancy, tarted-up, “oh, but this one is special!” I2C bus. Have you seen those monitors that you pivot and the system redraws at the new orientation? That’s DDC. Which is just I2C. And which, yes, there is programmatic access to. The essential parts of the OS X code amount to just a couple dozen lines and work entirely in user space (no drivers needed).

I haven’t tested this on the Apple TV yet, as I’ve only just ordered the needed HDMI breakout cable and am awaiting its arrival (it was only $5 mail order, whereas buying an HDMI cable locally for dissection would’ve been $25+; I’m cheap that way). But I’ve goofed around with the idea on my MacBook and, holy crap, it works!

I already had a crappy $4 surplus DVI cable I was willing to donate to science. But first I needed an adapter to attach that to the MacBook’s “Mini-DVI” port (I know, hard to believe, a non-standard connector on an Apple product!*):



(*To be fair and balanced, from what I've read the Windows APIs for DDC are undocumented. So it’s 2008 and you've got a proprietary connector on the Mac side, and a hidden API on the Microsoft side. Some things never change.)

I chopped the DVI cable in half, unshielded a couple of inches and stripped the ends of the exposed wires, then (using a pinout found by way of Wikipedia), tested the continuity of each line to find the essential four that would interface to the I2C servo controller board: +5V, ground, serial clock and data. Soldered those lines to a 4-pin plug for the servo controller, plugged it into the Mini-DVI port, and got…BLUE SMOKE! No, I’m kidding. No blue smoke. The servo controller’s “heartbeat” LED indicated it was getting power, so that was good, but my commands to the I2C bus were having no effect (not generating errors, just no effect). But I already had a pretty good idea as to why…

The OS X function involved in accessing the DDC (I2C) bus requires a framebuffer (let’s just think of it as a screen for conversation sake) as a parameter. But without an actual screen connected to the Mini-DVI port (just my hacked cable and the servo controller), the computer was still operating in a single-screen state; the bus returned, if it’s connected to anything at all, pertains then only to the laptop’s internal display, entirely separate from the I2C lines on the DVI connection. What I needed was not a cable with DVI at one end and the four I2C lines at the other, but an actual connection to another screen, with the I2C lines tapping off that in sort of a “Y” cable configuration. So I had the pleasure of resoldering all the lines of the two halves of the DVI cable back together, tapping those four lines for the servo controller. Edit: I’ve since found a workaround and can communicate on the I2C bus without the second display attached.



What’s funny is that all of my current computers are either laptops or all-in-one systems. It’s only by a stroke of luck that I hadn’t hauled off this one monitor to e-waste recycling this past weekend. Although the monitor doesn’t work, it seems to apply whatever load is required on the lines for the Mac to think there’s a second display attached. So I just have to rig the code to query the external (second) display, connect my servo controller, and…MORE BLUE SMOKE!

No, no, kidding. It works. I’m now talking bidirectionally to the servo controller. Through the monitor port. Who’d’a thunk? No USB-I2C adapter to buy, no drivers to install, no open case or voided warranty.



Since the Apple TV only has the one HDMI port, I’m guessing (or maybe just hoping) that the single framebuffer is always present and queries the same regardless of whether it’s actually connected to a telly or not. And if that’s the case, then the whole Y-cable nonsense (not to mention lugging around a 120 pound TV set) is unnecessary. Just a hacked-up HDMI cable with the desired I2C sensors and actuators attached, and you’ve got an extremely potent, relatively cheap ’bot.

No foolin’. Maybe I’ll write this up for Instructables or Make or something!

(Leave a comment)

Comments:

[User Picture]
From:[info]athelind
Date:April 1st, 2008 02:11 pm (UTC)
(Link)
TOTALLY BOGGLED
(Reply) (Thread)
[User Picture]
From:[info]terraluna_bat
Date:April 1st, 2008 03:38 pm (UTC)
(Link)
WOW!! Very cool. I2C is truly the back bone of the computer industry. All mother boards seem to use it to internally communicate with its internal component.

I2C seem to be that really ugly, hunch back bell cleaner and player that no one wants to talk about, but everyone depends on to get the internal things in a computer, working.

!GREAT JOB! :) You earned your official Hardware Hacker Badge. ;)

I'm sure Make Magazine would love and publish your writeup. :)
(Reply) (Thread)
[User Picture]
From:[info]smashwolf
Date:April 2nd, 2008 01:17 am (UTC)
(Link)
He should follow it up with a write-up on JTAG, and how to kit bash or bit bash JTAG from cheap or existing hardware.
(Reply) (Parent) (Thread)
[User Picture]
From:[info]normanrafferty
Date:April 1st, 2008 04:02 pm (UTC)
(Link)
Don't you have some animatronic dinosaur toys that crave to be controlled?
(Reply) (Thread)
[User Picture]
From:[info]thoughtsdriftby
Date:April 1st, 2008 05:06 pm (UTC)
(Link)
Fun!

Ok, likely all the port wants from the monitor is some ram data, EDID - Extended display identification data. It lets the graphics card know what it's connected to and how to talk to it.

http://en.wikipedia.org/wiki/Extended_display_identification_data

You should be able to let the port know it's connected to Foofer's spiff servo controller.

And yes, please keep working on this. It has possibilities.
(Reply) (Thread)
[User Picture]
From:[info]smashwolf
Date:April 2nd, 2008 01:16 am (UTC)
(Link)
What I am wondering is if you even need an EDID device on the monitor port. I have analog devices that I connect to Apple, and that is enough to convince it that it indeed has an external monitor on it. Hopefully that wouldbe enough to get the i2C bus on the external port lit up.
(Reply) (Parent) (Thread)
[User Picture]
From:[info]thoughtsdriftby
Date:April 2nd, 2008 04:12 pm (UTC)
(Link)
The old monitors just used pull up resistors, that may still work.
He does seem to have figured it out though.
---
There is a lot of import bandwidth available on a video port for future expansion (and with direct access to a lot of processing). I'm just glad people are playing, everyone learns.
(Reply) (Parent) (Thread)
[User Picture]
From:[info]doodlesthegreat
Date:April 1st, 2008 07:25 pm (UTC)
(Link)
Hack of the Day should also hear of this.
(Reply) (Thread)
[User Picture]
From:[info]kreggan
Date:April 1st, 2008 07:53 pm (UTC)
(Link)
Oh, and for those who are looking for something in the spirit of the day, and this journal: http://www.theserif.net/?p=5882
(Reply) (Thread)
[User Picture]
From:[info]porsupah
Date:April 1st, 2008 09:03 pm (UTC)
(Link)
Failing that, you could always just bit-bash and fake I2C. That's how one chip on the board I'm working on is actually set up - two of the controller's general I/O lines just bumped up and down under program control. It works. ^_^

And yes, congratulations! Some fine detective work there, and a healthy slather of hacker spirit.
(Reply) (Thread)
[User Picture]
From:[info]foofers
Date:April 1st, 2008 11:03 pm (UTC)
(Link)
Failing that, you could always just bit-bash and fake I2C.

Bit-bash what though? It's easy when you're on a microcontroller with sundry GPIO lines, or an older PC with a parallel port. Neither is present here...just higher-level ports...and the idea was to avoid other boards or interfaces as intermediaries, because...well, I haven't gotten around to writing about that part yet, but they're all really annoying.
(Reply) (Parent) (Thread)
[User Picture]
From:[info]smashwolf
Date:April 2nd, 2008 01:14 am (UTC)
(Link)
You can probably find a monitor dongle for the DVI connection that reports back i2c of monitor type or presence of monitor. Probably a DVI to analog adaptor, so you don't have to have an actual monitor load on the machine. Especially if that video port also outputs analog at the same time. Or maybe use an ADC/DVI to analog adaptor cable to fake out the computer? I know my extron boxes efectively fake out the mac into thinking it has a monitor.


Also, have you considered trying to just run the Darwin OS On your Apple TV? I bet it would work, and make the OS footprint smaller, possibly more efficient depending on how man system resources are saved by running a bunch of GUI stuff you might not need on the control system itself.

http://en.wikipedia.org/wiki/Darwin_(operating_system)
(Reply) (Thread)

Advertisement