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?
millis()
.Jawaban:
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.
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.
sumber
Anda tidak memerlukan RTC untuk membangun jam: chip ATmega memiliki semua perangkat keras yang diperlukan untuk melakukan tugas RTC itu sendiri. Begini caranya:
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.
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.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.
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:
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.
sumber
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.
sumber
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 mengeluarkan
noInterrupts();
sumber
millis()
kecuali jika Anda berhasil menghabiskan lebih dari satu milidetik sekaligus untuk melayaninya, dalam hal ini Anda memiliki masalah lain ... 4. Menonaktifkan interupsi dengannoInterrupts()
akan mencegahmillis()
dari menjaga waktu sama sekali!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" .
sumber