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

Тема в разделе "Схемотехника, компоненты, модули", создана пользователем 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 Гик

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