Experimental Le Dominoux using a PIC-08 (PICAXE) board and 2 LEDs. Watch the short video:


This version also supports a piezo speaker and “bendable” LEDs, thus combining all 3 Le Dominoux features into one.

The LEDs are bi-directional, meaning either one is an input as well as an output. The PIC samples each LED until it detects a small voltage change on one of them, then uses the other LED as a light output. In this experiment it’ll play a tune if the blink signal is lost.

These high-efficiency LEDs can generate over 1V when exposed to bright light. However, when connected to the PIC’s high-impedance ADC the LED may continue to hold its charge long after its exposure, thus making “off” measurements difficult, and causing the PIC to lose the blink signal. To ameliorate this the LED input is briefly switched to an logic input driven low, thus discharging any remaining voltage. This is done in the code (below) whenever a blink signal is lost.  This fairly simplistic method works ok in the PIC basic environment. The PICAXE manual recommends grounding unused inputs — I found that by touching an unused ADC input I caused spurious readings on the other ADC inputs; the unused ADC is now grounded.

Update: most (if not all) bi-directional LED designs use 2 GPIO’s for each LED, and a “Reverse Bias and Discharge measurement” technique. This design uses only 1 GPIO per LED.  I suspect the PIC’s ADC circuitry helps out but I’m no expert here.

PIC BASIC program:

;Demonstrates using a LED as a light sensor and emitter
; automatically selects a blinking input
; input on 1 or 4, output on 4 or 1
; R. Elwin, 3/2011

symbol old1 = b1
symbol inpin = b2
symbol outpin = b5
symbol inaction = w6
symbol thresh = 8       ;ADC input drop indicates end of blink
symbol ontime = 285     ;in ms
symbol timeout = 500    ;in ms*3, when to look at inputs again

b3 = 0
gosub pinselect ;stays here upon bootup until blinking detected
inaction = 0


 gosub readled

 if b6 = 1 then
 ; input off, output goes on
 high outpin
 pause ontime
 low outpin
 inaction = 0

 pause 1        ;short delay between samples
 old1 = b0

 ; check if nothing blinking
 inaction = inaction + 1
 if inaction > timeout then
 inaction = 0
 sertxd ("timeout",13,10)
 b3 = 1   ; play a tune
 gosub pinselect

goto main

; figure out which pins to use
; when swapping try to 'drain' LED's charge by setting output low
 low 1
 low 4
 if b3 = 1 then
 tune 0, 9,($09,$0B,$07,$27,$82) ;close encounter
 pause 2 ;don't play tune, just pause

 input 1
 input 4

 if inpin = 4 then    ; check other input
 inpin = 1
 outpin = 4
 inpin = 4
 outpin = 1

 readadc inpin,old1

 for b4 = 1 to 10                ; sample an input a few times for change
 gosub readled
 if b6 = 1 then
 pause 1        ;short delay between samples
 old1 = b0
 next b4

 sertxd ("sampling=",#inpin,13,10)
 sertxd (" data=",#b0,13,10)
goto pinselect2

; read LED on ADC, returns b6=1 if dropped below threshhold, b0=input sample
 b6 = 0
 readadc inpin,b0
 if old1 > b0 then
 b3 = old1 - b0
 if b3 > thresh then
 b6 = 1

Bi-Le Dominoux experiment, PICAXE-08M