Часы реального времени убегают нереально...

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем KoKaiN, 28 янв 2019.

  1. KoKaiN

    KoKaiN Нерд

    Привет!
    Сталкивался кто-либо с необходимостью корректировки показаний часов реального времени?
    Есть Часы реального времени от Амперки (эти - http://wiki.amperka.ru/продукты:troyka-rtc)
    Прикручены к Уно (этой - http://wiki.amperka.ru/продукты:arduino-uno)
    Есть два проекта, использующих эти платы и выводящих время. В обоих проектах часы "убегают" вперед. Там где время критично (часы) засекал скорость - примерно на 1 секунду в 7 часов.
    Железки разные, поэтому "убегание" вряд ли связано с кодом, но всякое бывает.
    Инициализирую часы отдельным "голым" скетчем, чтобы меньше тратилось времени за загрузку.
    В итоге, чтобы побороть убегание приходится перезаписывать время, отнимая по секунде каждые 7 часов.
    В чем проблема? Некачественные кристаллы в плате, в ДНК хромосом не хватает или какой другой косяк?


    Код (C++):
    #include <TroykaDHT.h>
    #include <TroykaRTC.h>
    #include <QuadDisplay2.h>

    RTC clock;
    volatile unsigned long previousMillisTime = 0;
    volatile unsigned long previousMillisTemp = 0;
    volatile unsigned long millisTimeShift = 0;

    float arrTemp[6], arrHum[6];

    QuadDisplay qd_c(11, 9, 10);
    QuadDisplay qd_t(8, 6, 7);
    QuadDisplay qd_h(5, 0, 1);

    int interval_Time = 200;
    int interval_Temp = 2000;

    DHT dht(12, DHT21);

    void setup() {
      clock.begin();
      qd_c.begin();
      qd_t.begin();
      qd_h.begin();
      dht.begin();
      dht.read();
      if (dht.getState() == DHT_OK) {
        for (int i = 0; i < 6; i++) {
          arrTemp[i] = dht.getTemperatureC();
          arrHum[i] = dht.getHumidity();
        }
      } else {
        for (int i = 0; i < 6; i++) {
          arrTemp[i] = 20.0;
          arrHum[i] = 20.0;
        }

      }
    }

    void loop() {
      timer_Time();
      timer_Shift();
      timer_Temp();
    }

    void timer_Time()
    {
      unsigned long currentMillis = millis();
      if (abs(currentMillis - previousMillisTime) > interval_Time ) {
        previousMillisTime = currentMillis;
        clock.read();
        qd_c.displayScore(clock.getHour(), clock.getMinute(), true);
      }
    }

    void timer_Shift()
    {
      unsigned long currentMillis = millis();
      if (abs(currentMillis - millisTimeShift) > 10080000 ) {
        clock.read();
        int currSec = clock.getSecond();
        if (currSec > 10)
        {
          clock.setSecond(currSec - 1);
          millisTimeShift = currentMillis;
        }
      }
    }

    void timer_Temp()
    {
      unsigned long currentMillis = millis();
      float avgTemp = 0;
      float avgHum = 0;
      if (abs(currentMillis - previousMillisTemp) > interval_Temp ) {
        previousMillisTemp = currentMillis;
        dht.read();
        if (dht.getState() == DHT_OK) {
          for (int i = 0; i < 5; i++) {
            arrTemp[i] = arrTemp[i + 1];
            arrHum[i] = arrHum[i + 1];
            avgTemp += arrTemp[i] / 6;
            avgHum += arrHum[i] / 6;
          }
          arrTemp[5] = dht.getTemperatureC();
          arrHum[5] = dht.getHumidity();
          avgTemp += arrTemp[5] / 6;
          avgHum += arrHum[5] / 6;
        }
        //    qd_t.displayTemperatureC(int(avgTemp));
        qd_t.displayTemperatureC(int(avgTemp - 3));
        qd_h.displayHumidity(int(avgHum));
      }
    }

     
     
  2. Пушной звер

    Пушной звер Оракул

    это нормально
     
  3. parovoZZ

    parovoZZ Гуру

    да. Качественный часовой кварц стоит столько же, сколько десять таких часов.
     
  4. KoKaiN

    KoKaiN Нерд

    Спасибо, вернули меня на землю. +\- 20 сек в день месяц (!) оказывается норма.
    Буду программно корректировать
     
    Последнее редактирование: 28 янв 2019
  5. parovoZZ

    parovoZZ Гуру

    это называется брак.
     
  6. KoKaiN

    KoKaiN Нерд

    Пардон, единицы измерения попутал, в месяц конечно (http://forum.watch.ru/showthread.php?t=35184)
     
  7. Пушной звер

    Пушной звер Оракул

    берем даташит, открываем на 7стр, смотрим как нарисован кварц и от чего зависит точность хода, потом смотрим на плату часов от амперки.

    а вообще за место 1307 за 300, можно было взять 3231 за доллар
     
    KoKaiN нравится это.
  8. KoKaiN

    KoKaiN Нерд

    А ведь верно, скорее всего от перегрева может еще время ползти.
    У меня ощутимо греется до +30+40
    И на 3231 температурный датчик для корректировки стоит, а на 1307 я такого не вижу.
     
  9. Airbus

    Airbus Радиохулиган

    Коррекция по ntp не?
     
  10. KoKaiN

    KoKaiN Нерд

    Не, еще сетевой модуль в коробку не влезет))
    Буду обходиться статичной корректировкой
    Но когда дорасту до "умного дома" - поставлю это в приоритет
     
  11. ImrDuke

    ImrDuke Гик

    Был модуль DS1302 - раз в час показания отставали на секунду.
    Поставил DS3231 - больше года показания не корректировал.
     
    KoKaiN нравится это.
  12. Аналогично, только если не часто опрашивать.
    Сначала постоянно его опрашивал, т.е. получил время/температуру и тут же опять опрашиваю, и часы стали заметно отставать. Стал опрашивать раз в минуту, уже забыл когда время подводил.
     
    KoKaiN нравится это.
  13. Vovka

    Vovka Гик

    У меня есть китайский модуль на DS1307, так убегает вперед за два дня аж на 4 минуты!!! Опрашиваю раз в сутки или после сброса. Его что, долбить каждую минуту, чтоб не спешил? :D:D:D
     
  14. KoKaiN

    KoKaiN Нерд

    Каждые 12 минут отнимать у него по секунде ;).
    Похоже индивидуальности конкретного кристалла и условий его эксплуатации можно лечить только программно.
    Я подобной подстройкой дошел до точности 1 секунда в сутки. При следующей прошивке еще и эту секунду поправлю
     
  15. Vovka

    Vovka Гик

    При этом придется корректировать и саму DS1307 или, как вариант, добавить резервное питание для МК - тогда DS1307 нафиг не нужна ;)
     
  16. KoKaiN

    KoKaiN Нерд

    Не очень понял ответ...
    Попробую подробнее:
    считываем время тогда когда надо, но раз в 12 минут делаем следующую операцию.
    Считываем время, затем записываем время назад за вычетом секунды.
    Теперь в 1307 сидит точное время и поддерживается батарейкой.
    Единственный минус - при длительном отсутствии питания МК не делает поправку.
    Я в своем коде такой фокус проворачиваю (см 1-е письмо)
    Код (C++):
    void timer_Shift()
    {
      unsigned long currentMillis = millis();
      if (abs(currentMillis - millisTimeShift) > 10080000 ) {
        clock.read();
        int currSec = clock.getSecond();
        if (currSec > 10)
        {
          clock.setSecond(currSec - 1);
          millisTimeShift = currentMillis;
        }
      }
    }
     
  17. ImrDuke

    ImrDuke Гик

    Проще выкинуть и купить нормальный.
     
    Daniil, parovoZZ и DetSimen нравится это.
  18. DetSimen

    DetSimen Гуру

    +100500
     
  19. KoKaiN

    KoKaiN Нерд

    И передать привет Амперке...
     
  20. ImrDuke

    ImrDuke Гик

    Что я с тем модулем только ни делал, и экранировал, и заземлял, фольгу подкладывал, кварц из материнки перепаивал...