Author Topic: Load capacitance for a 32.768 kHz watch crystal and ATmega328  (Read 613 times)

0 Members and 1 Guest are viewing this topic.

Offline VinzCTopic starter

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Hi all.

The current project (let's say "doodle") I'm fiddling with is an ATmega328 clock using an external watch crystal (32768Hz) I salvaged years ago — and I don't have the datasheet unfortunately. The project uses the watch crystal between TOSC1 and TOSC2 pins and two load capacitors. The crystal is bound to timer 2, which I've programmed to pulse OC2B (PD3) once in every second. I have also written a C program for use on a Raspberry Pi to count those pulses in order to time rising edges between the first and last counted events (OC2B drives an optocoupler connected to a GPIO pin on the Pi).

EDIT: FWIW the Pi is a model 2 B+.

According to the datasheet, the typical load capacitance for a crystal is 12 to 22 picofarad. Thanks to my timing application on the Raspberry Pi, I could bring the drift down to something around 5.8 ppm, which amounts to losing one second in about 40-50 hours or so. However the load capacitors I've had to use are way below the typical values: 1.8pF (TOSC1) and 3.3pF (TOSC2). The thing is without these the crystal oscillates way too fast, i.e. 30 ticks take about 29 seconds...

Is that somewhat expected? So far the timer has never failed a start though. Did I miss something?

Thanks for any hint and suggestion.
« Last Edit: April 07, 2024, 12:19:39 pm by VinzC »
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4799
  • Country: pm
  • It's important to try new things..
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #1 on: April 06, 2024, 02:12:04 pm »
Those 32kHz watch xtals are for typ 6 or 12pf. A single cap of 6 or 12pF at the input of the xtal invertor (inside the chip) will do the job, imho.
Make yourself a "gimmic capacitor" and try to tune the xtal with it.
 
The following users thanked this post: VinzC

Offline Peabody

  • Super Contributor
  • ***
  • Posts: 2020
  • Country: us
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #2 on: April 06, 2024, 02:38:15 pm »
Quote
The thing is without these the crystal oscillates way too fast, i.e. 30 ticks take about 29 seconds...

Could changing the Timer2 overflow value by one make this work?

Edit: Well, not the overflow, but whatever you use to count up to 32768, or 32767.

« Last Edit: April 06, 2024, 02:52:28 pm by Peabody »
 

Offline VinzCTopic starter

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #3 on: April 06, 2024, 03:55:44 pm »
Could changing the Timer2 overflow value by one make this work?

Edit: Well, not the overflow, but whatever you use to count up to 32768, or 32767.
I will use software correction anyway. This in particular is off-topic however.
 

Offline VinzCTopic starter

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #4 on: April 06, 2024, 04:03:15 pm »
Those 32kHz watch xtals are for typ 6 or 12pf. A single cap of 6 or 12pF at the input of the xtal invertor (inside the chip) will do the job, imho.
Excellent, thanks! I won't worry too much then ;-) .

I'm not sure which is the input but the datasheet indicates TOSC1 has about 18pF and TOSC2 about 6pF. I guess the one with the highest capacitance is the input, right?

EDIT: Attached is an excerpt from the datasheet in question.

Make yourself a "gimmic capacitor" and try to tune the xtal with it.
That reminds me of a demo by the IMSAI Guy on youtube who used the same method to tune a one-turn coil to build an oscillator with a tunnel diode  :-+
« Last Edit: April 06, 2024, 04:12:11 pm by VinzC »
 

Offline iMo

  • Super Contributor
  • ***
  • Posts: 4799
  • Country: pm
  • It's important to try new things..
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #5 on: April 06, 2024, 06:19:37 pm »
The input is the XTAL1 pin, afaik.
Put there the gimmick cap against ground.
The gimmick cap IMSAI_GUY is showing is rather gigantic one, indeed :) And it is not his or mine invention, of course :)
I've been talking about a normal useful gimmick capacitor, made of say 0.2mm diameter enameled copper wire, usually 10mm == 10pF, while the length of the gimmick cap on my above picture is 10mm :)
PS: I doubt the SW compensation would work as the 1LSB timer step at 32kHz is too coarse.
« Last Edit: April 06, 2024, 06:25:20 pm by iMo »
 
The following users thanked this post: VinzC

Offline VinzCTopic starter

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #6 on: April 06, 2024, 06:38:03 pm »
The input is the XTAL1 pin, afaik.
Put there the gimmick cap against ground.
:-+

