Часы на DS3231.Отстают прилично

valera678
Offline
Зарегистрирован: 04.11.2016

Добрый день! с Наступающим всех,друзья!

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

вот собстно код


#include "CyberLib.h"

#include "TM1637.h"
#define CLK 11   // пин 11
#define DIO 12   // пин 12
TM1637 tm1637(CLK,DIO);
#define ON 1
#define OFF 0

#include <DS3231.h>
#include <Wire.h>
DS3231  rtc(SDA, SCL);
Time t;

#include <IRstD.h> 
IRrecvstd irrecvstd(4); 
decode_resultsstd res_std;

#define MAXMILLIS 4294967295
unsigned long timme;
unsigned long timelapsed = 0;
int chas = 0;
int minuta = 0;
int secunda = 0;

///////////// B1 ////////////////////
uint8_t B1_flag = ReadEEPROM_Byte(1);
uint8_t B1chas_vkl = ReadEEPROM_Byte(2);
uint8_t B1minut_vkl = ReadEEPROM_Byte(3);

uint8_t val_shim = ReadEEPROM_Byte(4);

uint8_t flag_disp = 0;
uint8_t flag_zel_led = 0;

int buzzerPin = 5;

int8_t TimeDisp[] = {0x00,0x00,0x00,0x00};
int8_t BudDisp[] = {0x00,0x00,0x00,0x00};
unsigned char ClockPoint = 1;


void setup() 
{
  tm1637.set(val_shim);
  tm1637.init();
  pinMode(buzzerPin, OUTPUT);
  D7_Out;  
  D7_Low;
  D10_Out;

  if(B1_flag) D10_High;
  else D10_Low;
  
  Serial.begin(57600);
  irrecvstd.enableIRInstd();

  rtc.begin();
}


