Doğru zamanı nasıl alabilirim?


16

Bir Arduino kullanarak bir saat yaptım, ama zaman kayıyor gibi görünüyor. Rollover sorununun farkındayım ; saat, bir hafta boyunca yaklaşık 15 dakika sürükleniyor gibi görünüyor.

Ben Digi-key bu rezonatör ile özel bir PCB kullanıyorum . Kod, her döngünün başında millis () işlevini okur ve bu değerden çalışır.

Sorum şu: Geçilebilir bir masa saati yapmak için yeterince doğru bir Arduino ile zamanı nasıl ölçebilirim?


3
Milisaniye işlevi, çalışması için birkaç saat döngüsü gerektiren bir kesmeden alınan verilerle sağlanır. Bu, her bir kene için küçük bir süre ekler.
TheDoctor

3
@TheDoctor: Bu yanlış. Kesme, süren donanım zamanlayıcısını yavaşlatmaz millis().
Edgar Bonet

Yanıtlar:


15

Not: Cevabım kabul edilmiş ve daha yüksek bir oy puanına sahip olmasına rağmen, Edgar Bonet'in Arduino'nuzu bir RTC olmadan nasıl zaman tutacağına dair harika cevabı okuduğunuzdan emin olun .

DS1307 Gerçek Zamanlı Saat'i kullanmakta oldukça başarılı oldum. İşte veri sayfasına bir bağlantı .

