DS1302 часы убегают вперед

kristow
kristow аватар
Offline
Зарегистрирован: 08.08.2013

Приобрел плату "часы реального времени" на DS1302.

Настроил время на них, далее они сами в автономе лежали месяц. Сейчас подключил и вижу, что часы реального времени убежали вперед на 5 мин... А это значит что за год они убегут на час. А это очень много...

Есть возможность без подключения к ПК корректировать время? допустим через интернет? или еще как-то?

StrangerM
Offline
Зарегистрирован: 02.11.2013

Такая тема уже была. Почитайте. Моя тз (проверенная опытом) кондер с хорошим тке // кварцу. Я поставил 3пф с 0 тке убегать стали меньше, надо будет потом поставить 10.

ZagZag
Offline
Зарегистрирован: 08.05.2014

Искажение может быть из-за неправильного расположения часового кварца. Под ним желательно расположить заземление, расположить кварц как можно ближе к контроллеру. Перепады температуры окружающей среды тоже могут влиять.

Простой способ - ввести корректирующую поправку. Минусуй 5 минут раз в месяц или почаще (например 10 секунд в день)

StrangerM
Offline
Зарегистрирован: 02.11.2013

А еще лучше прогу написть коррекции с учетом температуры. :-)

ZagZag
Offline
Зарегистрирован: 08.05.2014

Или подключиться к эфиру, и синхронизировать время по радиосигналу

arduino DCF77 (на русском)

StrangerM
Offline
Зарегистрирован: 02.11.2013

Большие у меня сомнения, что не проживая на территории ФРГ можно "подключиться к эфиру" да еще на ~70 кГц. :-)

Как выход - "подключиться к космосу", т.е. использовать сигнал GPS.  Это лучше делать с использованием выносной антенны.

ZagZag
Offline
Зарегистрирован: 08.05.2014

GPS - дорогой вариант. А что, у нас не вещают сигнал точного времени?

Samodelkin
Offline
Зарегистрирован: 07.06.2012

Dcf77, GPS, не правильное расположение кварца, плохие конднсаторы, коррекция времени, ну вы мазохисты, еще можно написать писмо в Роскосмос, чтобы с МКС слали точное время для ардуины )) А можно проще поставить DS3231 - минимум обвязки, управление микрой точно такое же как и ds1307 и ей же подобной, т.е. даже скетч не понадобится переписывать. Уже тикают часики почти 6 месяцов, секунда в секунду.

StrangerM
Offline
Зарегистрирован: 02.11.2013

Может и вещают. Только как этот сигнал ловить. А GPS  15 баксов. Дорого? А тогда сколько немецкая фитюлька стоит?

art100
Offline
Зарегистрирован: 09.03.2014

Samodelkin пишет:

Dcf77, GPS, не правильное расположение кварца, плохие конднсаторы, коррекция времени, ну вы мазохисты, еще можно написать писмо в Роскосмос, чтобы с МКС слали точное время для ардуины )) А можно проще поставить DS3231 - минимум обвязки, управление микрой точно такое же как и ds1307 и ей же подобной, т.е. даже скетч не понадобится переписывать. Уже тикают часики почти 6 месяцов, секунда в секунду.

и библиотека какая-то рабочая есть?

смотрю там память еще какая-то

а зачем там память

StrangerM
Offline
Зарегистрирован: 02.11.2013

Я уже смотрел на такую штуку, и есть библиотека у Ады.(вроде)

kisoft
kisoft аватар
Offline
Зарегистрирован: 13.11.2012

Память там для беспамятных, короче под что угодно можно использовать. Я такой блок уже получил, только до конца не добил еще. Памяти там, кстати, немало. Библиотек тоже немало, я какую то выбрал, не помню уже. Насколько помню все эти часы одинаковые по интерфейсу (DS1307. DS3231).

 

StrangerM
Offline
Зарегистрирован: 02.11.2013

Уговорили - купил. Давно хотел, да вроде были дороже.

ZagZag
Offline
Зарегистрирован: 08.05.2014

Не знал про такие часы. Вполне годное решение. Только цена в 8$ - перебор. На ибее за 2$ продается.

http://www.ebay.com/itm/DS3231-AT24C32-IIC-module-precision-clock-module-/281163978761?pt=LH_DefaultDomain_0&hash=item4176add809