void loop() 
{
   if(irrecvstd.decodestd(&res_std)) 
    {
       if(res_std.valuestd == 16750695) // Прибавление часов
         {
           analogWrite(buzzerPin, 255);
           chas++;
           if(chas > 23) chas = 0;
           rtc.setTime(chas, minuta, secunda);
           disp();
           analogWrite(buzzerPin, 0);
         }

       if(res_std.valuestd == 16738455) // Убавление часов
         {
           analogWrite(buzzerPin, 255);
           chas--;
           if(chas < 1) chas = 0;
           rtc.setTime(chas, minuta, secunda);
           disp();
           analogWrite(buzzerPin, 0);
         } 

       if(res_std.valuestd == 16718055) // Прибавление минут
         {
           analogWrite(buzzerPin, 255);
           minuta++;
           if(minuta > 59) minuta = 0;
           rtc.setTime(chas, minuta, secunda);
           disp();
           analogWrite(buzzerPin, 0);
         }  

       if(res_std.valuestd == 16724175) // Убавление минут
         {
           analogWrite(buzzerPin, 255);
           minuta--;
           if(minuta < 1 || minuta > 60) minuta = 0;
           rtc.setTime(chas, minuta, secunda);
           disp();
           analogWrite(buzzerPin, 0);
         } 

       if(flag_disp && res_std.valuestd == 16761405) // Прибавление часов будильника
         {
           analogWrite(buzzerPin, 255);
           B1chas_vkl++;
           if(B1chas_vkl > 23) B1chas_vkl = 0;
           WriteEEPROM_Byte(2, B1chas_vkl);
           disp();
           analogWrite(buzzerPin, 0);
         } 

       if(flag_disp && res_std.valuestd == 16720605) // Убавление часов будильника
         {
           analogWrite(buzzerPin, 255);
           B1chas_vkl--;
           if(B1chas_vkl < 1 || B1chas_vkl > 24) B1chas_vkl = 0;
           WriteEEPROM_Byte(2, B1chas_vkl);
           disp();
           analogWrite(buzzerPin, 0);
         }  

       if(flag_disp && res_std.valuestd == 16726215) // Прибавление минут будильника
         {
           analogWrite(buzzerPin, 255);
           B1minut_vkl++;
           if(B1minut_vkl > 59) B1minut_vkl = 0;
           WriteEEPROM_Byte(3, B1minut_vkl);
           disp();
           analogWrite(buzzerPin, 0);
         }

       if(flag_disp && res_std.valuestd == 16716015) // Убавление минут будильника
         {
           analogWrite(buzzerPin, 255);
           B1minut_vkl--;
           if(B1minut_vkl < 1 || B1minut_vkl > 60) B1minut_vkl = 0;
           WriteEEPROM_Byte(3, B1minut_vkl);
           disp();
           analogWrite(buzzerPin, 0);
         }  


       if(res_std.valuestd == 16730805) // Вкл/Откл будильник
         {
           analogWrite(buzzerPin, 255);

           B1chas_vkl = ReadEEPROM_Byte(2);
           B1minut_vkl = ReadEEPROM_Byte(3);
           
           if(B1_flag) 
             {
                B1_flag = 0;
                D10_Low;
             }   
                
           else 
             {
               B1_flag = 1;
               D10_High;
             }
               
           disp();
           
           WriteEEPROM_Byte(1, B1_flag);
           analogWrite(buzzerPin, 0);
         }


       if(res_std.valuestd == 16728765) // Вывод будильника на дисплей
         {
           analogWrite(buzzerPin, 255);
           flag_zel_led = 0;
           
           if(flag_disp) 
             {
                flag_disp = 0;
                D7_Low;
             }   
                
           else 
             {
               flag_disp = 1;
               D7_High;
             }
               
           disp();
           analogWrite(buzzerPin, 0);
         }  


       if(res_std.valuestd == 16736925) // Подсветка +
         {
           analogWrite(buzzerPin, 255);
           val_shim++;
           if(val_shim > 7) val_shim = 7;
           WriteEEPROM_Byte(4, val_shim);
           tm1637.set(val_shim);
           disp();
           delay_ms(10);
           analogWrite(buzzerPin, 0);
         }  

       if(res_std.valuestd == 16754775) // Подсветка -
         {
           analogWrite(buzzerPin, 255);
           val_shim--;
           if(val_shim < 1 || val_shim > 254) val_shim = 0;
           WriteEEPROM_Byte(4, val_shim);
           tm1637.set(val_shim);
           disp();
           delay_ms(10);
           analogWrite(buzzerPin, 0);
         }  


       if(res_std.valuestd == 16732845) // +10 минут отсрочка
         {
           analogWrite(buzzerPin, 255);
           B1minut_vkl = B1minut_vkl + 10;
           
           if(B1minut_vkl > 59) 
             {
                B1minut_vkl = 10;
                B1chas_vkl++;
                if(B1chas_vkl>23)  B1chas_vkl=0;
             }

           delay_ms(5);
           analogWrite(buzzerPin, 0);

           flag_disp = 1;
           D7_High;
           disp();
           delay_ms(300);
           flag_disp = 0;
           D7_Low;
         } 

       //Serial.println(res_std.valuestd); // Удалить после программирования пульта
       
       irrecvstd.resumestd();
       res_std.valuestd = 0; 
    }


  unsigned long currtime = millis();
  
  if(currtime > timme) timelapsed = (currtime - timme); 
  else timelapsed = (MAXMILLIS - timme + currtime);
  
  if(timelapsed > 999)
    {  
        timme = currtime;
        
        if(flag_disp)
          {
            flag_zel_led++;
            if(flag_zel_led > 59)
              {
                flag_zel_led = 0;
                flag_disp = 0;
                D7_Low;
                analogWrite(buzzerPin, 255);
                delay_ms(5);
                analogWrite(buzzerPin, 0);
              }
          }
        
        disp(); 
     }


  t = rtc.getTime();
  chas = t.hour,DEC;
  minuta = t.min,DEC;
  secunda = t.sec,DEC;

  if(B1_flag)
    {
      if(chas == B1chas_vkl && minuta == B1minut_vkl) 
        {
           buzz();
        }

      if(chas == B1chas_vkl && minuta == B1minut_vkl && secunda == 59) 
        {
           B1minut_vkl = B1minut_vkl + 10;
           if(B1minut_vkl > 59) 
             {
                B1minut_vkl = 10;
                B1chas_vkl++;
                if(B1chas_vkl>23)  B1chas_vkl=0;
             }
        }
    }

} //END LOOP


