Bagaimana cara mendapatkan waktu yang akurat?

16

Saya telah membuat jam menggunakan Arduino, tetapi waktu tampaknya melayang. Saya mengetahui masalah rollover ; jam tampaknya melayang sekitar 15 menit selama seminggu.

Saya menggunakan PCB khusus dengan resonator ini dari Digi-key. Kode membaca fungsi millis () pada awal setiap loop, dan bekerja dari nilai itu.

Pertanyaan saya adalah: Bagaimana saya bisa mengukur waktu dengan Arduino, cukup akurat untuk membuat jam meja yang lumayan?

John Walthour
sumber
3
Fungsi milidetik disediakan dengan data dari interupsi, yang membutuhkan beberapa siklus clock untuk dijalankan. Ini menambahkan jumlah waktu sangat kecil untuk setiap centang.
TheDoctor
3
@TheDoctor: Ini tidak benar. Interupsi tidak memperlambat timer perangkat keras yang mendorong millis().
Edgar Bonet

Jawaban:

15

Catatan: meskipun jawaban saya diterima dan memiliki skor suara yang lebih tinggi, pastikan Anda membaca jawaban Edgar Bonet yang luar biasa tentang cara membuat Arduino Anda menjaga waktu tanpa RTC.

Saya sudah cukup berhasil menggunakan DS1307 Real Time Clock. Berikut ini tautan ke lembar datanya .

Berikut adalah beberapa fitur-fiturnya:

  • Menggunakan antarmuka IC untuk komunikasi dengan Arduino, membuatnya mudah untuk diprogram menggunakan perpustakaan yang tepat (tersedia di Net).

  • Terhubung ke Arduino melalui pin SCL dan SDA (masing-masing analog A4 dan A5), sehingga hanya menggunakan 2 pin.

  • Ini membutuhkan sangat sedikit komponen eksternal untuk dijalankan.

  • TI dapat dihubungkan ke baterai sel koin sehingga akan menjaga waktu bahkan saat Arduino dimatikan. Dalam mode daya rendah, baterai sel koin berlangsung selama bertahun-tahun.

  • Ini melayang sangat sedikit (dalam kasus saya hanya melayang beberapa detik per minggu).

  • Itu tidak terlalu mahal.

Jika Anda tidak bermaksud menggunakan RTC, Anda dapat mengganti kristal yang biasanya digunakan untuk menyediakan jam ke Arduino untuk modul osilator kristal seperti ini dari Farnel atau yang lain ini . Mereka datang dalam paket 4 pin seperti pada gambar di bawah ini. Mereka akan menghasilkan jam yang jauh lebih tepat untuk Arduino Anda.

Gambar osilator kristal Gambar osilator kristal Gambar osilator kristal

Kedua modul yang disebutkan memiliki toleransi 50 ppm dan beroperasi pada 5V.

Sekali lagi, hanya untuk menjadi jelas, modul osilator kristal ini tidak menjadi bingung dengan kristal 2 pin biasa seperti ini di bawah ini. Mereka adalah bagian dari sirkuit jam eksternal untuk MCU, misalnya.

Osilator kristal

Ricardo
sumber
Apakah DS1302 cukup baik atau haruskah saya pindah ke DS1307?
Kelly S. French
14

Anda tidak memerlukan RTC untuk membangun jam: chip ATmega memiliki semua perangkat keras yang diperlukan untuk melakukan tugas RTC itu sendiri. Begini caranya:

  1. Dapatkan kristal jam tangan 32768 Hz: beli atau bongkar jam lama. Kristal-kristal ini, yang dirancang khusus untuk menjaga waktu, memiliki pergeseran suhu yang sangat kecil. Anda juga akan membutuhkan salah satunya jika ingin menggunakan chip RTC.

  2. Konfigurasikan sekering ATmega Anda untuk menjalankan osilator RC 8 MHz. Ini akan membuat millis()fungsi Anda sangat tidak akurat, dan juga membebaskan pin XTAL1 dan XTAL2.

  3. Hubungkan kristal arloji ke pin TOSC1 dan TOSC2. Ini adalah pin yang sama dengan XTAL1 dan XTAL2 (9 dan 10 pada 328P). Nama yang berbeda digunakan untuk fungsi yang berbeda.

  4. Konfigurasikan Timer / Penghitung 2 untuk operasi asinkron, mode penghitungan normal, prescaler diatur ke 128, dan aktifkan timer overflow.