PS: I doubt the SW compensation would work as the 1LSB timer step at 32kHz is too coarse.
Quite the contrary, it's possible, just not in real time¹: since I can time the duration between two events (that is the purpose of the Raspberry Pi), say counting 3600 rising edges, I get the accumulated drift (compared to the clock of the measuring device, of course). Then I compute the average drift in ppm (as a fractional number). One over that is the amount of seconds after which I need to either skip or add one second.

I'm calling system_tick() every second otherwise. The correction would be very approximate but (I hope) somewhat effective, relatively.

¹ I'm considering stepping the "clock" or ticks after a given period.
« Last Edit: April 06, 2024, 06:52:31 pm by VinzC »
 

Offline PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1563
  • Country: au
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #7 on: April 06, 2024, 08:07:21 pm »
However the load capacitors I've had to use are way below the typical values: 1.8pF (TOSC1) and 3.3pF (TOSC2).
Is that somewhat expected?
Yes...
Correct C will certainly shift the kHz and allow single digit ppm trim.

The thing is without these the crystal oscillates way too fast, i.e. 30 ticks take about 29 seconds...
and no...

Incorrect CL should never be off by the 3% you claim here. There may be other factors at play here.

eg TI have an app note showing a 7pF crystal loaded with just 1pf will be off by  1-32778/32768 = 305ppm

 
The following users thanked this post: VinzC

Offline Peabody

  • Super Contributor
  • ***
  • Posts: 2020
  • Country: us
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #8 on: April 06, 2024, 10:35:26 pm »
So is the Raspberry Pi the time standard against which the crystal is measured?  Do you have any reason to believe it is more accurate than the watch crystal, or the 328P's crystal for that matter?
 

Offline VinzCTopic starter

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #9 on: April 07, 2024, 08:55:25 am »
[...] Incorrect CL should never be off by the 3% you claim here. There may be other factors at play here.

eg TI have an app note showing a 7pF crystal loaded with just 1pf will be off by  1-32778/32768 = 305ppm
Good you stressed on that. I indeed fixed a few bugs in my calibration software after I measured the crystal frequency without any load capacitor. I'll redo the measurement again and see. Thanks for pointing that :-+

So is the Raspberry Pi the time standard against which the crystal is measured?  Do you have any reason to believe it is more accurate than the watch crystal, or the 328P's crystal for that matter?
Good question. If you read my previous post, you'll see I hinted about that¹. Of course I have no means to assess the precision of that crystal. I initially thought (rather hoped) synchronizing the Pi with NTP would yield a rather stable clock (in the millisecond drift, kind of) but later realized/read the timer I'm using in my software isn't affected by NTP. But I also later read the precision of Pi's timers is "pretty accurate" without any data to back that up... :-//

So since I don't have the proper gear to measure the frequency of interest, I'm left with measuring accumulated errors, relatively to a clock that is known to be somehow accurate. I stuck to that method I described. Anyway I have planned to use the EEPROM of the MCU to store a correction factor, which I explained the use earlier in my posts, i.e. a 32-bit duration after which the MCU shall skip or add a second.

BTW the watch crystal is the ATmega328's crystal². It is not an Arduino but a bare microcontroller that I wired on a breadboard (alright, not the best context to calibrate the thing, I admit). The only barebone clock source in that thing is the internal RC oscillator. There's also an internal, low power 32kHz oscillator but the latter accuracy is rated... 30% while the former's is in the percent range.

¹ Quoting myself «I get the accumulated drift (compared to the clock of the measuring device, of course)»
² Just not the main clock but programmed to be timer 2's asynchronous clock source.
« Last Edit: April 07, 2024, 09:11:05 am by VinzC »
 

Offline VinzCTopic starter

  • Regular Contributor
  • *
  • Posts: 227
  • Country: be
  • See you later, oscillator.
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #10 on: April 07, 2024, 09:25:28 am »
I initially thought (rather hoped) synchronizing the Pi with NTP would yield a rather stable clock (in the millisecond drift, kind of) but later realized/read the timer I'm using in my software isn't affected by NTP.

Well I have to retract what I just wrote :D .

I've run the calibration program again but this time *before* the system clock was synchronized (read: stepped) by the NTP daemon. I then saw a sudden increase in the delta, i.e. a few thousands of seconds, which clearly indicated the function I'm using, timespec_get(), is indeed under the influence of the NTP daemon. Now is its drift it also corrected by the daemon in real time? That, I'm not really sure but that is promising as NTP might exhibit some jitter but the atomic clocks on which it's based make me expect a relatively low drift, provided I multiply the calibration exercise to get an average drift for my watch crystal, of course.