void buzz() 
{ 
  if(B1_flag)
   { 
     analogWrite(buzzerPin, 30);       
     delay_ms(100); 
     analogWrite(buzzerPin, 50);       
     delay_ms(100);
   }

  analogWrite(buzzerPin, 0);
  delay_ms(100);         
}


void disp()
 {
     if(!flag_disp)   
      {
        ClockPoint = (~ClockPoint) & 0x01;
        
        if(ClockPoint)tm1637.point(POINT_ON);
        else tm1637.point(POINT_OFF);

        TimeDisp[0] = chas / 10;
        TimeDisp[1] = chas % 10;
        TimeDisp[2] = minuta / 10;
        TimeDisp[3] = minuta % 10;
        tm1637.display(TimeDisp);
      }

     else
      {
        tm1637.point(POINT_ON);
        BudDisp[0] = B1chas_vkl / 10;
        BudDisp[1] = B1chas_vkl % 10;
        BudDisp[2] = B1minut_vkl / 10;
        BudDisp[3] = B1minut_vkl % 10;
        tm1637.display(BudDisp);
      }
 }
ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Мда. Ну, по пунктам разибирать тут долго, но код какой-то совсем ни о чём. Кстати, самое увивительное, что они у Вас хоть как-то идут. Мне это кажется сомнительным. Похоже, Вы выложили код, который поправили в последний момент и не проверяли.

Давайте абстрагируемся от нажатия кнопок и будильников и посмотрим как просто часы работают. При таком условии (кнопки на пульте никто и никогда не жамкает), перемнная flag_disp у Вас всегда равна 0. Вот давайте смотреть.

1. Вы сначала показываете время (строка 273), а только потом спрашиваете его у часов (строка 277).  Вам это не кажется странным? Вы показываете старые значения.

2. В строке 20 Вы заводите переменную timme, ничего ей не присавиваете, но в строке 252 уже вовсю используете. 

3. Строки 252-253 нужны для борьбы с мифическим переполнением millis, которого не возникает, если им правильно пользоваться.

4. Вы показываете время раз в секунду, причем не тогда, когда Ваши часы переходят на новую секунду, а когда миллис 1000 мс отсчитает. С точки зрения часов это может быть посередине секунды. Зачем Вы так поступаете?

5. Ваши часы не показывают секунд, но Вы обновляете время раз в секунду (причём неточно, см. предыдущий пункт). Зачем? Зачем Вам вообще что-то делать ежесекундно, если часы показывают только минуты и точность будильника только до минут?

6. Ну, и самое забавное на десерт. Как Вы понимаете строки 278-280? Вы там присваиваете значения трём переменным (chas, minuta, secunda). Попробуйте их (три переменные) напечатать  в сериал и посмотреть чему они равны после присваивания. Узнаете много интересного.

------------------

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

 

 

valera678
Offline
Зарегистрирован: 04.11.2016

спасибо,Евгений,за подробный ответ. в выложенном коде я понимаю немного ,потому как взят он отсюда http://istarik.ru/blog/arduino/60.html

Буду искать как еще можно сделать ход часов на этом модуле либо ds3107. 

inspiritus
Offline
Зарегистрирован: 17.12.2012

У меня часы на этом чипе в качестве резервного времени отставали также аццки

пришлось пропаять на землю кварц. Стало лучше , нр все равно криво.

в итоге сделал каждые 15 мин синхронизацию секунд по ntp

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678 пишет:

Буду искать как еще можно сделать ход часов на этом модуле либо ds3107. 

ТОлько на этом. Тот значительно хуже.

По поводу, "как делать". Посмотрите на Ваш модуль. У него есть пин SQW. Так вот, модулю можно объяснить, чтобы он раз в минуту (точно при переходе на новую минуту) выдавал импульс на этот пин.