Aşağıda bazı özellikleri verilmiştir:

  • Arduino ile iletişim için IC arayüzünü kullanarak doğru kütüphaneleri (Net'te mevcuttur) kullanarak programlamayı kolaylaştırır.

  • Arduino'ya SCL ve SDA pinleri (sırasıyla analog A4 ve A5) üzerinden bağlanır, böylece sadece 2 pin kullanılır.

  • Çalışması için çok az harici bileşen gerektirir.

  • Madeni para büyüklüğündeki bir pile bağlanabilir, böylece Arduino kapalıyken bile zaman kalır. Düşük güç modunda, madeni para büyüklüğündeki pil yıllarca dayanır.

  • Çok az sürükleniyor (benim durumumda sadece haftada birkaç saniye sürükleniyor).

  • Çok pahalı değil.

Bir RTC kullanmayı düşünmüyorsanız varsa yaygın bir için Arduino için saat sağlamak için kullanılır kristali yerine kristal osilatör modülü gibi Farnel dan bu bir veya bu diğeri . Aşağıdaki resimlerdeki gibi 4 pinli paketler halinde gelirler. Arduino'nuz için çok daha hassas bir saat üretecekler.

Kristal osilatör görüntüsü Kristal osilatör görüntüsü Kristal osilatör görüntüsü

Bahsedilen her iki modül de 50 ppm toleransa sahiptir ve 5V'de çalışır.

Yine, açık olmak gerekirse, bu kristal osilatör modülleri, aşağıdaki gibi normal 2 pimli kristal ile karıştırılmamalıdır . Bunlar, örneğin MCU'lar için harici saatlerin devresinin bir parçasıdır.

Kristal osilatör


DS1302 yeterince iyi mi yoksa DS1307'ye mi geçmeliyim?
Kelly

14

Saat oluşturmak için bir RTC'ye ihtiyacınız yoktur: ATmega çipi, RTC'nin görevlerini yerine getirmek için gereken tüm donanıma sahiptir. İşte böyle:

  1. 32768 Hz saat kristali edinin: ya satın alın ya da eski bir saati sökün. Özellikle zaman tutmak için tasarlanan bu kristaller, son derece küçük bir sıcaklık sapmasına sahiptir. Bir RTC yongası kullanmak isterseniz bunlardan birine ihtiyacınız olacaktır.

  2. ATmega'nızın sigortalarını 8 MHz RC osilatörünü çalıştıracak şekilde yapılandırın. Bu, millis()işlevinizi korkunç bir şekilde yanlış hale getirir ve ayrıca XTAL1 ve XTAL2 pinlerini serbest bırakır.

  3. Saat kristalini TOSC1 ve TOSC2 pimlerine bağlayın. Bunlar XTAL1 ve XTAL2 ile aynı pimlerdir (328P'de 9 ve 10). Farklı isimler, farklı işlevler anlamına gelir.

  4. Zamanlayıcı / Sayaç 2'yi eşzamansız çalışma, normal sayma modu, ön ölçekleyici 128 olarak ayarlanmış olarak yapılandırın ve zamanlayıcı taşma kesintisini etkinleştirin.

Şimdi saniyede bir kez çok sabit bir oranda bir TIMER2_OVF kesmesi alacaksınız. ISR'de saat ekranını yalnızca bir saniye ilerletmeniz gerekir. Kesintiler arasında MCU'yu çok derin uykuya alabilirsiniz (güç tasarrufu uyku modu: Zamanlayıcı / Sayaç 2'den başka hiçbir şey çalışmaz) ve birkaç AA hücresinde yıllarca çalışabilirsiniz. Tabii ki ekran güç tüketmiyorsa.

Tam da 24 saat tek elle duvar saatimi yapmak için yaptım . Bu bağlantı şimdi orijinal belgelerin Fransızca çevirisini göstermektedir.

Kuvars kalibrasyonu

Kuvarsınızı kalibre etmiyorsanız, genellikle haftada birkaç saniye olmak üzere önemli bir sapma bekleyebilirsiniz . Kayma hızı, kristali MCU'ya bağlayan izlerin başıboş kapasitansına bağlıdır. Prensip olarak, bazı ekstra, ince ayarlanmış kapasitans eklenerek çıkarılabilir. Bir RTC ile aynı sürüklenme problemine sahip olacağınızı belirtmek gerekir .

Bu tür bir doğruluktan memnunsanız, onunla yaşayın ve mutlu olun. Bununla birlikte, sapmayı ölçmeye özen gösterirseniz, bunun çok kararlı olduğunu fark edeceksiniz. Daha sonra yazılımda kolayca telafi edebilir ve yılda birkaç saniyelik bir doğruluk elde edebilirsiniz .

Kaymanın düzeltilmesi için algoritma çok basittir. Ölçülen sapmadan, 10 9  nanosaniyeye çok yakın olması gereken kesmeler arasındaki kesin gecikmeyi anlıyorsunuz , o zaman:

#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;
    }
}

Yukarıdaki örnekte, kuvars biraz fazla hızlıdır ve yazılım her birkaç günde bir kene "eksik" olarak telafi edilir. Kuvars çok yavaş olsaydı, aynı kod birkaç günde bir çift işaretli olurdu.

Bu tür bir kalibrasyon bir RTC için de yapılabilir, ancak RTC zamanı doğal olarak aritmetik işlemlere borç vermeyen bölünmüş bir formda raporladığı için daha karmaşık olacaktır.


Vay be bu gerçekten kaygan bir tasarım! Aptal monoglot Amerikalılar için bile tasarımı netleştirmek için yeterince fotoğraf koyduğunuzdan gerçekten hoşlandım :) Böyle açık proje belgelerini görmeyi gerçekten seviyorum!
John Walthour

2
@JohnWalthour: Teşekkürler! Şimdi beni çeviri yazmaya teşvik ediyorsun. :-)
Edgar Bonet

2
@JohnWalthour: Bitti! Bağlantı şimdi İngilizce çeviriye işaret ediyor.
Edgar Bonet

Açıkça söylemek gerekirse, "ATmega yongası gereken tüm donanıma sahiptir" dediğinizde, yeni bir kristal elde etmeniz gerektiğinde bu tamamen doğru değildir. Bence çözümünüz kaygan ve kristali değiştirmenin üstünde değilim ama donanıma ihtiyacım olmadığını söylediğimde biraz kafam karıştı ve sonra dönüp bir donanım parçasını değiştirmem gerektiğini söylüyorum.
Kelly