Sekarang Anda akan mendapatkan interupsi TIMER2_OVF pada tingkat yang sangat stabil sekali per detik. Anda hanya perlu memajukan tampilan jam satu detik di ISR. Di sela-sela interupsi, Anda dapat menempatkan MCU dalam kondisi tidur sangat nyenyak (mode hemat daya tidur: tidak ada yang berjalan kecuali Timer / Penghitung 2) dan berjalan selama bertahun-tahun pada beberapa sel AA. Kecuali jika tampilannya haus daya, jelas.

Saya melakukan ini untuk membangun jam dinding satu tangan 24 jam saya . Tautan ini sekarang menunjuk ke terjemahan bahasa Inggris dari dokumentasi asli dalam bahasa Prancis.

Kalibrasi kuarsa

Jika Anda tidak mengkalibrasi kuarsa Anda, Anda dapat mengharapkan pergeseran yang signifikan, biasanya beberapa detik per minggu . Kecepatan drift tergantung pada kapasitansi liar dari jejak yang menghubungkan kristal ke MCU. Pada prinsipnya, itu bisa dihilangkan dengan menambahkan beberapa kapasitansi ekstra yang disetel dengan halus. Perlu dicatat bahwa Anda akan memiliki masalah drift yang sama dengan RTC.

Jika Anda puas dengan akurasi semacam ini, maka hiduplah dengan itu dan bahagia. Namun, jika Anda peduli untuk mengukur arus, Anda akan melihat bahwa itu sangat stabil. Anda kemudian dapat dengan mudah mengkompensasinya dalam perangkat lunak, dan mencapai akurasi beberapa detik per tahun .

Algoritma untuk mengoreksi drift sangat sederhana. Dari drift yang terukur, Anda mengetahui penundaan tepat antara interupsi, yang harus sangat dekat dengan 10 9  nanodetik, kemudian:

#define ONE_SECOND    1000000000  // in nanoseconds
#define ONE_INTERRUPT  999993482  // for example

ISR(TIMER2_OVF_vect)
{
    static uint32_t unaccounted_time;

    unaccounted_time += ONE_INTERRUPT;
    while (unaccounted_time >= ONE_SECOND) {
        advance_display_by_one_second();
        unaccounted_time -= ONE_SECOND;
    }
}

Dalam contoh di atas, kuarsa sedikit terlalu cepat, dan perangkat lunak mengkompensasi dengan "menghilangkan" tanda centang setiap beberapa hari. Jika kuarsa terlalu lambat, kode yang sama akan mencentang dua kali setiap beberapa hari.

Kalibrasi semacam ini juga dapat dilakukan untuk RTC, tetapi akan jauh lebih kompleks karena RTC melaporkan waktu dalam bentuk rusak yang tidak secara alami cocok untuk operasi aritmatika.