Поэтому ход часов делается так:

1. Пин SQW заводится на 2 или 3 пин Ардуино.

2. В setup один раз модулю объясняется., чтобы он раз в минуту выдавал на SQW импульс 

3. Там же в setup назначется обработчик прерывания от пина на который заведен SQW.

4. В обработчике прерывания нужно спросить у часов время и показать на экране.

Собственно всё. Как видите loop тут вообще не при делах. В нём для хода вообще ничего делать не надо.

------------------------------

Кстати, Вы поставили печать тех трёх переменных, как я советовал? Посмотрели, что Вы им на самом деле присваиваете?

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

inspiritus пишет:

У меня часы на этом чипе в качестве резервного времени отставали также аццки

пришлось пропаять на землю кварц. Стало лучше , нр все равно криво.

в итоге сделал каждые 15 мин синхронизацию секунд по ntp

Вы что-то перепутали. У 3231 невозможно пропаять кварц на землю, т.к. кварц у них внутри микросхемы. Внешнего кварца там нет.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678 пишет:

взят он отсюда http://istarik.ru/blog/arduino/60.html

Запомните автора и больше никогда у него ничего не берите. Он полный чайник, а код - бред.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

inspiritus пишет:

У меня часы на этом чипе в качестве резервного времени отставали также аццки

пришлось пропаять на землю кварц. Стало лучше , нр все равно криво.

в итоге сделал каждые 15 мин синхронизацию секунд по ntp

Вы что-то перепутали. У 3231 невозможно пропаять кварц на землю, т.к. кварц у них внутри микросхемы. Внешнего кварца там нет.

"Верьте мне люди" - кинофильм, если человек говорит, что пропаял, значит пропаял...
А из поста вашего узнал для себя много интересного, а то голову ломал, что за контакт SQW

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

если человек говорит, что пропаял, значит пропаял...

Тоже верно. Взял микроскоп, залез в кристалл, ...

ua6em пишет:

что за контакт SQW

Кроме того, о чём я говорил, на этот пин можно

1. Выводить импульс при переходе на новую секунду (а не минуту)
2. Выводить импуль при срабатывании будильника (там есть два встроенных будильника )
3. Выводить меандр с некоторой частотой (там варианты)
4. пин может переходить в High impedance когда микросхема теряет питание на Vcc

 

valera678
Offline
Зарегистрирован: 04.11.2016

nik182
Offline
Зарегистрирован: 04.05.2015

Я приводил код часов на этой микросхеме здесь. http://arduino.ru/forum/obshchii/attiny85-i-posledovatelnyi-port#comment-232712

Отлично работает уже больше трёх месяцев. Ухода нет. Будильник есть. Отлаживал на нанке. Запихнул в тиньку.

Кстати импульс можно выводить раз в секунду или минуту или час или день.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nik182 пишет:

Кстати импульс можно выводить раз в секунду или минуту или час или день.

Нет, только минуту и секунду. Всё остальное - разновидности будильников (срабатывает по совпадению). Вот полная таблица. Минута и секунда помечены ** и * соответственно:

ALARM 1 REGISTER MASK BITS (BIT 7)
A1M4 A1M3 A1M2 A1M1
X 1 1 1 1 Alarm once per second (*)
X 1 1 1 0 Alarm when seconds match
X 1 1 0 0 Alarm when minutes and seconds match
X 1 0 0 0 Alarm when hours, minutes, and seconds match
0 0 0 0 0 Alarm when date, hours, minutes, and seconds match
1 0 0 0 0 Alarm when day, hours, minutes, and seconds match
 
ALARM 2 REGISTER MASK BITS (BIT 7)
A2M4 A2M3 A2M2
X 1 1 1 Alarm once per minute (00 seconds of every minute) (**)
X 1 1 0 Alarm when minutes match
X 1 0 0 Alarm when hours and minutes match
0 0 0 0 Alarm when date, hours, and minutes match
1 0 0 0 Alarm when day, hours, and minutes match

 

