Arduino Due - Hardware Pulse Counter for 10MHz signal


I am using an Arduino Due for a project where I want to the following:

  • Count the number of pulses of a 10MHz square wave

  • Everytime a 1Hz trigger is set, the code gets the current count and resets it to keep counting

  • All this done by hardware while at the same time the arduino is doing other stuff:

  • SPI Communications

  • I2C Communications

  • R/W on a SD data logger

  • Calculations

(This are not all done simultaniously, but follow a specific order where I want to get values from different sensors, but I am not sure if the 10MHz pulse counting would interfere in such accesses. And also I wouldn't like to compromise the counter integrity doing so.)

I am not sure if this is possible in an Arduino Due. I only want to get the current count when i get the trigger signal, but i don't want to occupy the CPU while counting the 10MHz pulses. Everytime I get the trigger the algorithm would start by reading the count before doing the other things metioned above.

I have some experience with Arduino UNO but i have never used a Due before. My questions are:

  • Is this possible?
  • If so, how accurate can i expect the pulse counting to be?
  • How should I do it? (What approach? Examples?)

Can someone please help me with this problem?

The number of pulses is supposed to be 10M ! or are you expecting something else ?

I am expecting 10M pulses but with plus or minus a few pulses like 10M+1, 999.999 pulses some other times.

I am building a GPSDO (GPS Disciplined Oscilator) and I can rely on the 1Hz pulse to be exactly on time, but the 10MHz pulse will drift slightly (in frequency). In order to correct that drift I would like to have a good enough resolution to check wether the 10MHz signal was off by at least 1 pulse. And thus verify if I am actually at 10MHz or 10.000.001Hz. Or something close.

Dividing down the 10MHz signal would decrease the resolution I wanted to perform an accurate correction. So that is an option I would like to avoid if possible.

That is the reason I want to count it that way (hardware) while at the same time keeping the CPU free to run other stuff. But I don't understand very well how it actually works to implement an hardware counter, and if this idea I described is doable. The main loop operations wouldn't interefere with the counter and viceversa.

A few thoughts:

  • It's a rather complex project ...

  • If you are looking for any drift above 1 period of a 10 MHz signal, you should consider any jitter above 10^-7 second being a no go.

  • The internal 12 MHz crystal of the DUE itself can drift due to temperature drifts. Maybe a first step would be to replace it with a temperature compensated 12 MHz crystal. A (poor) workaround might be to precisely calibrate the drift of the DUE Master clock frequency against temperature variations with its builtin temperature sensor connected to A15.

  • The best input capture precision is provided by the 2 embedded quadrature decoders QDEC0 and QDEC1. A 10 MHz signal could be seen as a quadrature encoder pulse outputing 40 000 000 edges/s. The 1 Hz signal could be seen as the Index signal of a quadrature encoder. However, 40 M edges/s is very close to the limits of the quadrature decoder capabilities (Max 42 M edges/s). For this reason, I suggest you divide the 10 MHz input signal by 2.

  • If you want to try out the solution with a quadrature decoder, you will have to provide PHA with the 10 MHz/X pulse (use a digital pulse divider), PHB with a delayed of this pulse of approwimately half a period. For that you could use an RC circuit with a time constant of half a period 0.5 * (10^-7) * X.

Some time ago I posted a QDEC sketch for position measurement that you could leverage. Using the Index signal straight into the quadrature decoder would reset PHA counter which is what you want. BUT you want to record PHA counter right before the Index signal rises up....Therefore I suggest to connect the Index signal on one of the Schmitt trigger input GPIO instead, trigger an interrupt on rising edge ( takes ~ 8 * 84 MHz clock cycles, do not use attachinterrupt()) and inside the interrupt handler log PHA counter.

This topic was automatically closed 120 days after the last reply. New replies are no longer allowed.