Detecting when an 'external' LED flashes

Innes

Member
Hi,

After an absence from these forums of quite some time (about two years, I think), I am almost ready to get back into the workshop and do some tinkering, but I am hoping to obtain some advice before I dig in. Hopefully, this is a relatively simple project (aren't they the ones that always turn out to be the most complicated?)...

I need to detect when a fault occurs on a piece of equipment without interfering with the existing system. When a fault is raised, a red LED flashes on the control panel, and when this happens, I want my picaxe circuit to detect the flashing LED and trigger an alarm, so I am thinking that a fairly simple optical sensor would do the job.

I have a bit of a blank regarding the detection of the flashing LED, but as the normal state for the LED is ON (solid), my first thoughts are that I could simply detect an absence of light from the LED. On a fault, the LED flashes about twice per second, so as long as the picaxe code can check for an absence of light at faster than that frequency (which I am certain it can), then that should do the trick.

However, I really think that I should be able to come up with a more elegant detection routine; something that actually detects flashing over a period (say 30 seconds), just to make sure that it really is a fault. e.g. If the light sensor became detached from the control panel, then there would be a permanent absence of light from the LED, which would not be a fault as such (perhaps this could trigger a different alarm signal). This is where I have drawn a blank! I can't think of the code to detect flashing (of an indeterminate frequency).

The detection of light from the LED should not be a problem; the LED has a panel that closes over it, and there is enough room to mount a small detection device, so it will be in a permanent state of darkness. If it helps, it is not any sort of critical system; it would just be nice to know when a fault occurs as soon as it happens, rather than finding out later. Initially, the alarm will be an audible alert. The next stage would be to add a wireless alert, but as ever, I plan to get the basics working first!

Any suggestions would be appreciated to get my brain working on this one, even if it is just a bit of pseudo-code to get me started.

Thanks in advance,
I
 

BeanieBots

Moderator
It should be simple enough but you will need to define some criteria by which "flashing" can be determined. For example:-
If on, then keep monitoring.
otherwise, it's off.
If off, has it been off for X amount of time?
If X > predetermined value, then sensor has fallen off.
otherwise, enter another routine to check for ON again but now test to see if it goes off again within a certain amount of time. If it stays on for longer than that time, then it must be a sensor which has fallen off and has now been put back in place again.

Just draw it out in a flow diagram.

As for making the test itself, a simple LDR should do the job. You should put a gell filter in front of it of the same colour as the LED, otherwise, should it fall off, ambient light would be detected as an ON state.
 

hippy

Technical Support
Staff member
PULSIN may be all you need. If it times out then there was no change of state, otherwise check what period of pulse ( LED flash ) there was. Count those in range until you're happy then handle the fualt.
 

moxhamj

New Member
What an interesting mathematical conundrum. Short answer - yes it can be done with picaxe.

Hardware as advised - an LDR in series with a suitable resistor (?10k). You may not need a colour filter.

I find it helpful to think of analog circuits that do what you want, then simulate these in digital code.

Read the light value with readadc. This may vary a bit with day and night and obviously it will vary a lot with a flashing led.

I wonder about keeping this analog rather than trying to convert to a digital high or low. Read the analog value 10 times a second. Record the value in a variable, say b0. Record the previous value in a value, say b1 - so before you read the value you make b1=b0. Now take the absolute difference between the two - eg if b1>b0 then b2=b1-b0 else b2=b0-b1. This is like a high pass filter - big changes in the light level create big values, and little changes create small values, or even zero values.

The absolute function is like a diode rectifier so the values are always positive.

Next step - run this into a capacitor that is in parallel with a resistor. An analogy might be a leaky bucket - you put in cups of water (via the absolute function above), and water is running out continuously. If the values are not changing then the bucket will be empty.

In code, set up a variable, eg w3. Every readadc cycle, add the absolute value, and subtract a constant. Then you just need to test for underflow and overflow.

If the value in w3 goes above a preset value, then the led is flashing.

Sounds complex? Here is some pseudo code:

main:b1=b0
readadc b0
if b1>b0 then
b2=b1-b0
else
b2=b0-b1
endif
' change in light level is now in b2
w3=w3+b2' add this to the running total
'now subtract a constant - tweak this for the flash frequency
if w3>10 then
w3=w3-10
else
w3=0
endif
' test if over a certain value
if w3>50 then gosub flashing_detected
' just for completeness, test w3 is overrange
if w3>65000 then
w3=65000
endif
pause 100' wait 0.1 seconds
goto main
 
Last edited:

BeanieBots

Moderator
Taking Doc's Idea a little further, simply feed the LDR/resistor potential into a large RC filter. The time constant of the RC needs to be several times larger than the flash period so if it's a 1Hz flash, then use something like 100k/47uF.
ReadADC will then already return the average voltage. Experiment to find what value relates to which of the three conditions.

Hippy's idea is the simplest but pulsin has a timeout of 0.65S at standard clock frequencies. If the flash rate is slower than that, then it won't work unless you reduce the clock speed.
 

Jeremy Leach

Senior Member
Isn't an LDR a bit sluggish anyway, so it would effectively do some filtering itself? Perhaps just the LDR, and test the voltage. I think some experimentation would give the best answer.
 

BeanieBots

Moderator
Depends on your deffinition of sluggish.
They're not much use for high speed optical data comms, but most can keep up with a humanly perceivable flashing LED.
 

Jeremy Leach

Senior Member
Oh, I didn't think they were that responsive ...not that I've tested it. Anyway LDR better solution here than phototransistor etc if can get away with it. A neat little addition would be to echo the input on another LED - ie you are going to have to obscure the LED you are monitoring. Ok, not essential, but easy to do !
 

Dippy

Moderator
Assuming the sensor is shrouded to keep out ambient light, couldn't you use a photo-t or LDR+sutiable resistor(s) to get a Logic on-off detection?

Then use something like:
Code:
symbol LEDON=w0
symbol LEDOFF=W1
symbol Alarm=b4

main:

w0=0
w1=0
Alarm=0

do
	ledon=ledon+1
	pause 1
	if LEDON>1000 then exit	'
loop while pin1=1

do
	ledoff=ledoff+1
	pause 1
	if LEDOFF>1000 then exit
loop while pin1=0
And then test LEDON and LEDOFF times?

This could provide info as to whether flashing , always dark or always light (i.e. fallen off, unless the room is dark)

Note: I've only said 1000 above as an example.

You could even include High and Low within the loops to echo LED status as per Jeremy's suggestion.
 

BCJKiwi

Senior Member
Think it is being overthought!

If ReadADC is used then all that is required is to maintain an average of the last x reads of the LDR. A pause between each read will sort out how big x should be.

This will result in 3 obvious numbers (approximately) for the readadc value.

LED on all the time == High number
LED Flashing == middle number
LED off == 0

The resistor divider with the LDR will determine the medium and high number of each read.

The pauses and number x of the count to average over will determine what the middle and high values actually are.
Modified example code snippet from Post #6 here
http://www.picaxeforum.co.uk/showthread.php?t=10139
Code:
#PICAXE 08M
SYMBOL Set      = 4            'ADC4 ~ the voltage from the LDR ADC
SYMBOL SetVar_1 = b5           'Variable for FIFO buffer
SYMBOL SetVar_2 = b6           'Variable for FIFO buffer
SYMBOL SetVar_3 = b7           'Variable for FIFO buffer
SYMBOL SetVar   = b8
main:
   readadc Set,SetVar  'read ADC Value
'Sum the last three ReadADC values to determine average light level
   SetVar_3 = SetVar_2
   SetVar_2 = SetVar_1
   SetVar_1 = SetVar 
   SetVar = SetVar_1 + SetVar_2 + SetVar_3 / 3 'Sum last 3 Readings, take the average
   'Average will be low, medium, or high
 

Jeremy Leach

Senior Member
The only thing here is that you need to be careful when you sample .... if you happen to sample at the flashing rate then you could get all samples giving 'high' for instance. So I think would be best to sample at 1.5 period of flashing.
 

Dippy

Moderator
Or even:
ReadADC
little pause
ReadADC

test the difference in ADC values. LED On/Off gives a step change.
Add a counter to see if sensor has fallen off.
Many ways I would have thought... is this a mountain out of a molehill?
 

boriz

Senior Member
Or…

Sensor on pin1, HIGH=sensor illuminated.

Code:
do
	w0=0
	do while pin1=1 and w0<64000
		inc w0:pause 50
	loop
	if w0=64000 then:gosub fail:elseif w0>0 then:gosub flashing:endif
loop
As long as the flash-on-time is less than about 3 seconds, it jumps to a sub called Flashing when the LED flashes once, and to a sub called Fail when the sensor has been illuminated for more than about 3 seconds.
 

Innes

Member
I'm sorry about the delay in responding; I hope you don't all think I was being discourteous in not replying sooner, but I have been incredibly busy recently (I am now teaching full time). A great deal of useful information has been provided for me to digest, and at some point, I am going to have a play with the various suggestions and see what I can do.

Although I am very happy with coding side of things, my electronics knowledge is a bit on the rusty side (okay; a lot on the rusty side), so I'll probably be back with loads of daft questions over the coming weeks; please be gentle with me!

Rather than dive into this project, I think I will make it easy on myself; I have got my workshop completely cleared and have a PC, all my components, picaxes and breadboards at the ready, but now I have sat down with the manuals, I have found that what I had learned about picaxe during 2006 (the last time I visited this forum), has now slipped my memory, so I am effectively starting from scratch again. I'm going to start with something less ambitious - flashing LEDs and controlling servos, etc. - to get me back on track before I get stuck into a 'real' project.

Thanks again,
Innes
 

boriz

Senior Member
"I have got my workshop completely cleared and have a PC, all my components, picaxes and breadboards at the ready"

Ahh bliss.

And the missus wants us to go away to some bloody sweaty tourist trap to sit on some sand and stare at old pottery while rubbing ointment onto bloody insect bites and hoping you can get to the toilet before that bloody ‘orrible food reappears! I just don't understand.
 
Top