EDIT: And after running the calibration software without any load capacitor, I get a drift about 9.9ppm, which amounts to a one second correction in 28h20m or thereabouts. I'll try fiddling again with those capacitors and see what gives.

EDIT:... and I get 3.7ppm drift with a 3.3pF capacitor at the oscillator input. I think I'll stop fiddling here as I get results that are consistent enough, especially something totally manageable now.

So thanks for your hindsight, guys.
« Last Edit: April 07, 2024, 09:54:48 am by VinzC »
 

Offline Peabody

  • Super Contributor
  • ***
  • Posts: 2020
  • Country: us
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #11 on: April 07, 2024, 02:25:18 pm »
I had a similar task recently that involved calibrating the Aging register of a DS3231 RTC to its optimum value.  I bought a cheap ($13) GPS module on Amazon, and used its PPS output to compare to the 1Hz squarewave output of the RTC.  I counted the number of 16MHz processor cycles of a Nano between the two edges, and adjusted Aging until that difference stopped changing, or as nearly as possible.  The DS3231 is pretty accurate because it has a built-in automatic temperature compensation feature.  In theory it should be possible to adjust Aging to get the RTC to within just a few seconds a year.  The accuracy of the Nano isn't important so long as its resonably consistent in the short run.

I think the GPS PPS signal is the closest thing we have to perfect time, certainly better that NTP.  So maybe you could check your Pi frequency against that.  But everything except PPS changes with temperature and power supply voltage.  Anyway, here's what I did:

https://github.com/gbhug5a/DS3231-Aging-GPS
 
The following users thanked this post: VinzC

Offline PCB.Wiz

  • Super Contributor
  • ***
  • Posts: 1563
  • Country: au
Re: Load capacitance for a 32.768 kHz watch crystal and ATmega328
« Reply #12 on: April 07, 2024, 08:57:41 pm »
.... I initially thought (rather hoped) synchronizing the Pi with NTP would yield a rather stable clock (in the millisecond drift, kind of) but later realized/read the timer I'm using in my software isn't affected by NTP. But I also later read the precision of Pi's timers is "pretty accurate" without any data to back that up... :-//

So since I don't have the proper gear to measure the frequency of interest, I'm left with measuring accumulated errors, relatively to a clock that is known to be somehow accurate. I stuck to that method I described.


Google find this, from a while ago

Quote
I measure the actual frequency on GPIO4 using an HP5328 counter which has been recently GPS calibrated and has a frequency error of better than 0.010 PPM. From this, I calculate the actual PPM error of the crystal to be around -43 PPM. It varies a bit with room temperature, but rarely differing by more than 0.5 PPM from -43 PPM.
I use "ntpdc -c loopinfo" to query the NTP measured frequency offset and I consistently get values around -45.5 PPM. Again due to temperature variations and network jitter/ load I do see some variations around -45.5, but rarely exceeding 0.5 PPM.
The difference between the actual PPM error and the NTP measured PPM error seems to consistently be about 2.5 PPM, plus or minus 0.5 PPM.

So it looks like you can measure your short-term 'stable' Pi Clock using that query, to get down to low-ppm errors, which is probably good enough for your purposes.
Looks like there is some debate around the absolute precision of that NTP report if chasing final ppm numbers.

and also this from more recent :

Quote
Calibration:
  As of 2017-02, NTP calibration is enabled by default and produces a frequency error of about 0.1 PPM after the Pi has temperature stabilized
  and the NTP loop has converged...

  NTP calibration:
  NTP automatically tracks and calculates a PPM frequency correction. If your Pi is connected to the internet and you are running NTP, you can use the  --self-calibration option to have PiCW periodically querry NTP for the latest frequency correction.
 Some residual frequency error may still be present due to delays in the NTP measurement loop.
This method works best if your Pi has been on for a long time, the crystal's temperature has stabilized, and the NTP control loop has converged.


With 10ppm xtals common these days, it is nice to somewhat centre that error.

At some point, investing in a GPS 1pps source will become a good idea  8)

EDIT: FWIW the Pi is a model 2 B+.

I also find this more recent web comment :

Quote
Note that for NTP it’s better to use a Raspberry Pi 4 than older boards. The old ones have their ethernet port on the wrong side of a USB hub, so their network suffers from millisecond-level packet timing jitter. You will not be able to get microsecond-level NTP accuracy.
« Last Edit: April 07, 2024, 09:08:43 pm by PCB.Wiz »
 
The following users thanked this post: VinzC


Share me

Digg  Facebook  SlashDot  Delicious  Technorati  Twitter  Google  Yahoo
Smf