valera678
Offline
Зарегистрирован: 04.11.2016

ЕвгенийП пишет:

6. Ну, и самое забавное на десерт. Как Вы понимаете строки 278-280? Вы там присваиваете значения трём переменным (chas, minuta, secunda). Попробуйте их (три переменные) напечатать  в сериал и посмотреть чему они равны после присваивания. Узнаете много интересного.

да посмотрел в мониторе переменные .

 t = rtc.getTime();
  chas = t.hour,DEC;
  minuta = t.min,DEC;
  secunda = t.sec,DEC;
  Serial.println( chas);
 Serial.println(minuta );
 Serial.println(secunda );
delay(1000);

Печатаются в формате 19,2,4 например. Правильнее наверно 19,02,04 ? Вы это имели ввиду

nik182
Offline
Зарегистрирован: 04.05.2015

ЕвгенийП пишет:

nik182 пишет:

Кстати импульс можно выводить раз в секунду или минуту или час или день.

Нет, только минуту и секунду. Всё остальное - разновидности будильников (срабатывает по совпадению). Вот полная таблица. Минута и секунда помечены ** и * соответственно:

ALARM 1 REGISTER MASK BITS (BIT 7)
A1M4 A1M3 A1M2 A1M1
X 1 1 1 1 Alarm once per second (*)
X 1 1 1 0 Alarm when seconds match
X 1 1 0 0 Alarm when minutes and seconds match
X 1 0 0 0 Alarm when hours, minutes, and seconds match
0 0 0 0 0 Alarm when date, hours, minutes, and seconds match
1 0 0 0 0 Alarm when day, hours, minutes, and seconds match
 
ALARM 2 REGISTER MASK BITS (BIT 7)
A2M4 A2M3 A2M2
X 1 1 1 Alarm once per minute (00 seconds of every minute) (**)
X 1 1 0 Alarm when minutes match
X 1 0 0 Alarm when hours and minutes match
0 0 0 0 Alarm when date, hours, and minutes match
1 0 0 0 Alarm when day, hours, and minutes match

 

И как это противоречит тому, что я написал? Например

X 1 1 0 0 Alarm when minutes and seconds match - выводит сигнал один раз в час , каждый час. 

 

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

Евгений Петрович - я готов быть учеником и написать с нуля, только одно условие, весь код (с так называемыми библиотеками) будет в одном скетче и, там еще микросхема памяти имеется - используем под свои нужды )))
PS я понимаю, что некрасиво ставить условия учителю, но мне, пенсионеру - учиться так учиться )))

 

valera678
Offline
Зарегистрирован: 04.11.2016

нашел только что интересную библиотеку для ds3231 и ds3232 https://github.com/JChristensen/DS3232RTC

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

valera678 пишет:

нашел только что интересную библиотеку для ds3231 и ds3232 https://github.com/JChristensen/DS3232RTC

А чем же она хороша?

valera678
Offline
Зарегистрирован: 04.11.2016

да понятия не имею)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

nik182 пишет:

И как это противоречит тому, что я написал? Например

X 1 1 0 0 Alarm when minutes and seconds match - выводит сигнал один раз в час , каждый час. 

Как противоречит? Очень просто. Для такого фокуса надо ещё и аларм настраивать "с кем именно match", т.е. это то, что я и назвал "разновидность будильника" потому, что для такого "match" нужно пожертвовать одним из будильников.

Я же говорил о возможности без всяких алармов иметь сигнал каждую минуту/секунду для обновления экрана, а алармы остаются свободными для использования по прямому назначению.

Т.е. вопрос в понимании терминологии - мы о разном, похоже, говорили.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678 пишет:

да посмотрел в мониторе переменные .

 t = rtc.getTime();
  chas = t.hour,DEC;
  minuta = t.min,DEC;
  secunda = t.sec,DEC;
  Serial.println( chas);
 Serial.println(minuta );
 Serial.println(secunda );
delay(1000);

Печатаются в формате 19,2,4 например. Правильнее наверно 19,02,04 ? Вы это имели ввиду

