hex led sensor


Senior Member
<A href='http://www.user.dccnet.com/wrigter/picaxe/hexledsensor.gif ' Target=_Blank>External Web Link</a>

shows an example of LEDs used as self illuminating photo sensors.

I used garden variety high efficiency clear lens red LEDs with 1K resistors for current limiting.

The bidirectional port (out0-7) of the 18x (thanks to hippy)is used first as inputs to measure whether the light on each LED photosensors generates a time constant that is more or less than a threshold.

Then the LEDs with a longer time constant (ie lower light) are turned on for 10ms and the process repeats.

The result is that if a shadow is cast on any LED in the array, illuminated externally by moderate ambient light, it will light up.

<code><pre><font size=2 face='Courier'>

;wilf rigter - 07/01/07

poke 5,8 ;serout=1
pins = %00000000 ;out0-7=0
POKE $AE,%11111111;out0-7=input
pause 10 ;set threshold
peek 6,b0 ;b0=out0-7
POKE $AE,%00000000;out0-7=output
poke 5,0 ;serout=0
pins=b0 xor $FF ;output b0
pause 10

The light to LED conversion process takes several steps:

1) The LEDs are reverse biased by setting serout=1 (poke 5,8) and out0-5=0. This charges the LED junction capacitance to 5V while the voltage on out0-5 is 0V.

2) pins out0-5 are configured as inputs

3) pause 10ms during which

4) the voltage on pins out0-5 starts to rise from 0V to 5V as the photo leakage current discharges the junction capacitance.

5) transfer input state of pin out0-5 to b0 (zero is read if the voltage on that pin has not decayed above the logic 0 threshold).

6) pins out0-5 are configured as outputs

7) set serout=0 (poke 5,0)

8) transfer b0 inverted to out0-5 to light the LEDs that were dark.

9) pause 10ms

10) repeat

The circuit was tested on a breadboard which adds significant stray capacitance to the circuit which increases the photocurrent controlled time constant.

PAUSE 10 sets the light threshold for the conversion. Larger values give higher sensitivity at the expense of noticable flicker as the conversion cycle time is increased.

A PCB with careful layout will give a shorter time constant and may allow multiplexing a matrix of 5x7 LED sensors.

More complex code can provide proportional light measurements for each LED.

Note that the out6 and out7 pins don't work for this application. They work fine as outputs and with switch inputs but I suspect that these are configured internally with a weak pullup resistor. More experiments will bear this out.

One application for this self illuminating LED sensor array is an art project I have in mind for a SHADOW CAST LED MIRROR which illuminates the silhouettes of passing people.

On the other hand I have used the bi-directional pins of an 08M to control a single LEDsensors to automatically start flashing when it gets dark.

On the gripping hand, hmmm... well I'm sure you'll think of something much more exciting.



Edited by - wilf_nv on 09/01/2007 10:14:24


Senior Member
I tried this with an 08M and didn't have any success at all, so maybe that was down to the LED I was using.

I looked at the datasheet and couldn't see too much different in the I/O circuitry for Pins 6/7, but those are also wired into the ADC which is what I suspect is the problem; extra load causing the LED's to drain faster than you can read them ? You could try &quot;SETFREQ M8&quot; to see if that improves things. A scope would probably reveal in more details what's happening.

I assumed my failure was because the LED were draining far too quickly for the PICAXE's speed so I thought it wouldn't work. It's good to know it does work and that my poking about has come in useful.

I did design some bi-directional opto comms but without working hardware it has sat in the 'some day' tray. The comms has to be self-synchronising and self-clocking so I used light pulses of various lengths to indicate idle, 0 or 1. When the receiver sees the light is gone ( lack of light for too long and an idle bit is transmitted again ) , it switches to transmitting, the transmitter switching to receive.

That's enough to send single bits between the two bi-directionally, and serial data is then just a case of sending 8-bits in sequence.

I think that project may now move up a tray.

Edited by - hippy on 09/01/2007 11:31:34


Senior Member
Got it working. I thought this was impossible, so many thanks for the example code. Had to tweak the PAUSE value up to 20 for the LED+R I have. Worked(ish) on Pins 6/7 but not reliably. I altered the POKE values to use an Out Pin for 'LED charging' so I can still use SERTXD for debugging.

So, LED Tx to LED Rx light transfer ... has anyone done this or any advice ? Any preferable colour or IR ?

The actual Tx and Rx LED drivers can be replaced by hard wires so protocol development is under way without worrying about LED's. Expect to see another bumper edition .ZIP file in the future. The unique aspect of the test programs so far are that they all run on 08M or 18X without source code changes -- READ $FE,b0 if $00 it's an 18X, otherwise it's an 08M, assuming there's not an &quot;EEPROM $FE,()&quot; in the source ! There's a bit more twiddling involved because things like INPUT, OUTPUT and LET DIRS won't compile for an 18X, but all good fun to keep amused with.


