##### Adding USB support to a barebone microcontroller project

When I asked the potential users of the frequency counter I am working on their advice on the design, most of them wrote to me that they actually would...

In this post we are going, just for once, to focus mainly on theoretical concepts, to explain the microcontroller performance when using direct and reciprocal frequency measurement.

**Direct frequency measurement**means that we are counting the wave fronts during one second. Hence we get a direct measure of the number of repetitions of the signal during one second, expressed as a frequency (noted f).**Reciprocal frequency measurement**means that we are measuring the duration of only one period of the signal (noted p), expressed in seconds.

This paper is objective is to expose the limitations of resolution and accuracy, and the techniques used to count frequencies over a **very large bandwidth**. Possibly you might want to skip the pure theory section and get to the theoretical experiment.

Basic theory of frequency vs period

Microcontroller computation techniques

Direct frequency measurement with a microcontroller

Reciprocal frequency measurement with a microcontroller

Limitations

1) Upper frequency limit

2) Accuracy

3) Resolution

Theoretical experiment

Operational hypothesis

1) Reciprocal counting resolution and domain of operation

2) Direct counting resolution and domain of operation

3) Reciprocal + direct counting resolution and domain of operation

4) Introducing the maximum frequency and clock accuracy limitations

5) Extending the domain of operation

6) Proposed display resolution

Real world application

In theory we can compute the frequency from the period (duration of a cycle) or the period from the frequency with this function

f = 1 / p that is equivalent to p = 1 / f

For example a 10 Hz signal has a period p = 1/10 = 0.1 second.

Our first problem is that when using a microcontroller we don’t have access to a precise time reference. What we have available is the number of microcontroller clock counts that executed while measuring the signal.

Since we know our microcontroller is clocked at 10 MHz (as an example), after we count 10 000 000 clock counts we know that a time duration of approximately one second has passed. So we just have to

- start to count the mcu (i.e. microcontroller) clock fronts in a counter (let’s call it counter 1)
**count every signal fronts**that we see on an input (in counter 2)- when the mcu clock “counter 1” reaches 10 000 000, we stop counting the signal fronts in counter 2.

The number in the counter 2 equals the frequency of the signal. For example counter 2 = 1000 means the signal has a frequency of 1 KHz and a period of 1/ 1000 = 0.001 seconds.

We can approximate the period of the signal in seconds with the function

p = clock counts (during one period of the signal) / mcu clock frequency

To achieve this we have to

- start to count the
**mcu clock fronts in a counter**when we see a signal front. - stop to count the
**mcu clock fronts**in the counter as soon as we see another signal front

For example if we count 1000 clock counts between two fronts of the waves, that is during a whole period, we compute the period as p = 1000 / 10 000 000 = 0.0001 second

And we deduct the frequency as explained above f = 1/0.0001 = 10 KHz

The main point of this paper will be to expose the limitations of this technology:

When direct counting it is not possible to count frequencies higher than half the microcontroller is clock frequency. This is explained by the Nyquist theorem. (Wikipedia full and complex explanation).

So, in our example, **the maximum frequency that can be counted is 10/2 = 5 MHz**.

But, **we might cheat a little by using a prescaler**. This is an external device that will pre-count the signal. It will output one clock signal every time it has seen a certain binary number of fronts on its input. In this example we will consider a 16:1 prescaler. That is we will be able **to count up to 16 x 5 = 80 MHz **

Common prescalers are 74HC93, 74VHC4040 and many others.

We just explained that our knowledge of time duration depends on to the microcontroller is clock frequency. Unfortunately this clock is not perfect. It vibrates at approximately its defined frequency (10 MHz here). But its accuracy error does create as much error in our computation. We will express this error in ppm. If the error of the clock is 1 part per million, that is our measuring of one second can be wrong at most by 1/1000000 of a second. Our computation will also have an error of 1 ppm. This creates an uncertainty **on the 7th digit** of our computation.

**This error in accuracy of around 1 ppm (on the frequency value + as much of drift due to temperature + aging) is the best we can get from nowadays small and affordable TCXO clock chips**. It was more in the 50 ppm range only a few years ago. Looking for an even better accuracy would need more advanced, much more costly and space consuming devices.

Then we also have to consider the inner working of the MCU (internal signal propagation and management) and the fact that this computation is based on a code that executes on the MCU (with delays of code execution and possible queuing when using interrupts). In consequence a 1 ppm device is a good choice and we might not get much more accuracy when using a more accurate clock with these relatively simple techniques. And because of the different sources of errors the total accuracy will probably be above 1 ppm and not constant over the all bandwidth. But we will not consider these too complicated and ill-defined aspects of the problem.

We will consider that the **total raw inaccuracy** of our circuit (frequency + temperature drift + aging + computation errors)** is less than 10 ppm (6 digits)**.

But, to compensate some of the inaccuracy, the program might include a calibration mechanism. This would allow to reduce the **total inaccuracy when calibrated to possibly as low as 1 ppm (7 digits)**.

Now, we have another big problem. Since we measure the time in terms of clock counts, we are working with digital data. We can’t measure with more resolution than 1 clock count. This brings a **terrible limitation** to our approximation of the frequency.

