using timer1 to read 230kHz-300kHz signal

Is it feasible to do this? I was thinking of writing a program that reads the pin state at the frequency the timer is set to in order to obtain the frequency of a signal at the pin and any changes in this frequency as part of a metal detector project I am doing. I am not too familiar with the timer library so comments on the feasibility of this and any hints people can offer would be greatly appreciated.
Thanks very much,
-TW

I think you'll be pushing it.

A 300 kHz signal means 1/300e3 is the time between pulses, namely 3.33 uS.

A 16 MHz processor has a clock frequency of 1/16e6, namely 62.5 nS.

Each instruction takes around 1 to 3 clock cycles, so say two on average.

In the time period 3.33 uS you can fit (1/300e3) / (1/16e6) = 53.33 clock cycles. That is, around 26 instructions.

That would be barely enough to test if the signal has changed, load a memory location, add 1 to it, and store it, at the same time keeping track of the interval between accesses.

If you use interrupts, it takes around 3.5 uS to enter an ISR, but you only have 3.33 uS. Not quite enough time, and the ISR has to actually do something.

So, no, I doubt it. Maybe just.

Perhaps someone will correct me, but I think it's very very tight.

1 Like

Example
Task: Measure the frequency of an external 122 Hz - 100 kHz logical square signal using an 8 MHz ATmega128.

Quoted from: http://home.roboticlab.eu/en/avr/timers Code: Timing Events
So, 200 kHz on 16 Mhz arduino. I'm sure you can tweak it up, there are some thoughts what I'd try:
not using division operation inside ISR, measure just period in "ticks";
using int instead of long;
get rid off "if" statement.
But problem with "granularity" of results would still persist, as there are only ~50 ticks , you can register only 2% changing in frequency, that (IMHO) too much for metal detector. Next step to increase accuracy is fill up an array (the bigger the better) with data and calculate average ( at this point floats and division are allowed to get freq.) Due presence of noise (this is one of not many cases where noise is "helpful") it should works in similar way what they call "oversampling" technics.

twarcup:
Is it feasible to do this?

Just entering and leaving your interrupt routine will take longer than the time you have to take a sample. This means that you can't do it as an interrupt, you have to do it as a tight polled loop.

However, then the next question is: where are you getting the data from? Is it an external input using something like I2C, or is it an analog signal, or is it a digital signal?

If it's I2C, then the data rate won't be high enough to actually sample at that rate.
If it's analog, then the Arduino built-in ADCs actually don't have sufficient bandwidth for high precision sampling at that rate.
If it's digital, you may be able to do it polled, not continuously, but taking snapshot samples. Something like this:

wait for signal to go high
count how many loop iterations until signal goes low
count how many loop iterations until signal goes high
now, you can calculate approximate frequency and duty cycle, and do whatever you need

Also, you can't use digitalRead() for this, as it has some function call overhead; you probably want to use inline assembly or some compiler intrinsic to read the input pin value directly.

I'm just laughing at my own previous post, no mistake, everything correct, except
OP asking for measurements of frequency ( the easiest what could be task for microprocessor ),
but was given the answers how to measure PERIOD or duty cycle.
There is a link:
http://interface.khm.de/index.php/lab/experiments/arduino-frequency-counter-library/
Thats right, start timer and count pulses at the input, this way the higher frequency, the more accurate results....

ack, I am trying that link from the lab at school but it won't load no matter what.. is there any other way of getting that include so I can test things out?
Thanks,
TW

It's not loading for me either. Try Googling "arduino-frequency-counter-library" and follow one of the working links, see if that helps.

Magician:
OP asking for measurements of frequency ( the easiest what could be task for microprocessor ),
but was given the answers how to measure PERIOD or duty cycle.

There is an upper limit to counting even pulses for any particular microprocessor.
Once you're past the Nyquist frequency in sampling your pulses, you will miss some low-to-high transitions, and your count will be off.
I think most of this article is about figuring out whether you could even theoretically count pulses accurately at 320 kHz.
I think the answer is "possibly, for some sample interval, but certainly not if you use interrupts for pulses."

I haven't used any of them, but Google suggests that there are various frequency-to-voltage converters around. If you can get one that handles the frequency range you're using, it might be easier to do the frequency detection in hardware and have your Arduino just monitor the result. (Depending what you want to do once you have measured the frequency, maybe you can do away with the Arduino altogether.)

Link was O'k yesterday, now it's not opening for me ether.... Luckily, I have a copy :slight_smile:

FreqCounter1.zip (3.6 KB)