There are several scenarios where it’d be nice to detect the pulse of a blinking LED – especially low-power, because then we can sense it with a long-lasting battery-powered setup, such a JeeNode or JNµ.
Fortunately, that’s fairly easy to do. I used this test setup to try things out:
The left-hand side is a test pulse, generating 10 ms pulses once a second to simulate a typical indicator light. It’s simple enough with no further explanation needed.
The right-hand side of the above circuit is the actual pulse sensor we’re trying to implement. It’s a voltage divider with on the upper half a fixed resistor (well, a trimmer, but we only have to adjust it once) and the lower half is a Light Dependent Resistor (LDR) – like these two examples:
We want to generate one electrical pulse for each incoming light pulse, in such a way that it could trigger an ATmega’s digital input pin. With a clean pulse we could then set up a pin-change interrupt and keep the ATmega asleep most of the time.
The trouble is that LDR’s and voltage dividers are analog i.s.o digital. One way would be to constantly read out the signal as analog input. But this sort of polling and continuous ADC use eats up quite a bit of power – a digital signal would be a lot better as it’d allow us to use pin-change interrupts.
No worries. A digital signal is also a voltage, but it has to stay under a certain limit to be treated as digital “0” and above another limit to act as digital “1”. Here are the specs from the ATmega328 datasheet:
With a JeeNode running at 3.3V, we get: “0” ≤ 1V and “1” ≥ 2V. Note that in theory voltages between 1 and 2V will have indeterminate results, but in practice the signal will work fine as long as it doesn’t stay forever within that gray zone.
The trick is to make that LDR sensor as sensitive as possible. The LDR which I used is a fairly standard one (same one as included with the Room Board) and rises to over 1.5 MΩ resistance when dark. Let’s assume 1 MΩ as extra margin, then we could use 470 kΩ as upper resistor of the above resistor divider, and the resulting signal would be about 2.2V when dark.
The way I maximized the dark-state resistance was to place it in a small black plastic cap, as shown in the above photograph. This is essential, as you’ll see.
Now the actual pulse detection: the resistance of an LDR drops (quite dramatically) in the presence of light, so the trick is to place it close enough to the blinking LED that we want to “read out”. I placed my blinking test LED a few millimeteres from the black cap (which is open at the end, of course);
Here’s a scope snapshot of the LED pulse (channel 1, yellow trace) and the detected signal (channel 2, blue trace):
You can see the LDR signal dropping when light is detected, and that the LDR actually needs a bit of time to react. For 10 ms pulses, it’s plenty fast enough, though.
This configuration is probably ok – the voltage swings from about 1.8V (a marginal “1”) down to 0.7V (a clean “0”). The whole setup really depends on first getting the dark resistance as high as possible (i.e. shielded from any stray light) and pulling it down enough during the LED blink (i.e. close enough to pick up a good LED signal).
When the LED is inserted inside the plastic tube, the signal becomes much stronger – but recovery is slower:
It all hinges on the pull-up resistor, really. Which is why the best way to create this sensor is to use an adjustable 1 MΩ trimpot, and tweak it. You won’t need an oscilloscope or even a multimeter to get optimal results:
- very important: shield the LDR from stray light as well as you can
- pick as high a resistance as possible which still gives a “1” signal (between 100 kΩ and 1 MΩ)
- place the LDR + shield near enough to the LED to generate a “0” pulse
- tweak and iterate the above steps until it works reliably under all conditions
For minimal power consumption, the pull-up resistor should be as large as possible. Example: with an optimal pull-up of 1 MΩ and the LDR’s dark resistance about 1 MΩ as well, the quiescent current draw will be (Ohm’s law: I = E/R) 3.3 V / 2 MΩ = 1.65 µA, an excellent value for ultra-low power nodes. During the LED light pulse, this will increase to at most twice that (i.e. if the LDR resistance were to drop completely to 0 Ω).
Note that a more sensitive sensor design will be needed if you want to actually measure the length of the pulse with a decent accuracy, but for simple counting purposes where incident light can be kept out, there is nothing simpler than this LDR + pull-up trimmer, probably.
Update – More info about LDR’s on the LadyAda site.