Нет, я имел в виду ... в общем. уберите все ", DEC" и сравните результат.

valera678
Offline
Зарегистрирован: 04.11.2016

Разницы не заметил

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678 пишет:

Разницы не заметил

Вот и я ж про тоже, общие выводы:

1. ", DEC" - не нужны

2. Эта конструкция (", DEC") означает здесь совсем не то, что Вы (или кто там автор скетча) думали.

valera678
Offline
Зарегистрирован: 04.11.2016

Евгений,поломаю мозг разбираясь в том ,судя по всему,никчемном коде. Толкните в правиьном направлении. Абсолютно не пойму как сделать это: 

2. В setup один раз модулю объясняется., чтобы он раз в минуту выдавал на SQW импульс 

3. Там же в setup назначется обработчик прерывания от пина на который заведен SQW.

4. В обработчике прерывания нужно спросить у часов время и показать на экране

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678 пишет:

Евгений,поломаю мозг разбираясь в том ,судя по всему,никчемном коде. Толкните в правиьном направлении. Абсолютно не пойму как сделать это: 

2. В setup один раз модулю объясняется., чтобы он раз в минуту выдавал на SQW импульс 

3. Там же в setup назначется обработчик прерывания от пина на который заведен SQW.

4. В обработчике прерывания нужно спросить у часов время и показать на экране

Не в каждой библиотеке есть готовая функция для "ежеминутных импульсов", написать её самому, как я понимаю, для Вас не вариант.

Хорошо, возмите вот эту библиотеку, в ней точно есть.

Соедините SQW с пином 2 или 3 (какой Вы там в коде выберите). Ну, питание и I2C соедините как обычно.

Попробуйте вот такой маленький код

#include <Wire.h>
#include <DS3231.h>

#define	PIN_SQW	3	// можно использовать 2 или 3 пин

static DS3231 Clock; // Собственно часы

//
//	Обработчик прерывания от часов, которое приходит при переходе минуты
//	Вообще-то гнать в сериал в обработчике прерывания - очень плохая идея,
//	Здесь это делается только чтобы не усложнять пример выводом на экран.
//	По уму, конечно, нужно на экран выводить.
//
static void everyMinuteAlarm(void) {
	const byte oldSReg = SREG;
	sei();
	Serial.print(Clock.getHour());
	Serial.print(":");
	Serial.print(Clock.getMinute());
	Clock.clearAlarmSignal(2);
	SREG = oldSReg;
}


void setup(void) {
	Serial.begin(115200);
	pinMode(PIN_SQW, INPUT);
	Wire.begin();
	Clock.setClockMode(false);	// Часы в 24-часовом режиме. Нужен 12-ти - пишем true
	Clock.turnOffAlarm(2);	//	Для очистки совести, мы не знаем что там часы делают
	Clock.EnableMinuteInterrupt();	// включаем ежеминутное прерывание
	attachInterrupt(PIN_SQW - 2, everyMinuteAlarm, FALLING);	// собираемся его обрабатывать
}

oid loop(void) {}

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

Он должен раз в минуту (при переходе на новую минуту по часам) выдавать в сериал текущее время. При запуске ничего не выдаёт. Первый раз он напечатает время только тогда, когда дождётся перехода минуты, так что как запустите - потерпите, в течение минуты он должен первый результат выдать, а потом каждую минуту.

Как видите, три десятка строк с пустым loop(). В loop можете делать что хотите, хоть delay(100500) - это не помешает часам спокойно идти и показывать результат, т.к. всё работает на прерывании, а ему на delay наплевать.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

Евгений Петрович - я готов быть учеником и написать с нуля, только одно условие, весь код (с так называемыми библиотеками) будет в одном скетче и, там еще микросхема памяти имеется - используем под свои нужды )))
PS я понимаю, что некрасиво ставить условия учителю, но мне, пенсионеру - учиться так учиться )))

Учёного учить - только портить!

inspiritus
Offline
Зарегистрирован: 17.12.2012

valera678 пишет:

