Go Down

Topic: Precision Timings for Frq Measurement (DS3231?) (Read 257 times) previous topic - next topic


Sep 03, 2017, 01:40 pm Last Edit: Sep 03, 2017, 01:51 pm by ianRobinson101

I wonder if anyone can offer a little help here.

I am using an Uno to measure the frequency (~40-100kHz) of a square wave pulse from a fluxgate magnetometer (http://www.starfishprime.co.uk/projects/EFM/EFM.html).

I use the FreqCount routines to count the pulses over a 2 sec interval presenting the output to a PI for processing. The system runs continuously i.e keeps repeating the count.

I need a high level of stability as the system needs a reproducibility  of better than 1:104 as the shifts in magnetic field are of the order of 1 nT, approx 10 -4 of the earth's field.
I am not terribly concerned about the absolute 'accuracy' of the count rather than the timings are consistent over a 24 hr period.

I presume that I can use an external oscillator to provide a more stable clock pulse than the arduino's internal oscillator.

I have an Adafruit DS3231 breakout board but this seems to be a clock rather than a device to supplant the Arduino's oscillator.

Any thoughts on how to make the Arduino's internal oscillator more stable?


Ian Robinson


Find an Arduino with a quartz oscillator perhaps?  The ceramic resonators in many of the boards
are only +/- 0.4% or so absolute, with significant temperature drift.

With quartz precision it should be possible to get pretty stable frequency counting using an ISR, so long
as the frequency doesn't get too high. 

Maybe you could use the 1 second pulses from a GPS unit as the reference, but that relies on being outdoors
for reliable GPS signal.

An RTC module can be programmed for 1 second pulses too, a bit more practical.

100kHz is pretty fast even for an ISR, I fear that's going to lose a few counts when it collides with the timer0
interrupt that's used to maintain the millis() value.

I've used external counter chips in the past for this kind of thing, but it was complicated to read out the
value as a consistent snapshot. The SN74LV8154 was the chip, and I needed various shift registers to
drive it and get the reading out from its 2 16 bit counters.  At the time I couldn't find a convenient
SPI or I2C driven counter chip.
[ I will NOT respond to personal messages, I WILL delete them, use the forum please ]


Sep 04, 2017, 02:08 am Last Edit: Sep 04, 2017, 02:36 am by allanhurst
The millis() built-in takes about 7uS every 1.024 mS to correct it's counters on a AT328 at 16MHz. I've measured this.  So if you looked at the millis() counter, you could be up to 0.7% out in absolute value over 1mS even with a 'perfect' crystal. . If you measured every second that would be reduced to 0.0007% or 7 ppm. Much better.

Typical cheapo crystals can be  up to +/- 100ppm - ie 1  in 10^4. Buy a decent one - 20ppm aren't dear. 3ppm are available. Or you can buy a 0.1ppm VCTCXO for <£20 from eg Magna Frequency.

16MHz is in the 'sweet spot' for crystal manufacturers - ie the best price/performance and stability  area. Having designed pagers which required +/- 2.5 ppm, you tried to specify one in the 12-18MHz 3rd overtone range. They drifted around -0.1ppm over a year, so you tuned a little high on test to allow for settling.

Fit a prescaler - divide by  16 , 32 etc.  Try eg a 74HCT4040. Then the arduino built-ins and interrupt latency are far less significant.

Or just buy a frequency counter - 10ppm ones aren't dear.



Sep 11, 2017, 07:37 pm Last Edit: Sep 11, 2017, 07:43 pm by mrguen
If I understand well you are just looking for constant accuracy and not concerned by the timing error over a long duration.

Normally using FreqCount library and an external crystal of good quality (frequency error under 30 ppm...) + appropriate capacitors (https://blog.adafruit.com/2012/01/24/choosing-the-right-crystal-and-caps-for-your-design/ )  you should get a resolution of 10-5 between 40 Khz and 100 Khz without problem. Your signal conditioning has to be good. You don't need a prescaler. 

Go Up