StrangerM
Offline
Зарегистрирован: 02.11.2013

Так 8 за 5. =1.6

melvladimir
Offline
Зарегистрирован: 08.03.2013

То 8,64$ за 5 штук :) сейчас думаю купить или нет, т.к. 5 микроконтроллеров лежит, ждут своей очереди :)

Пока сделаю еженедельную компенсацию в коде.

denis64
Offline
Зарегистрирован: 07.10.2013

kristow пишет:

Приобрел плату "часы реального времени" на DS1302.

Настроил время на них, далее они сами в автономе лежали месяц. Сейчас подключил и вижу, что часы реального времени убежали вперед на 5 мин... А это значит что за год они убегут на час. А это очень много...

В результате полугодового эксперимента ваши выводы полностью подтвердились коллега. За 185 дней набежало 28,5 минут

Коррекция составляет 9 секунд в день..

trembo
trembo аватар
Offline
Зарегистрирован: 08.04.2011

Кварцы с материнок поточнее будут. Попробуйте на него  поменять, многие жалуются на эти часики.
Или берите готовые на  DS3231

dimax
dimax аватар
Offline
Зарегистрирован: 25.12.2013

StrangerM пишет:

Большие у меня сомнения, что не проживая на территории ФРГ можно "подключиться к эфиру" да еще на ~70 кГц. :-)

В Москве ловит отлично, у меня уже несколько лет часы так синхронизируются... никаких забот по подстройке.

Клапауций 999
Offline
Зарегистрирован: 06.06.2015

trembo пишет:

Кварцы с материнок поточнее будут. Попробуйте на него  поменять, многие жалуются на эти часики.
Или берите готовые на  DS3231

я со старого японского факса снял.

Andrey_Y_Ostanovsky
Offline
Зарегистрирован: 03.12.2012

StrangerM пишет:
Может и вещают. Только как этот сигнал ловить.

В Петербурге ( в европейской части России) - ловит, дальше - как повезет.

maksmkv
Offline
Зарегистрирован: 07.04.2013

denis64 пишет:

kristow пишет:

Приобрел плату "часы реального времени" на DS1302.

Настроил время на них, далее они сами в автономе лежали месяц. Сейчас подключил и вижу, что часы реального времени убежали вперед на 5 мин... А это значит что за год они убегут на час. А это очень много...

В результате полугодового эксперимента ваши выводы полностью подтвердились коллега. За 185 дней набежало 28,5 минут

Коррекция составляет 9 секунд в день..

 

А ваш код с коррекцией можно сюда  запостить??? Такая же ерунда  с часами.

denis64
Offline
Зарегистрирован: 07.10.2013

Кода нет. Просто плата с батарейкой провалялась 185 дней. Недавно руки дошли.

Каждые 9340035 миллисекунд  делайте setTime на секунду меньше от имеющегося времени. ИМХО так.

RainMan
Offline
Зарегистрирован: 21.06.2011

у меня DS3231 вперед убегают очень сильно. Причем нету зависимости от колебания температуры. Каждый раз разное время убегания. Как ни мучался скорректировать не удалось... 

maksmkv
Offline
Зарегистрирован: 07.04.2013