@ KellyS.French: Cümlem “ATmega çipi RTC'nin görevlerini yerine getirmek için gereken tüm donanıma sahip ” idi (vurgu eklendi). Ancak, her yerde bulunan DS1307 de dahil olmak üzere çoğu RTC'nin çalışması için harici bir kristale ihtiyaç duyduğunu fark etmek önemlidir. ATmega farklı değil: RTC'nin kendisini değiştirmek için gereken her şeye sahip , ancak yine de RTC'ye bağlamanız gereken kristali değiştirmek için değil. Lütfen not bir RTC o modül olup daha adil daha bir RTC, bu kristal içerir yaptığı gibi.
Edgar Bonet

6

Belirttiğiniz rezonatör, kristal veya kristal osilatörün (Ricardo tarafından belirtildiği gibi) 50 ppm olduğu% 0,3 stabiliteye sahiptir. Birçok kez daha kararlı. Rezonatörün sıcaklık kaymasından bile bahsetmiyorum bile korkunç. Güneş ışığı ile ısıtma bunu değiştirecektir. Bu nedenle, bir rezonatör uzun süreler boyunca zaman tutmak için kullanılmamalıdır.

Böylece bir kristal veya kristal osilatör kullanmak istediğinizi elde eder. Ya ATmega üzerinde kullanın ve sırasıyla sigortaları ayarlayın ya da bir RTC'ye bağlı bir sigorta kullanın.


50ppm% 0.005 kararlılık nerede?
Matthew G.12

Cevabı kısa tutmak için bu spesifikasyon üzerinde genelleme yapıyorum. Kararlılığı bir kenara not edin Res. çok daha büyük bir toleransa sahip ve oldukça kapalı olabilir. John W deneyimlediği gibi. "doğru iş için doğru bölüm"
mpflaga

Oh, sadece @mpflaga terminolojisini merak ediyordum ... benim için yeni.
Matthew G.12

4

Gerçek Zaman Saati gibi ekstra donanım kullanmak istemiyorsanız (örn. DSDS1307), kullanılmayan tüm kesintileri devre dışı bırakarak zamanlama doğruluğunu önemli ölçüde artırabilirsiniz. Varsayılan olarak Arduino çizimleri çeşitli kesme rutinleri etkin olarak gelir ve genellikle eskiziniz için kullanılmazlar. Vermeden bunları yapıp yapamayacağınızı öğrenmenin en hızlı yolunoInterrupts();


3
−1 (bu −4'ü hak etmesine rağmen) çünkü: 1. Bunlara gerçekten ihtiyacınız olmadığı sürece, yalnızca zaman tutma için gerekli olan TIMER0_OVF hariç olmak üzere tüm kesintiler varsayılan olarak devre dışıdır. 2. Arduinos'un zamanlama doğruluğu esas olarak rezonatörün kalitesi ile sınırlıdır. 3. Kesintiler millis(), bir seferde bir milisaniyeden fazla harcama yapmayı başaramazsanız, bu durumda başka sorunlarınız olduğu sürece kesinliğini etkilemez ... 4. Kesintileri devre dışı bırakmak , hiç zaman kaybetmemenizi noInterrupts()önler millis()!
Edgar Bonet

2

Anladım ki Arduino ile olan ruhun çoğu tutumlu ve zaman zaman bir sorunla doludur. Arduino'yu (ve şimdi chipKIT'i kullanıyorum, çünkü işyerim için 10x RAM ve 10x saat hızı var) ve hıza ulaşmak ve mümkün olduğunca çabuk çalışmak için "çevresel işlevlere" ihtiyacım var.

Sparkfun gerçek zamanlı saatini projelerimden birinde kullanıyorum ve bundan çok memnunum. Ayrıca "Dead on" varyantı var .

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.