I wanted a board that shows the state of all I/O pins on LEDs with all of these properties....
"Read More" for the circuit details and photos.....
Here is the circuit I ended up using. At first, this may seem expensive. However, $15 buys 100 LMV358 dual opamps at Digikey (or $10 buys 25 of them, but they're so useful that 75 more for $5 is a real bargain). The rest of the parts are cheap resistors, and course the LED, pushbutton and thumbwheel pot.
The 2.2M and 100K resistors cause the pin to default to low. However, 2.3M is so weak that the chip's internal pullup resistor will easily pull the pin high. Of course, the thumbwheel pot also drives the pin for the ones with analog input ability. I used the same circuit for all pins, except leaving the pot off for the digital-only pins. For testing digital inputs, the pushbutton can bring the pin high, and the 330 ohm resistor is meant to protect the pin if it happens to be configured as an output when someone presses the button.
The opamp circuit is the interesting part. I'm sure many people reading this will feel an opamp is too extravigant or a "waste" for only driving a LED. However, these opamps are 200 (2 per chip) for only $15 at Digikey. The huge advantage is you can experiment with the pin without the LED loading. You can try connecting very weak signals, or I2C, or signals like the output of an IR receiver module with a pullup resistor, and the LED always works without the power to drive the LED loading & changing the signal.
The circuit works by measuring the LED current with a 47 ohm resistor. The opamp's feedback loop causes the voltage on the 47 ohm resistor to match the voltage beween the 2.2M and 100K resistor, so the LED always has a current that is linear with the actual voltage on the pin. Even for the non-analog pins, that's very useful while experimenting. Sometimes the LED will be dim indicating things aren't quite as expected, even though everything seems to work from the software side.
When I first built this, I neglected the 150K feedback resistors. You can see here when I added them in:
The opamp has PNP transistors on it's input, so a tiny current is sourced from the input pins. That tiny current, flowing through 100K creates a few millivolts, which is enough to put a bit of current through the LED. I used low current LEDs (HLMP-D150A), where that tiny current causes it to light up just a bit. Of course, that's no good, because you want "very dim but not completely off" to indicate something is wrong. The 150K resistor adds slightly more than 100K impedance on the other input, so the opamp sees just a slight negative voltage between its inputs when the pin is at zero volts (or just a few millivolts). At even with only 25 mV (something driving the pin low, but not all the way to ground) the LED starts lighting up properly.
The end result is a "breakout board" that lets me easily test every pin in every possible mode, with LEDs showing a true indication of every actual analog voltage!
I realize this is probably excessive design for most people, but when you're making a development board and testing nearly every major Arduino library, it's amazing how handy tools like this can be. So I thought I'd document this little circuit, and especially the 150K feedback resistor trick that makes it work so well with these higher impedances and the chip LMV358 opamp.