А я все  с DS1307 мучаюсь - как раз уезжал на выходные, выключал их из розетки -включил , остали где-то на 4 часа ((( Как же работают часы во всяких метеостанциях и прочих устройствах, что их не надо подстраивать???

RainMan
Offline
Зарегистрирован: 21.06.2011

maksmkv пишет:

А я все  с DS1307 мучаюсь - как раз уезжал на выходные, выключал их из розетки -включил , остали где-то на 4 часа ((( Как же работают часы во всяких метеостанциях и прочих устройствах, что их не надо подстраивать???

перед тем как там все заработает предшествуют танцы с бубном в виде замены кварцев, переноса его ближе к процессору и т.д. У меня  DS1307 - 3шт разных производителей. Ни одна сборка не работает удовлетворительно.

denis64
Offline
Зарегистрирован: 07.10.2013

китайская сборка DS1302 работает нормально ничего не подпаивая, только программно корректировать нужно

т.е. величина погрешности стабильная

denis64
Offline
Зарегистрирован: 07.10.2013

Есть проблема. Нужна помощь.

Я написал код часов для четырехразрядного индикатора на сдвиговых регистрах и DS1302 , в нем присутствует корректировка  для спешащих часов. Код  работает сносно пока часы работают и на них есть питание.

.

#include <DS1302.h>
// Init the DS1302
DS1302 rtc(7, 6, 5);
//integers for holding the various time values.
int hours = 0;
int minutes = 0;
int dates = 0;
int months = 0;
int mode = 0;
boolean time_correction = false;
String str0;
unsigned long time;
unsigned long god;
unsigned long mes;
unsigned long day;
unsigned long hour;
unsigned long minut;
unsigned long sek;

unsigned long timetemp1;
unsigned long timetemp2;
const int menuPin = 8;
int buttonState = 0;         // variable for reading the pushbutton status
const int latchPin = 3;
const int clockPin = 4;
const int dataPin = 2;
int number1;
byte number2;
byte number3;
byte number4;
const byte digit[24] =      //seven segment digits in bits
{
  B11000000, //0
  B11111001, //1
  B10100100, //2
  B10110000, //3
  B10011001, //4

  B10010010, //5
  B10000010, //6
  B11111000, //7
  B10000000, //8
  B10010000, //9

  B01000000, //10
  B01111001, //11
  B00100100, //12
  B00110000, //13
  B00011001, //14

  B00010010, //15
  B00000010, //16
  B01111000, //17
  B00000000, //18
  B00010000, //19

  B10111111, //20   -
  B10011100, //21   °
  B11111111, //22   null

};


void setup() {
  Serial.begin(9600);
  //устанавливаем режим OUTPUT
  pinMode(latchPin, OUTPUT);
  pinMode(dataPin, OUTPUT);
  pinMode(clockPin, OUTPUT);
  pinMode(menuPin, INPUT);

  digitalWrite(menuPin, HIGH);
  // Set the clock to run-mode, and disable the write protection
  //rtc.halt(false);
  //rtc.writeProtect(false);

  //Time t(2015, 6, 30, 22, 41, 0, Time::kSunday);
  //rtc.time(t);
}

void loop() {
  Time t = rtc.time();
  buttonState = digitalRead(menuPin);
  if (buttonState == LOW){


    ++mode;
    delay (100);
    if (mode > 3)  mode=0;

    Serial.println("Button as down");
    Serial.println(mode);
  }


  switch (mode) {
  case 0:
    //выполняется, когда mode равно 0 - отображение времени на индикаторе

    str0  = String(t.hr) +  String(t.min);
    // следующие два цикла проверки - блок коррекции времени ежедневно утром притормаживающий часы на 9 секунд
    if (t.hr == 5 && t.min==55 && t.sec==9 && time_correction == false){
      god=t.yr;
      mes=t.mon;
      day=t.date;
      hour=t.hr;
      minut=t.min;
      sek=t.sec;
      hour=5;
      minut=55;
      sek=t.sec;
      Time t(god, mes, day , hour, minut, 0, Time::kSunday);
      time_correction == true;
    }
    if (t.hr == 5 && t.min==56){
      time_correction == false;
    }


    timetemp1=t.min;
    timetemp2=t.hr;
    // следующие два цикла проверки - блок коррекции "пустого" разряда когда значение минут или часов занимает только один разряд например "1 час 5 минут"
    // происходит "дорисовка" дополнительных нулей
    if (timetemp2 < 10){
      str0  = String("A")+String(t.hr) +String(t.min);
    }

    if (timetemp1 < 10)
    {
      str0  = String(t.hr) +  String(0)+String(t.min);
      // Serial.println(timetemp1);

      if (timetemp2 < 10){
        str0  = String("A")+String(t.hr) +  String(0)+String(t.min);
      }
    }



    break;
  case 1:
    //выполняется когда mode равно 1 отображение даты


    str0  = String(t.date) +  String(t.mon);
    // следующие два цикла проверки - блок коррекции времени ежедневно утром притормаживающий часы на 9 секунд



    timetemp1=t.mon;
    timetemp2=t.date;
    // следующие два цикла проверки - блок коррекции "пустого" разряда когда значение даты или месяца занимает только один разряд например "1.02"
    // происходит "дорисовка" дополнительных нулей
    if (timetemp2 < 10){
      str0  = String(0)+String(t.date) +String(t.mon);
    }


    timetemp1=t.mon;
    timetemp2=t.date;
    // следующие два цикла проверки - блок коррекции "пустого" разряда когда значение даты или месяца занимает только один разряд например "1.02"
    // происходит "дорисовка" дополнительных нулей
    if (timetemp2 < 10){
      str0  = String("A")+String(t.date) +String(t.mon);
    }

    if (timetemp1 < 10)
    {
      str0  = String(t.date) +  String(0)+String(t.mon);
      // Serial.println(timetemp1);

      if (timetemp2 < 10){
        str0  = String("A")+String(t.date) +  String(0)+String(t.mon);
      }
    }





    break;

  case 2:
    //выполняется когда mode равно 3 отображение температуры
    
    str0  = String("-32G");

    break; 
  case 3:
    //выполняется когда mode равно 3 отображение напряжения
    int sensorValue = analogRead(A0);
    str0  = String(sensorValue);
    Serial.println(sensorValue);
    break;    
    //default:
    // выполняется, если не выбрана ни одна альтернатива
    // default необязателен
  }


  switch (byte(str0.charAt(0))) {

  case 48:
    number1 = digit[0]; // 
    break;
  case 49:
    number1 = digit[1]; //
    break;
  case 50:
    number1 = digit[2]; //
    break;
  case 51:
    number1 = digit[3]; //
    break;
  case 52:
    number1 = digit[4]; //
    break;
  case 53:
    number1 = digit[5]; //
    break;
  case 54:
    number1 = digit[6]; //
    break;
  case 55:
    number1 = digit[7]; //
    break;    
  case 56:
    number1 = digit[8]; //
    break;
  case 57:
    number1 = digit[9]; //
    break;
  case 71:
    number1 = digit[21]; //
    break;
  case 45:
    number1 = digit[20]; //
    break;
  default:
    number1 = digit[22]; //
    break;
  }
  // далее проверяем нужно ли рисовать центральную точку разделитель
  // здесь режимы отображения времени и даты - точку рисуем
  if (mode < 2) { 
    switch (byte(str0.charAt(1))) {


    case 48:
      number2 = digit[10]; //  0
      break;
    case 49:
      number2 = digit[11]; //
      break;
    case 50:
      number2 = digit[12]; //
      break;
    case 51:
      number2 = digit[13]; //
      break;
    case 52:
      number2 = digit[14]; //
      break;
    case 53:
      number2 = digit[15]; //
      break;
    case 54:
      number2 = digit[16]; //
      break;
    case 55:
      number2 = digit[17]; //
      break;    //default:
    case 56:
      number2 = digit[18]; //
      break;
    case 57:
      number2 = digit[19]; //
      break;
    case 71:
      number2 = digit[21]; //
      break;
    case 45:
      number2 = digit[20]; //
      break;
    default:
      number2 = digit[22]; //
      break;
    }
  }
  //здесь другие режимы - центральную точку не рисуем
  if (mode > 1) { 
    switch (byte(str0.charAt(1))) {


    case 48:
      number2 = digit[0]; //  0
      break;
    case 49:
      number2 = digit[1]; //
      break;
    case 50:
      number2 = digit[2]; //
      break;
    case 51:
      number2 = digit[3]; //
      break;
    case 52:
      number2 = digit[4]; //
      break;
    case 53:
      number2 = digit[5]; //
      break;
    case 54:
      number2 = digit[6]; //
      break;
    case 55:
      number2 = digit[7]; //
      break;    
    case 56:
      number2 = digit[8]; //
      break;
    case 57:
      number2 = digit[9]; //
      break;
    case 71:
      number2 = digit[21]; //
      break;
    case 45:
      number2 = digit[20]; //
      break;
    default:
      number2 = digit[22]; //
      break;
    }
  }
  switch (byte(str0.charAt(2))) {


  case 48:
    number3 = digit[0]; //  0
    break;
  case 49:
    number3 = digit[1]; //
    break;
  case 50:
    number3 = digit[2]; //
    break;
  case 51:
    number3 = digit[3]; //
    break;
  case 52:
    number3 = digit[4]; //
    break;
  case 53:
    number3 = digit[5]; //
    break;
  case 54:
    number3 = digit[6]; //
    break;
  case 55:
    number3 = digit[7]; //
    break;    //default:
  case 56:
    number3 = digit[8]; //
    break;
  case 57:
    number3 = digit[9]; //
    break;
  case 71:
    number3 = digit[21]; //
    break;
  case 45:
    number3 = digit[20]; //
    break;
  default:
    number3 = digit[22]; //
    break;
  }
  switch (byte(str0.charAt(3))) {


  case 48:
    number4 = digit[0]; //  0
    break;
  case 49:
    number4 = digit[1]; //
    break;
  case 50:
    number4 = digit[2]; //
    break;
  case 51:
    number4 = digit[3]; //
    break;
  case 52:
    number4 = digit[4]; //
    break;
  case 53:
    number4 = digit[5]; //
    break;
  case 54:
    number4 = digit[6]; //
    break;
  case 55:
    number4 = digit[7]; //
    break;    
  case 56:
    number4 = digit[8]; //
    break;
  case 57:
    number4 = digit[9]; //
    break;
  case 71:
    number4 = digit[21]; //
    break;
  case 45:
    number4 = digit[20]; //
    break;
  default:
    number4 = digit[22]; //
    break;
  }


  // проходим циклом по всем 16 выходам двух регистров
  for (int thisLed = 0; thisLed < 16; thisLed++) {
    // записываем сигнал в регистр для очередного светодиода
    registerWrite(thisLed, HIGH, number1, number2, number3, number4);
    // если это не первый светодиод, то отключаем предыдущий
    if (thisLed > 0) {
      registerWrite(thisLed - 1, LOW, number1, number2, number3, number4);
    }
    // если это первый светодиод, то отключаем последний
    else {
      registerWrite(15, LOW, number1, number2, number3, number4);
    }


  }
}
// этот метод отсылает бит на сдвиговый регистр

void registerWrite(int whichPin, int whichState, byte  number1, byte  number2, byte  number3, byte  number4) {
  // для хранения 16 битов используем unsigned int
  unsigned int bitsToSend = 0;

  // выключаем светодиоды на время передачи битов
  digitalWrite(latchPin, LOW);

  // устанавливаем HIGH в соответствующий бит
  bitWrite(bitsToSend, whichPin, whichState);

  // разбиваем наши 16 бит на два байта
  // для записи в первый и второй регистр
  byte registerOne = highByte(bitsToSend);
  byte registerTwo = lowByte(bitsToSend);

  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, number4);
  shiftOut(dataPin, clockPin, MSBFIRST, B0001);
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, number3);
  shiftOut(dataPin, clockPin, MSBFIRST, B0010);
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, number2);
  shiftOut(dataPin, clockPin, MSBFIRST, B0100);
  digitalWrite(latchPin, HIGH);
  digitalWrite(latchPin, LOW);
  shiftOut(dataPin, clockPin, MSBFIRST, number1);
  shiftOut(dataPin, clockPin, MSBFIRST, B1000);
  digitalWrite(latchPin, HIGH);

  // "защелкиваем" регистр, чтобы биты появились на выходах регистра

}

Это часы с одной кнопкой переключающей их на индикацию других параметров например температуры и напряжения.

Проблема в том что часы корректируются программно только пока работают Это происходит каждое утро в "5.55" часы приостанавливаются на 9 сек. При отключении питания мк не работает а работает только DS1302. Часы я планирую использовать в автомобиле, а там МК будет выключатся отчего корректировки происходить не будет. Для того что бы использовать корректировку при выключениях необходимо плясать от дат и хранить данные в ПЗУ. Перед тем как начать писать этот код хочу поинтересоваться не знает ли кто хорошей библиотеки для работы с датами, конкретно нужна функция для вычисления периода между датами в разных месяцах и годах.

Joiner
Offline
Зарегистрирован: 04.09.2014

Samodelkin пишет:

А можно проще поставить DS3231 - минимум обвязки, управление микрой точно такое же как и ds1307 и ей же подобной, т.е. даже скетч не понадобится переписывать. Уже тикают часики почти 6 месяцов, секунда в секунду.

Точно. У меня такие же часики, наблюдаю месяц. Секунда в секунду. Даже не верится. Заказал на ебее еще пару штук. Забыл...они еще температуру показывают.