Observations of frequency measurement of a square wave -- advice requested

Hi all,

I am new to Arduino but would like to state a few observations, and then get your thoughts regarding whether my explanations of the observations seem reasonable!

We are measuring the frequency of the TSL235R light to frequency converter. It puts out a nice, de-bounced square wave with frequency up to 1 MHz when it is very bright, all the way down to, say, 10 Hz when it is very dark.

I have measured this frequency three different ways:

1) with digitalRead combined with simple boolean logic. When the new digitalRead measurement changes from HIGH to LOW, the program can record an edge and calculate frequency.

OBSERVATION: This method seemed particularly unreliable, and yielded strange, random fluctuations in frequency even when light levels were stable.

2) with an interrupt routine like the one found here:https://playground.arduino.cc/Main/TSL235R/. This option was very appealing to me, as I understand the interrupt fires whenever the pin equipped with interrupt functionality catches an edge.

OBSERVATION: The method did indeed work very reliable, but only up to ~ 125 kHz. Beyond this, it seemed everything else in the code failed to execute. For example, the serial monitor would simply go blank, then when the light levels were reduced, it would yield a very high count (for just one data point), which I assume the interrupt had been catching for the entire time. I suspect the interrupt executed so frequently, that everything else in the code was essentially ignored.

3) with the FreqCount library described here: https://www.pjrc.com/teensy/td_libs_FreqCount.html. This library was like some amazing black magic! It has worked very well at the highest frequency range of the sensor -- that is, about 1 MHz. No issues. However, I would really like to know more about how it works. For example, why does it require the signal be wired to pin 47 on our Mega board? Anything special about that pin? The library is like a black box to me now.

Thanks so much for your time! If I can explain anything else better, let me know :)


Looking at the Mega 2560 pinout, pin 47 on the processor has the label ICP1 - this stands for Input Capture. Where it lives on the 2560 is unknown to me but on the ATMega328 (UNO processor) it's part of TC1. You might gain some insight examining the 328 datasheet Timers section on Timer/Counter 1 or, find the 2560 datasheet.

Here is an excellent tutorial on Arduino timers, including use of the Input Capture feature of Timer1 to measure frequency.

That's the clock input pin - you set the timer for use with external clock, and can count pulses at speeds of up to f/2 (so 8 MHz signals for a 16 MHz processor clock).

Works like a charm indeed. I've used this technique myself (but not the library) to count 4-6 MHz signals.

On a Mega you have four 16-bit timers, so you should be able to count four such signals. As it's all done in hardware, there's no overhead. Check the data sheet for which pin refers to which timer input.

Thank you all very much for the help. This is great. I'm diving into the tutorial link right now.

It makes sense that this FreqCount library accesses the 16 MHz clocks to do counts, and record over what time interval they occurred.

I'm also excited that I have four 16-bit timers! That means I can add more light sensors positioned in different orientations on the instrument!