Load capacitance for a 32.768 kHz watch crystal and ATmega328 - Page 1
Forum section: electronics / projects

author: VinzC
author_rank: Frequent Contributor
timestamp: April 06, 2024, 09:03:08 am
content: 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.

author: iMo
author_rank: Super Contributor
timestamp: April 06, 2024, 02:12:04 pm
content: 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.

author: Peabody
author_rank: Super Contributor
timestamp: April 06, 2024, 02:38:15 pm
content: QuoteCould 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.

author: VinzC
author_rank: Frequent Contributor
timestamp: April 06, 2024, 03:55:44 pm
content: Quote from: Peabody on April 06, 2024, 02:38:15 pmI will use software correction anyway. This in particular is off-topic however.

author: VinzC
author_rank: Frequent Contributor
timestamp: April 06, 2024, 04:03:15 pm
content: Quote from: iMo on April 06, 2024, 02:12:04 pmExcellent, 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.Quote from: iMo on April 06, 2024, 02:12:04 pmThat 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

author: iMo
author_rank: Super Contributor
timestamp: April 06, 2024, 06:19:37 pm
content: 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, indeedAnd it is not his or mine invention, of courseI'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 10mmPS: I doubt the SW compensation would work as the 1LSB timer step at 32kHz is too coarse.

author: VinzC
author_rank: Frequent Contributor
timestamp: April 06, 2024, 06:38:03 pm
content: Quote from: iMo on April 06, 2024, 06:19:37 pmQuote from: iMo on April 06, 2024, 06:19:37 pmQuite 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 callingsystem_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.

author: PCB.Wiz
author_rank: Super Contributor
timestamp: April 06, 2024, 08:07:21 pm
content: Quote from: VinzC on April 06, 2024, 09:03:08 amYes...Correct C will certainly shift the kHz and allow single digit ppm trim.Quote from: VinzC on April 06, 2024, 09:03:08 amand 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

author: Peabody
author_rank: Super Contributor
timestamp: April 06, 2024, 10:35:26 pm
content: 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?

author: VinzC
author_rank: Frequent Contributor
timestamp: April 07, 2024, 08:55:25 am
content: Quote from: PCB.Wiz on April 06, 2024, 08:07:21 pmGood 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 thatQuote from: Peabody on April 06, 2024, 10:35:26 pmGood question. If you read myprevious 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 crystalisthe 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'sasynchronousclock source.

author: VinzC
author_rank: Frequent Contributor
timestamp: April 07, 2024, 09:25:28 am
content: Quote from: VinzC on April 07, 2024, 08:55:25 amWell I have to retract what I just wrote.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.

author: Peabody
author_rank: Super Contributor
timestamp: April 07, 2024, 02:25:18 pm
content: 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

author: PCB.Wiz
author_rank: Super Contributor
timestamp: April 07, 2024, 08:57:41 pm
content: Quote from: VinzC on April 07, 2024, 08:55:25 amGoogle find this, from a while agoQuoteSo 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 :QuoteWith 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 ideaQuote from: VinzC on April 06, 2024, 09:03:08 amI also find this more recent web comment :Quote