I love it! Not sure I fully understand the code but its cool nonetheless. Have you seen Danny Rozin's wood mirror? <A href='http://www.smoothware.com/danny/woodenmirror.html' Target=_Blank>External Web Link</a> Oooh... better yet, its an interactive Jim Campbell! <A href='http://jimcampbell.tv/LE/LEReconstruction/index.html' Target=_Blank>External Web Link</a>

Anyway, what kind of distance can you get from this?



Senior Member
Hippy -

Thanks for that. It is always good to get confimation a design is repeatable.

The real limitation of using LEDs as sensors is their very low photo leakage current. That means that the rate of change of the output voltage is limited by the stray and junction capacitance. This restricts the maximum data rate for any communication application.

With two LEDs (Tx/Rx) face to face and 25ma of transmitter current, the LED output signal time constant can be lowered to &lt;1ms.
300 baud may be practical. The baud rate would drop drastically when the LEDs are separated a significant distance.

The low LED photo leakage current and very high impedance during measurements also makes the circuit sensitive to stray leakage currents and coupled signals from adjacent PCB traces.

For that reason you will also find it difficult to measure the LED photo current signal because of the influence of the 10x scope probe resistance. The only way to measure this signal is to use a FET opamp voltage buffer and even then the additional stray capacitance will affect the TC of the circuit.

I call it the LED sensor &quot;Uncertainty Principle&quot; : It works when you're not looking and it doesn't work when you do.

Brian -

Yes I have seen the wooden mirror and have been trying to find a low cost equivalent using LEDs. Not quite as organic as clacking teak tiles though.

Edited by - wilf_nv on 09/01/2007 22:02:29


Senior Member
Thanks for the info. I've got the protocol running and it's amazing to see the Tx LED bounce between the two PICAXE's.

It's hard wired but with the LED sampling code ( Pause 10mS ) in to get accurate timing, and I'm using LED on times of 120mS/240mS/360mS as that gives the receiver large enough loop counts of 'LED On' to be reliable ( 6/12/18 ) and that's giving a baud rate of ...

1.5 - Yes, one and a half bits per second !

There's some overhead with SERTXD for debugging, and if I made 0/1 pulses shorter than Idle and improved the protocol I can probably bump that up to around 10 baud, but I don't think it's going to be quick on a PICAXE.

It has thrown up a novel way of passing data between two PICAXE's in the backgound using Interrupts when 'LED On', timing how long it is on for, and then feeding a software Uart which consequently knows when a full byte has been received. Because each acknowledges receipt, it should be possible to have them running totally asynchronously updating each others' 'last received' data items in the background, but I'm getting way off-topic to what this thread originally started with.


For bi-directional LED communications (iDropper), see http://www.merl.com/papers/docs/TR2003-35.pdf

Also, I got an LED sensor working on an O8M w/o using any special bit-banging. It's not in any pretty form, but I'll post it if anyone's interested.


Senior Member
<A href='http://www.user.dccnet.com/wrigter/picaxe/hexledsensor.avi' Target=_Blank>External Web Link</a>

shows a very short video of the hexledsensor responding to the shadow of my hand.


To answer you question about distance. If used as a mirror on one wall, a directional flood light can be placed on the oposite wall, say 10 feet away. Anyone walking between the light and mirror will cast a moving shadow on the mirror which illuminates the shadow by turning on those darkend LEDs.

It is quite possible to take snap shots which may be played back randomly when no shadow is cast.

Another idea is &quot;mirror image&quot;: a two way LED window or double sided LED mirror that either reflects or transmits and/or transposes left/right, the shadow images from one side to the other side.




Senior Member
I've had no such success, but that could be the LED's which are 'normal' red ones. The previous test code which detected light and dark appears to have now stopped working, and the hard-wired hardware seems to be playing up - An 08 won't take a download at all unless voltage is dropped to 4V, and an 18X won't detect a signal from the 08. Probably just needs investigating further, but there are other priorities for now.

Example code for doing the comms can be found here. It sends bytes both ways using RS232 style Start+8+Stop bits, filling rxStream as a shift register for light seen. The send times will need to be adjusted to fill rxStream correctly ( or vice-versa ).


I did some baud rate calculations - Assuming a 10mS LED sample time, 3 cycles per zero bit, six cycles per one bit, that's 45mS per bit on average, half-duplex, that's 11 baud at best.


Senior Member
For the bi-directional 1 wire bus (hardwired) application use a single 1K resistor between the two chips to avoid bus conflict. Without some current limiting you can blow one or both chips if the I/O pins simultaneously change to the output state.


Senior Member
It wasn't clear in that file that the hard-wired version is two-wire, so Out-&gt;In in both cases. I've updated the file, but thanks for mentioning the issue anyway.