спасибо,Евгений,за подробный ответ. в выложенном коде я понимаю немного ,потому как взят он отсюда http://istarik.ru/blog/arduino/60.html

Буду искать как еще можно сделать ход часов на этом модуле либо ds3107. 

я писал что пропаял после этого сообщения > про тот чип что в нем указан

что непонятно ?

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Тема про DS3231, а в том сообщении сказано "на этом модуле либо ds3107", Вы же написали "У меня часы на этом чипе". То, что под "этом" Вы понимали "либо", понятно Вам одному.

nik182
Offline
Зарегистрирован: 04.05.2015

С кем именно match надо настраивать для любого вывода сигнала. По умолчанию никаких сигналов не выводится. Для вывода надо настроить. Нельзя вывести сигналы и отдельно будильники.Нога одна. Её можно настроит на вывод Square-Wave Output с частотами 1Гц, 1,4,8 кГц. Или на вывод будильников, так как я говорил. При этом первый будильник может выдавать 1 Гц. Но только после настройки.  

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

так вот посимпатишнее наверное )))
 

static void everyMinuteAlarm(void) {
  const byte oldSReg = SREG;
  sei();
  Serial.print(Clock.getHour());
  Serial.print(":");
  Serial.print(Clock.getMinute());
  Serial.println("");
  Clock.clearAlarmSignal(2);
  SREG = oldSReg;
}

Кстати, так тоже видимо будет работать, но позволит добавить незначащие нули, то-есть, еще симпатишнее:
 

static void everyMinuteAlarm(void) {
  const byte oldSReg = SREG;
  sei();
  Serial.print(String(Clock.getHour()));
  Serial.print(":");
  Serial.print(String(Clock.getMinute()));
  Serial.println("");
  Clock.clearAlarmSignal(2);
  SREG = oldSReg;
}

 

 

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

ua6em пишет:

так вот посимпатишнее наверное )))

По первому скетчу, ln  нужен в 6-ой строке (я просто забыл добавить), а седьмая вовсе не нужна.

По второму - запрос памяти в прерывании, ..., ну, можно, конечно, но побойтесь Бога :)

valera678
Offline
Зарегистрирован: 04.11.2016

Да,Евгений,ваш маленький, замечательный код работает

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Да, удивительно, потому что сам я его не опробовал.

Теперь попробуйте будет ли он идти точно. Вы говорили, что на том коде погрешность уже через несколько часов была очевидной.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

Да, удивительно, потому что сам я его не опробовал.

 

Мы тут уже несколько постов разбор полётов кода ведём в полной уверенности, что он работает, и что там можно улучшить )))
А вот люблю я чтобы часики выводились четырьмя числами )))
Выдайте Евгений ваш код этого в пару строк )))

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Троллить изволите?

Ну, не знаю, я бы как-нибудь так делал:

// 
// int8_t n;
// Гарантировано, что 0 <= n < 100
//
char * buffer = "00";
if (i < 10) buffer[1] += n;
else {
	buffer[0] += n / 10;
	buffer[1] += n % 10;
}
// buffer содержит искомую строку

-------------------------------------------------

UPD: Троллинг не получился? :((( Прошло полдня и никто не ткнул меня носом? Или никто не читал код? Просто на всякий случай, чтобы не было недоразумений - так делать нельзя. Эта ошибка подробно разбирается в моём третьем этюде про память (порча константы).

valera678
Offline
Зарегистрирован: 04.11.2016

не сомневаюсь что многие видели. Но для меня это так же понятно как клинопись)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678 пишет:

так же понятно как клинопись)

Ну, смотрите, там же я беру указатель на константу и гажу в неё ( в константу). Я про такую ошибку в этюде писал.

ua6em меня троллил, ну и я решил потроллить в ответ, но он толи не заметил ошибки, толи не повёлся на троллинг :(

В любом случае, с наступающим! :)

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

valera678,

так что, нормально часы идут с тем скетчем, что я дал или тоже отстают? Вы не написали.

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

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

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

dimax пишет:

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

у профессиоаналов всё может.

ua6em
ua6em аватар
Offline
Зарегистрирован: 17.08.2016

ЕвгенийП пишет:

valera678 пишет:

так же понятно как клинопись)

