Prop+TSL230 Light-to-Freq as a Motion Detector (poor Man's PIR)
BR
Posts: 92
I've been playing around with using a TSL230 light-to-frequency converter as a motion detector. Here's what I've come up with so far. It actually seems to work OK as a general motion detector. I'm testing it out now for an application I have in mind wherein a PIR sensor doesn't work as well as I'd like (though I have to admit I haven't tried the new/improved PIR sensor to see if it does any better). The attached example is set up to work on a propeller demo board.
Some advantages I can think of as compared to the PIR sensor:
Some disadvantages I can think of:
Feel free to give it a whirl if you're interested. Let me know how it works for you. And if anyone has ideas how the detection algorithm can be further improved, I'm open to ideas.
Some advantages I can think of as compared to the PIR sensor:
- Less expensive than a PIR sensor (about half the price)
- Sensitivity is not decreased in hot ambient conditions
- No false alarm triggers due to hot/cold air currents
- More user control over the motion detection algorithm, sensitivity, etc.
- A TSL230 can be configured to have much more directivity than the PIR by suitable arrangement of the sensor, the sensor enclosure, the light source, and the target reflectivity
Some disadvantages I can think of:
- Requires ambient light or an active light source to work....won't work in the dark
- Probably somewhat less sensitive to motion than the PIR...detects motion by small changes in ambient light level, so generally less sensitive to motion in low light
- More effort required to set up, wire TSL230, etc.
- Uses a cog
Feel free to give it a whirl if you're interested. Let me know how it works for you. And if anyone has ideas how the detection algorithm can be further improved, I'm open to ideas.
Comments
Duane
My initial test to see how this works for the application I'm working on was a failure, but only because I rigged a demo up with a 9v battery and the battery died before I had a chance to try it out. I'll try again, this time with a fresh battery.
I'm using a 3.5mw red laser + TSL230 + reflective tape. The basic idea is simple...just accumulate TSL230 cycles with light source on, then decrement cycles with it off (to subtract out ambient light). The remainder is "signal" strength.
I've tried this out with a simple TSL230 mounted on a breadboard with only a 2 inch piece of plastic conduit placed over the TSL230 to help shield it from ambient light...laser just taped onto the side of the conduit and pointed coaxially with the axis of the sensor face.
I made some distinctly un-scientific measurements of signal strength vs distance between laser/sensor package and reflective tape. Results are:
3 ft..........4000-8000
5 ft..........1000-5000
10 ft..........500-1300
15 ft..........250-500
20 ft..........250-300
25 ft..........80-160
30 ft..........60-120
35 ft..........40-90
The "signal strength" with ambient noise is in the 0-20 range, so I'm arbitrarily cutting off the useful range at ~35ft. This is with no optics on the receiver end, mind you...so could be considerably better with a little attention to receiver gain if more distance was desired.
I show a range of "signal" values in the above table because the value returned seems to "wander" with time and over a considerable range. What's even more disturbing is that the "wandering" is distinctly non-random in the sense that readings will gradually climb over a span of ~1 min, then gradually drop back down over about the same period. I'm accumulating cycles over a span of 1 sec in my demo, so I'm looking at readings once per second. I'd sure like to figure out what's causing that behavior and get rid of it.
Still, this appears to be adequate for the application I have in mind (I want to be able to detect whether a door is open or closed using a sensor that is about 25 ft away without having to string a wire over to the door). I'll probably fiddle around with it a bit to see if I can make it a bit better. I'd welcome any comments or ideas for improvements. Or thoughts as to what might be behind the "wandering" phenomenon I mentioned.
The code I used for my proof-of-concept is attached. Schematics included in code.
Wish Parallax had a sensor that would meet this need...hint hint.
That's cool!
Does your ambient light also wander up and down non-randomly, too? or if you use a light source other than the laser?
Without being able to read your code right now, I would check that my repeat loops are doing what they are supposed to do and aren't skipping somehow... or that your counting registers are indeed getting cleared on every count cycle. Glad to hear you gave this a try.
After a fair amount of experimenting, I have concluded that at least one factor that is contributing to the changing readings is...me. As I move around (closer or farther away), it seems to have an effect on the magnitude of the readings. It isn't clear to me why me moving around should have any impact on the signal strength, unless there's a significant amount of light from the active light source being reflected off me. But my active light source is a laser, so it is a tightly focused beam.
The attached picture is a typical trace of readings. X-axis is measurement number...I'm taking readings once per second, so x-axis is also equivalent to measurement time, in seconds. The y-axis is "signal strength", defined as the number of TSL230 ticks accumulated with laser on minus ticks accumulated with laser off, switching at 1000 Hz and accumulating over a 1 sec interval. The sensor is just sitting on a table pointing up at the ceiling. I have a piece of reflective tape stuck on the ceiling, with the laser spot directed onto the reflective part of the tape. A 2 inch piece of plastic conduit is sitting over the TSL230 to narrow its field of view and cut down on stray light.
Note that the readings wander over the course of tens of seconds in a range of ~1200 to nearly 12000 at one point. The increased intensity of "wandering" after reading #601 is me starting to figure out that it is correlated with me moving around and I'm intentionally moving to try to test the hypothesis.
The two portions of data where the readings drop to zero are where I intentionally moved the laser off the reflective tape (it is just pointing at a white ceiling). As you can see, the change in signal level is quite strong, certainly enough to use. So the wandering, while annoying, isn't debilitating. But I'd like to make if better if I could since a more stable reading implies a higher usable range.
Are you talking about the laser being modulated? In other words, is the laser flashing on and off at 1000 Hz? If so, I'm wondering if the TSL230 could be experiencing some sort of saturation effects. Are you taking readings at only one sensitivity? It might be worthwhile recording sensitivities at 1X, 10X, and 100X and seeing if the results match each other. If the TSL230 is saturating, then you might see the 100X sensitivity reading be only 2 or 3 times the value of the 10X sensitivity reading, for example. Note that the output reading does NOT necessarily have to show 1600000 Hz or whatever to be saturated.
To understand how that might happen, check out this discussion some time ago:
http://forums.parallax.com/showthread.php?133699-How-fast-bright-flashes-can-cause-errors-in-the-TSL230-Light-to-Frequency-sensor
But, of course, that might have nothing to do with your problem, in which case I hope Phil Pilgrim has some suggestions. If you are modulating your laser, I'm wondering why it's necessary to do that for your application.
Per your suggestion, I tried an experiment to see if I'm somehow running into a device saturation condition. So I used this object to output a raw TSL230 reading once per second. I forced the device into the high gain mode...the experimental setup is exactly as was used for the previous chart I posted. Attached plot shows that the number of TSL230 "ticks" accumulated in a 1 sec interval with the laser continuously on is in the ~8500-1000 range. The drop down to ~6000 at measurements 55-85 is me covering up the laser to see what the "laser off" contribution is. I infer from this experiment: 1) that the TSL230 is nowhere near saturation, 2) that the "wandering" is clearly evident in this setup as well, and has about the same time constant. So unless I'm missing something (wouldn't be the first time for that), I don't think it is a saturation thing.
I was staring at my code and realized that the way I have it set up, it toggles the laser on and off in one complete cycle per 2 passes through the repeat loop...thus the "120Hz" I thought I originally had is really 60 Hz...sweet. Nevertheless, the 1000Hz I claimed in a previous post is still 500Hz, fast enough to stay away from 60 Hz aliasing, I think. And 500Hz is slow enough that rise time/fall time of any component I'm using ought to be many orders of magnitude faster, so not likely a factor.
Just seems like the readings ought to be more rock solid than this. Other possibilities I'm contemplating:
Slightly updated version of the code attached.
BR,
I'm a perpetual newbie so I hope my suggestions on this don't lead you astray, but what you're doing with the increment/decrement thing seems a little bit overly-complicated to me. If I were doing this, I would turn on the laser, give it, say, 0.1 second or so to stabilize (longer maybe???) and then open up my counter to start receiving pulses from the TSL230 for, say, half a second or 1 second or whatever feels good. Then I would close up my counter, store its value in a variable (= LaserOn), shut off the laser, give everything, say, 0.1 second to calm down, clear the counter register, and then I'd do a "dark count" for the same time as LaserOn had and store that result into LaserOff. Then simply calculate LaserOn-LaserOff.
The only time I've ever seen the TSL230 do anything like what you're describing is when I've had the light source blinking at some phase that is somewhat off from the phase of my counter opening and closing, so then, because I'm clipping off odd parts of the pulses, I get different counts each time. I don't know if that's what's happening with your approach, but to eliminate that as a possibility, I would just dumb down my code and make your approach more straightforward and see if the wandering stops.
Does my suggestion make sense in this case?