Saturday, January 30. 2010

Charlieplexing: watch your voltage levels!

Charlieplexing is a technique to allow n tristate digital output pins to control n(n-1) LEDs, by exploiting the high-impedence state of the output pins and the reverse-bias tolerance of LEDs.

I put together a circuit to test this out, similar to the 6-LED diagram in the Wikipedia entry. I added three 220Ω resistors, though. This ASCII art sums it up nicely:

      +--->|---+          +--->|---+          +--->|---+    
      |  LED1  |          |  LED3  |          |  LED5  |
 <----|        |-/\/\-+---|        |-/\/\-+---|        |-/\/\-+-->
      |  LED2  |      |   |  LED4  |      |   |  LED6  |      |   
      +---|<---+      R   b---|<---+      G   +---|<---+      B   

where R, G, and B are the three connections to the Arduino, and the arrows on the left and right side are joined by a jumper. I put together some simple Arduino-level code to drive this layout in a simple counter sequence, and fired it up.

One thing I will say about the Arduino: tinkering pays off. After the usual forgotten-semicolon cleanup, LEDs started blinking immediately. This is good, because I don't have much of an Arduino-debugging toolbox at this point!

Anyway, there's a problem. When an LED is fully illuminated, two other LEDs glow at about 50% brightness. For example, when LED1 is on, LED4 and LED6 glow too. It's not hard to see why: to turn LED1 on, the arduino drives R low and B high. The path through LED1 is intended, but LED4 and LED6 are also forward-biased in series, albeit with more resistance inline and the voltage-drop from two LEDs. Can this be prevented?

Let's work out the math here, using the resistance r as the only parameter I can change. The LEDs I'm using (5mm Green LEDs from CHINA YOUNG SUN) don't have a lot of performance data, but do list a forward voltage drop of 1.8-2.2V, so let's use 2V. My Arduino is running from the USB power at 5V. The resistor to the left of R defines the current through that leg for the remaining 5-2 = 3V, so I1 is 3/r. On the leg containing LED4 and LED6 a total of 1V remains across two resistors, so I4 and I6 are both 1/2r.

The LED datasheet lists a maximum average current (20ma) and peak current (30ma), but doesn't list a minimum current. Guessing 1ma, I need 1/2r < 0.001, so r > 500. At that point, though, I1 is just 6ma - not nearly bright enough to impress, particularly with a 16% duty cycle when multiplexing all 6 LEDs. All the same, I figured I'd try it. The closest resistor I had was 470Ω, so I gave that a shot. The result was bad on all fronts: the expected LED is dim, and the unwanted LEDs are still visible.

I suspect that, to get this to work, I'd need to reduce the supply voltage to something less than twice the LEDs' forward voltage drop. Then two LEDs in series would carry no current. I considered doing this with a simple voltage divider on each microcontroller pin, but this of course ruins the tri-state behavior that's critical to charlieplexing. I could build that by using two transistors for each pin, but by that point the benefits of charlieplexing in terms of component count are long lost.

So, in short, for good charlieplexing, make sure that your source voltage is less than twice the Vf of your LEDs.

[EDIT: it turns out, after some futzing that this also "works fine" if you just leave out the ballast resistors. Presumably this relies on a limited duty cycle and a "high enough" internal resistance to not melt the LEDs]

Saturday, January 23. 2010

2005 Mac Mini as an Arduino Development System

I have an early Mac Mini that's not good for much of anything anymore. It's not too fast, and it's a 32-bit PPC chip, so most proprietary-blob software is off-limits, meaning it doesn't make a good media PC. I put Gentoo on it, and decided to use it to interface with my new Arduino Duemilanove. I'm more interested in the Arduino as a processor I can play with, rather than a gateway to flashing LEDs, so I don't want the full IDE - just a compiler and assembler, and a USB-based programmer.

This post documents the process I followed to set all of this up.


Continue reading "2005 Mac Mini as an Arduino Development System"

Friday, January 22. 2010

Object identity in Perl

I ran across a surprising weakness in Perl, regarding object identity. I was writing a function to handle XMsgs, which are messages used by the Amanda transfer architecture to indicate the progress of a transfer. Messages sent from any transfer element are delivered to the same handler, and in this case I needed to know which element had sent the message. Fortunately, XMsg objects have a elt attribute pointing to the sending element.


Continue reading "Object identity in Perl"

Sunday, January 17. 2010

A future for Svnmerge?

Svnmerge has always been the kid brother of Subversion. It's in the project's contrib directory, and is thus unversioned. Since it's a single Python script, users just download it directly from the repository. In the last year, the script has only seen a few non-trivial commits, and the mailing list has been almost silent.

There are some simple reasons for decline. First, Subversion itself, in version 1.5, has adopted some of the functionality of Svnmerge. In particular, svn now uses properties (svn:mergeinfo) to track the revisions that have and have not been merged into a particular branch. There are some limitations, of course. Most obviously, a branch can only be "reintegrated" into trunk once, which is not the workflow of many Svnmerge users. Also, to my knowledge, Subversion cannot merge between repositories, while Svnmerge can.

Second, Git, Mercurial, and other DVCS's now provide strong support for merge-heavy workflows. Both tools also have excellent "gateways" to Subversion. For example, Amanda's Github repository tracks the Subversion repository using some simple shell scripts.

Between these two forces, I think that much of the audience for Svnmerge has disappeared. Those left, sadly, will see even less support.

Notice

The postings on this site are my own and don't necessarily represent the opinions of Zmanda, Inc.