Ну, смотрите, там же я беру указатель на константу и гажу в неё ( в константу). Я про такую ошибку в этюде писал.

ua6em меня троллил, ну и я решил потроллить в ответ, но он толи не заметил ошибки, толи не повёлся на троллинг :(

В любом случае, с наступающим! :)

Евгений Петрович - я не не повёлся, для троллинга надо было напрячь мозги, а я мастер простых решений )))
Вам то это без напряжения, а мне...

В напряжении высоком,
В беспокойности минут
Ты стучи горячим током
Переполненный сосуд.

Храм мечтаний, якорь страсти,
Справедливости весы.
Миокард - в чьей высшей власти
Жизни хрупкие часы.

Ты стучи горячим током
Переполненный сосуд.
В напряжении высоком,
В беспокойности минут.

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

dimax пишет:

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

Это у Вас не может, а у "нормальных пацанов" (помните такой анекдот?) ... Вы не поверите, но может.

Вы, видимо не смотрели на скетч ТС. Если, например (как там сделано), сначала показывать время на экране, а потом запрашивать его у часов, то и не такое возможно.

Andrey12
Andrey12 аватар
Онлайн
Зарегистрирован: 26.12.2014

dimax пишет:

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

Еще есть параметр Aging Offset который регулируется записью данных по адресу 10h

Я же правильно понимаю что записав туда значение отличное от 0 можно устранить убегание/отставание часов. Так как с английским не ахти то возможно неправильно понимаю значение этого параметра.

Вот даташит на 14 странице есть описание. 

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

 

 

valera678
Offline
Зарегистрирован: 04.11.2016

dimax пишет:

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

dimax, даже если вы смоете флюс ,смените батарейку,вымоете руки,поместите изделие в стерильный бокс.. то все равно удивитесь)

dimax
dimax аватар
Онлайн
Зарегистрирован: 25.12.2013

Andrey12, это очень тонкая настройка, при её крайних константах макс. уход часов за год будет меньше чем у Т.С. набегает за день.

valera678, как бы то ни было проблема в любом случае аппаратная.

valera678
Offline
Зарегистрирован: 04.11.2016

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

valera678
Offline
Зарегистрирован: 04.11.2016

похоже Вы,правы,dimax, отставания я не замечаю на часах собранных на макетке. Еще была проблема с коррекцией часов , при нажатии "+час" "-час" коррекция происходила на секунду и значение возращалось в первоначальному. Печатку пересмотрел. Но ума не приложу в чем проблема. Все собрано на атмеге 328P ,может кварц битый или еще что. Вобщем найду устраню

valera678
Offline
Зарегистрирован: 04.11.2016

на макетке все работает без замечаний...как ни странно

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Кварц там совсем не при делах. У часов свой кварц.

valera678
Offline
Зарегистрирован: 04.11.2016

да... по ходу проблема с панелькой модуля часов. Соединяю модуль часов с МК проводами-все работает

Ardo23
Offline
Зарегистрирован: 29.12.2016

модуль 1307 убегает за неделю на 2 минуты . вывод SQ присутствует - это тот же самый SQW ???

ЕвгенийП
ЕвгенийП аватар
Offline
Зарегистрирован: 25.05.2015

Ardo23 пишет:

модуль 1307 убегает за неделю на 2 минуты . вывод SQ присутствует - это тот же самый SQW ???

Тут все предлагают за кого-нибудь в гугле поискать, а мне за Вас даташит почитать?

Я не знаю, что и на каком заборе написал производитель модуля, но в микросхеме DS1307 нет вывода SQ, а вывод SQW есть. Он означает не совсем то, что в 3231, но переключать часы точно, а не когда попало, по нему можно. Его можно сконфигурировать на выдачу прямоугльного сигнала в 1Hz при этом переключение секунд в часах будет происходить по заднему фронту этого сигнала.