frequency analysis alternatives from pulsein function

hello people, i have used pulsein() with digital pins to get the frequency of IR light received by an IR phototransistor, this is fine given the phototransistor only has a low output when no IR light is on it, but sadly a simple desk lamp makes it trigger a high in the digital pins so i can't read pulses any more if a decent light source is on, or any other solid IR light for that matter, i know i can use a different value resister to dull down its sensitivity but then i have to up the IR light source, so i guess i need to use the analogue inputs to look for a frequency of input? the analogue input seems to have limit of 10,000 samples per second, so the highest frequency i could read by getting the time between pulses with analogue is 10khz from what i know, is there any alternative to read up to at least 20 khz or preferably higher or less process intensive manner?

also i know i could use an IR receiver module to get the frequency for me but i don't fully know how receiver modules work and phototransistors are way cheaper!

It sounds to me like your desk lamp is swamping out the IR signal. If that is the case, no amount of ADC work will allow you to see what is effectively one tree in a forest, especially when the whole forest is on fire.

The IR portion of the light may be a tiny tiny fraction of the total light, and separating the IR from the ambient using software alone is going to be nigh on impossible. It is doubtful that the ADC would be sensitive enough to detect the tiny changes in brightness.

What you really want to do is to filter out all the ambient visible light, and only sense infra red light. You can get IR filters to do just that job (commonly available for cameras).

Another method, that might be possible, is to change how you connect the PT to the Arduino. If you were to take the output from the PT and pass it through a capacitor you would remove any DC voltage from the signal. Then, any positive change in the output of the PT would give a positive pulse from the capacitor, and any negative change in the output of the PT would give a negative pulse. Ignore the negative pulses (just look at the leading edges of your signal), amplify them with an op-amp (use it as a comparator with a reference voltage from a pot so you can easily adjust it), and feed it into the digital input.

Also, instead of using pulsein(), attach an interrupt that just counts the pulses. Then, for a pre-defined sample period (say 100ms or whatever you like) you know the frequency as the pulses divided by the period (200 pulses over 100ms is 200/0.1, or 2KHz).

By the way, the highest frequency you can sample with an ADC is half the maximum sample frequency (look up Nyquist–Shannon sampling theorem), so if you can do 10,000 samples per second, the highest frequency you could actually sample would be 5KHz.

completely forgot about the nyquist theorem my brain was wired thinking it would be in sync which there i no guarantee of, any way with the light on the analog level goes from 50 to like 600 or so, but if i then flash the distant IR light on it it goes up to around 650 i think that's enough for a change to make use of, i could check for difference in levels once there is a significant change i will get a few samples average out the times and get the frequency that way, and put in some failsafes to discard the process if the change is only once, EG some one turning a light on or off or the sensor entering or exiting shade. i want various frequencies of light that it can measure like from 10 khz to 30khz with how ever much accuracy it will allow but 5khz wont give me much range or accuracy

Sounds like your best bet may be to do the capacitor + comparator thing then.

You can measure the frequency up to as fast as the ISR can trigger (or just use your existing code if that works ok).

Basically the capacitor works as a high-pass filter - the smaller the capacitor the higher the cut-off frequency. The changes in ambient light occur at very low frequencies, so those get filtered out (you only see the high frequency components of the off->on or on->off changes).

If you have a very small capacitor you will get very short pulses into your digital input, so you will need to use an interrupt to count them over a predefined period. If your capacitor is larger you will still get a square wave, but only half the amplitude of before (you are throwing away half of it), and it may take longer to stabilize after a change in ambient light.

The comparator is there to then take the pulses or square wave and both clean it up and amplify it to a suitable level for a digital pin to detect properly.

Take the following little circuit:

Two square waves summed gives the IR signal and the ambient light. You can see how after the capacitor (point A) the signals are converted into pulses - positive for the leading edges, negative for the trailing edges. When the ambient light changes you get a large pulse, and this affects the subsequent few high frequency pulses, as can be seen in the output trace (B) as a wider pulse or gap.

If you increase the value of the capacitor, so the cut-off frequency of the filter is lower, the stretched pulses / gaps are accentuated:

filter2.png

thanks for the information, really useful stuff there, i will look more in to it!

majenko:
Take the following little circuit:

Two square waves summed gives the IR signal and the ambient light. You can see how after the capacitor (point A) the signals are converted into pulses - positive for the leading edges, negative for the trailing edges. When the ambient light changes you get a large pulse, and this affects the subsequent few high frequency pulses, as can be seen in the output trace (B) as a wider pulse or gap.

If you increase the value of the capacitor, so the cut-off frequency of the filter is lower, the stretched pulses / gaps are accentuated:

I have been looking in to this, the high pass frequency is 1/(2pir*f) right? in a circuit like this: http://upload.wikimedia.org/wikipedia/commons/thumb/f/fe/High_pass_filter.svg/210px-High_pass_filter.svg.png

guessing that R is the 1k resister in your diagram the frequency would be 1 / (2 * 3.1415 * 1000 * 0.0000001)=1592 hz this is way over the 200 hz you have, if i add the 10k resisters you have before the cap it then makes the pass range below 200 but why do it the way you did and not just have a 10k resister in place of the 1k one? also i guess that op amp is in saturate mode?

It's all a balancing act, between how fast you want it to react to changes in ambient light, and how much of the original square wave you want to retain. The values I chose are just random ones to illustrate the point. Better ones can (and should) be chosen.

As you can see in the first set of traces the filtered square wave turns into pulses (as I mentioned). This has the advantage that the ambient light filtering is better, but it relies on the op-amp to clean the signal up again. As you're not interested in the size of the pulses, just the frequency of the pulses, it's not a problem at all.

Remember, a square wave contains lots of high frequency harmonics that don't get filtered out by the high pass filter (those are what make up the pulses). For instance, a 1KHz square wave would also have frequencies of 3KHz, 5KHz, 7KHz, 9KHz, ad infinitum.