Edgar Bonet
sumber
Wow itu desain yang sangat apik! Saya sangat suka bagaimana Anda telah memasang foto yang cukup untuk memperjelas desain, bahkan bagi kami orang Amerika monoglot yang bodoh :) Saya sangat suka melihat dokumentasi proyek eksplisit seperti ini!
John Walthour
2
@ JohnWalthour: Terima kasih! Sekarang Anda mendorong saya untuk menulis terjemahan. :-)
Edgar Bonet
2
@JohnWalthour: Selesai! Tautan sekarang menunjuk ke terjemahan bahasa Inggris.
Edgar Bonet
Untuk lebih jelasnya, ketika Anda mengatakan, "ATmega chip memiliki semua perangkat keras yang dibutuhkan", itu tidak sepenuhnya benar ketika Anda harus mendapatkan kristal baru. Saya pikir solusi Anda licin dan tidak di atas mengganti kristal tapi saya agak bingung ketika Anda mengatakan saya tidak membutuhkan perangkat keras dan kemudian berbalik dan berkata saya perlu mengganti perangkat keras.
Kelly S. French
@ KellyS.French: Kalimat saya adalah “chip ATmega memiliki semua perangkat keras yang diperlukan untuk melakukan tugas-tugas RTC itu sendiri” (penekanan ditambahkan). Tetapi kemudian penting untuk memperhatikan bahwa sebagian besar RTC, termasuk DS1307 di mana-mana, membutuhkan kristal eksternal untuk beroperasi. ATmega tidak berbeda: ATmega memiliki semua yang diperlukan untuk mengganti RTC itu sendiri , tetapi tidak untuk mengganti kristal yang harus Anda hubungkan ke RTC. Harap dicatat bahwa RTC modul adalah lebih dari sekedar RTC, seperti halnya termasuk kristal.
Edgar Bonet
6

Resonator yang Anda tentukan memiliki stabilitas 0,3%, di mana osilator kristal atau kristal (seperti yang disebutkan oleh Ricardo) adalah 50ppm. Banyak kali lebih stabil. Belum lagi penyimpangan suhu resonator mengerikan. Pemanasan oleh sinar matahari akan mengubahnya. Oleh karena itu resonator tidak boleh digunakan untuk menjaga waktu dalam jangka waktu lama.

Oleh karena itu baik menggunakan osilator kristal atau kristal akan mendapatkan apa yang Anda inginkan. Baik menggunakannya di ATmega dan mengatur sekering masing-masing atau kita yang terhubung ke RTC.

mpflaga
sumber
Di mana 50ppm adalah 0,005% stabilitas?
Matius G.
Saya menggeneralisasi spesifikasi itu, untuk menjaga agar jawaban tetap singkat. Catat stabilitas selain Res. memiliki toleransi yang jauh lebih besar dan bisa sangat tidak aktif. Seperti yang dialami John W. "bagian yang tepat untuk pekerjaan yang tepat"
mpflaga
Oh, saya hanya ingin tahu tentang terminologi @mpflaga ... baru bagi saya.
Matius G.
4

Jika Anda tidak ingin menggunakan perangkat keras tambahan seperti Jam Waktu Nyata (mis. DSDS1307), Anda dapat secara signifikan meningkatkan akurasi waktu dengan menonaktifkan semua gangguan yang tidak digunakan. Secara default, sketsa Arduino hadir dengan berbagai rutinitas interupsi yang diaktifkan dan seringkali sketsa tersebut tidak digunakan untuk sketsa Anda sebenarnya. Cara tercepat untuk mengetahui apakah Anda dapat melakukannya tanpanya untuk mencoba dan menonaktifkannya dengan mengeluarkannoInterrupts();

jippie
sumber
3
−1 (walaupun ini layak −4) karena: 1. Kecuali Anda benar-benar membutuhkannya, semua interupsi dinonaktifkan secara default, dengan pengecualian tunggal TIMER0_OVF, yang diperlukan untuk menjaga waktu. 2. Ketepatan waktu Arduino dibatasi terutama oleh kualitas resonator. 3. Interupsi tidak memengaruhi keakuratan millis()kecuali jika Anda berhasil menghabiskan lebih dari satu milidetik sekaligus untuk melayaninya, dalam hal ini Anda memiliki masalah lain ... 4. Menonaktifkan interupsi dengan noInterrupts()akan mencegah millis()dari menjaga waktu sama sekali!
Edgar Bonet
2

Saya mengerti banyak semangat dengan Arduino yang hemat dan kadang-kadang dengan susah payah melewati masalah. Saya menggunakan Arduino (dan sekarang chipKIT, karena punya 10x RAM dan 10x kecepatan clock) untuk tempat kerja saya dan saya perlu "fungsi periferal" untuk mempercepat dan bekerja secepat mungkin.

Saya menggunakan jam waktu nyata sparkfun di salah satu proyek saya dan saya sangat senang dengan itu. Mereka juga memiliki varian "Mati di" .

Chris K
sumber