- When using direct frequency measurement, the resolution is one signal front per second i.e. 1 Hz. The equation that defines the resolution (see later charts) expressed as digits is
**Res = log(freq) +1**- For example if we measure a 10 KHz signal this means that the resolution gap is visible on the
**5th digit only!**

- For example if we measure a 10 KHz signal this means that the resolution gap is visible on the
- When using reciprocal frequency measurement, the resolution is the counting of 1 clock front for a total count of n clock fronts counted during one period of the signal. It can be expressed as
**Res = log( f_mcu_clock / f ) +1**- for example if we measure a signal of 10 KHz the resolution gap is visible on the
**4th digit only!**

- for example if we measure a signal of 10 KHz the resolution gap is visible on the

From this we can see that direct frequency measurement has a reasonable resolution only for high frequency signals, while reciprocal frequency measurement has a reasonable resolution only for low frequency signals.

Thus if we want to create a frequency counter that covers very lows up to very high frequencies, we need to use both computation methods.

After reading the theory section we know that our measurement system is limited. We have to consider these parameters:

- We will be using a microcontroller clocked at 16 MHz by a TCXO having an accuracy of 1 ppm, plus other sources of inaccuracy for a total of 10 ppm.
- This gives a theoretical upper limit of the measurement at 8 MHz (Nyquist theorem). But we will also consider using a 16:1 prescaler to increase this limit to 16*8 = 128 MHz
- We would like to have
**the maximum resolution possible and at least**a minimum of- 4 digits for low frequencies (under 10 KHz)
- 5 digits for high frequencies (above 10 KHz)

As seen above the resolution **Res = log(f_mcu_clock/f) + 1** is plotted on this chart

**The green area is the low frequencies domain of operation**. It is the area between the minimum of 4 digits of resolution and the maximum theoretical resolution. When measuring frequencies from 1 Hz to 10 KHz we are certain to get the minimum resolution we would like.

- We can go as far as (a little more than) 8 digits of precision when measuring a 1 Hz signal with our microcontroller clocked at 16 MHz.
- But we can see that the resolution would fall down to only (a little more than) 1 digit at 10 MHz. So it is not suitable for high frequencies.

As seen above the resolution **Res = log(freq) +1 **is plotted on this chart

**The green area is the high frequencies domain of operation**. It is the area between the minimum of 4 or 5 digits of resolution that we chose and the maximum theoretical resolution. When measuring frequencies from 1 KHz to the upper limit we are certain to get the minimum resolution we would like.

- In pure theory we can go as far as 10 digits of precision when measuring a 1 GHz signal but our microcontroller clock of 16 MHz will not allow this (read next).
- But we can see that the resolution would fall down to only 1 digit at 1 Hz. So it is not suitable for low frequencies.

**When using both computations we can extend the domain of operation from the very low frequencies to the ultra high frequencies. **Here we have

- Up to 8 digits of resolution at 1 Hz.
- Up to 10 digits of resolution at 1 GHz.
- Always a minimum of 4 to 5 digits as we wish.

Now if we add the limitations that we exposed before regarding the maximum frequency that can be measured and the accuracy of the microcontroller clock, the domain of operation gets limited.

- The yellow line is the accuracy limit. It is constant over the bandwidth. We will always get some imprecision above the 6th digit.
- The purple line is the maximum frequency that can be measured, depending on the microcontroller clock frequency.

We can see that the domain of operation has been much narrowed. But we still maintain the resolution we wanted. And **we can build a frequency counter that will work as expected from 1 Hz to 8 MHz**.

We have exposed that we might increase the upper frequency limit by using a prescaler. And we can also push the accuracy limit by calibrating the device. Here is what we should get

**When using a 16:1 prescaler we can see that we can extend the domain of operations from over 1 Hz to 128 MHz. **

We used the prescaling in two stages 4:1 at 5 MHz and 16:1 at 20 MHz. So, even though we reduced the theoretical resolution, the direct counting resolution line (in dark blue) it is still above the accuracy error and preserves the domain of operation.

After calibrating the device we expect to reduce the accuracy error from 10 ppm to 1 ppm at best, providing some overhead (light green area) in the domain of operation.

In this paper we have shown that the microcontroller performance when using direct and reciprocal frequency measurement depends a lot on the mcu clock speed and accuracy, but that we have techniques to increase the performance of the device.

Now that we know the resolution profile, we can choose how to display the results. Here, we have to define a profile of **display resolution**.

If we prefer to be conservative and the device is not calibrated we can use a display resolution profile like this one

**This profile guaranties that we will never display any biased values over the all bandwidth even though the device is not calibrated**. We did not exploit the possible high resolution in low frequencies because a regular user might find strange to have a drop of resolution in the mid band.

But if we are ready to take a risk to get a few biased values between 5 KHz and 10 KHz, if the device is calibrated and if we want to use the enhance resolution in the low frequencies band we could use this profile:

This profile will give us the maximum possible display resolution over the all bandwidth.

These 4 techniques (direct & reciprocal counting, prescaler and calibration) are used in the Arduino compatible frequency counter.