RTC установка времени с сохранением, как реализовать?

Надо сохранить время в eeprom.
Если МК перезагружается, взять сохраненное время. При клике, сохранять новое. Эта часть вроде как работает. Проблема начинаются в поиске разницы, сколько прошло. Как ее правильно найти, не понимаю…
И другой не приятный момент, это когда загружается скейт с ПК.
Новое время не хочет устанавливаться, берется из памяти.

#include <EEPROM.h>
#include "RTClib.h"
RTC_DS1307 rtc;

uint32_t MVtime = 0;
void setup() {
 // 1 установка даты и вр. с ПК
  if (!rtc.isrunning()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
//2 взять из памяти... Менял местами с 1, не сработало.
 MVtime = EEPROM.get(0, MVtime); 
  if (EEPROM.get(0, MVtime) > 2){ // если в памяти есть запись
      rtc.adjust(DateTime(MVtime));//установить дату из памяти 
  }
 }
void loop() {

  //часы
  DateTime now = rtc.now();// получить настоящее время
  static uint32_t startTime = rtc.now().unixtime();  // Время когда вкл МК
  uint32_t nowTime = now.unixtime();                 //время в данный момент
  uint32_t passedTime = nowTime - startTime;         //разница от старта до сейчас

//Пока МК работает, разницу находит. Сколько прошло.

  //форматирование
  byte sec = passedTime % 60;
  byte minutes = (passedTime % 3600) / 60;
  byte hour = passedTime / 3600;
  byte day = passedTime / 86400;


  //если был клик, обновить время
  if(isClick()){
    EEPROM.put(0, nowTime); // записать в память
  }

Мое предположение, что надо еще запомнить время на момент отключения.
Как именно это реализовать, если память быстро изнашивается…
Сохранять каждых 30 минут… ? или есть решения, по быстрой записи в момент отключения…

Другой вопрос, как обновлять время с ПК… Здесь даже предположений нет…

uint32_t startTimeSave = EEPROM.get(4, MVtime);

Добавляем за loop переменную, в нее запишем что есть.

 if(startTimeSave > 2){
     MVtime = startTimeSave; 
   static uint32_t startTime = rtc.adjust(DateTime(MVtime)); //установить дату из памяти 
 } else {
   static uint32_t startTime = rtc.now().unixtime();  // Время включения устройства
 }

Проверяем, что там что-то есть и устанавливаем сохраненное время.
Иначе настоящее записываем

uint32_t tmr1;

  if (millis() - tmr1 >= 60000) {
    tmr1 = millis();
    EEPROM.put(4, nowTime);
  }

Используем таймер, сейчас на 1 минуту…
Он запишет последнее время.
И вроде как все заработает…

Ругается на
static uint32_t startTime = rtc.adjust(DateTime(MVtime));
exit status 1
Compilation error: void value not ignored as it ought to be

Дело явно в этом моменте… как его обойти…
rtc.adjust(DateTime(MVtime));

Как написано, так и работает

Чего тут понимать?

переменная now получает значение только один раз, при инициализации, после чего не меняется. Соответственно, делать нужно так

DateTime now;
now = rtc.now();// получить настоящее время

Новое время устанавливается ТОЛЬКО если часы были остановлены. А они скорее всего продолжают работать. Т.е. опять же - как написано, так и работает

Не вижу смысла

С разницей ладно, методом ошибок решу задачу.
Как обойти проблему с установкой в момент загрузки с ПК… ?
Просто вообще нет ничего по этим часам. В примерах тоже

А чего там понимать. Преобразуйте оба времени в unix-time (при помощи функции mktime) и вычтите одно из другого - получите разницу в секундах.

1 лайк

Тоже мне проблема.

Просто не устанавливайте! Вы же сами его в строке №9 и устанавливаете! Уберите строку

rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));

из кода и не будет ничего устанавливаться.

Кстати, Вы вообще, понимаете, что у Вас в коде написано?

Да понимаю. Это строчка отвечает за установку вр. с ПК, ну и даты…
Она нужна, что бы обновляться. Когда загружаешь скейтч.
F это макросы, особо не знаю.

Зачем? Проблема исчезновения питания решается установкой резервной батарейки на модуль RTC - при нормальной батарейке модуль будет работат без внешнего питания месяцами, если не годами. И никакого сброса времени. А сохраненное в eeprom время прокиснет уже через минуту. А какой от него толк часов через 10?

Я уже показал, как надо. Но если хотите потом заявить, что сами разобрались - кто ж вам помешает ))

Вот врать-то зачем? Вот в примерах к библиотеке RTCLib

Из первого примера забрал все нужное. А так в них нет нужной реализации.
Там встроенная память, которые требует преобразование в HEX и обратно в DEC…
это побитовые операции, плохо знаком. Требуется 5 ячеек, вроде как для Float и 4 для uint32_t… + если питание пропадет, все исчезнет. Поэтому EEPROM.

Ладно, спасибо за помощь, буду думать дальше) Это полезно… Иногда даже интересно

Форум, это последнее) Когда уже сам не можешь…
А я на самом деле долго искал ответ, надеялся что тут
подобное кто-то реализовывал…

Что за бред?

С какого перепугу пропадет? Еще раз - при наличии батарейки время в RTC НЕ сбрасывается при пропадании питания. И даже не останавливается - оно продолжает идти. Хоть через неделю, хоть через три месяца включи девайс - время будет актуальным

Время в eeprom для восстановления при включении? Еще раз - это бессмысленно

1307 имеет 56 байт памяти. Что бы записать число 1715969180000, его надо разбить побитно в HEX для записи. В примере написано, что она не хранит данные,
если питание пропадет. Там нужен аккумулятор, который не так просто найти.
Да и приедет не скоро. Батарейки нельзя.

Пока для меня единственный вариант, это eeprom. Точное время не требуется.
Буду перезаписывать каждых 10-15 минут. Все равно не планирую что бы плата
жила вечность)

Да и просто интересно реализовать.

Простите, но вот это вместе

Выше моего понимания.

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

Это бред. Ничто и никогда не требует таких преобразований, кроме процедур вывода на печать/экран для чтения человеком.

Что подобное? Часы? Все реализовывали. А что хотите реализовать Вы, думаю не понимает никто (и Вы в первую очередь).

3 лайка

А мужики-то и не знали )))

Для использования обычных батареек нужно удалить цепь заряда аккумулятора

модуль расчитан на применение аккумулятора LIR2032, если будет использоваться обычная батарейка, цепь заряда лучше отпаять, чтобы батарейка не портилась. Цепь заряда - это диод (красненький бочонок) и резистор R6. Диод нужно выпаять, резистор R6 выпаять и впаять вместо него перемычку. Дополнительно можно выпаять резисторы R4 и R7

Можно. После удаления ненужного

Еще раз - через несколько часов какой смысл от времени, которое отстает от текущего на несколько часов?

1 лайк

Обычный LI на 4.2 - 3в подойдет? Таблетка точно на 3в…
только это полный заряд или нет… Или например кинуть этот
АКБ на питание ардуино… через TP4056… что бы он не перезаряжался.

И все равно надо обнулять дату… А она через static.
хотя это не такая проблема, просто еще одну переменную добавить.

P.s. Я хотел потрогать EEPROM и это единственная причина почему
решил попробовать. Спасибо

Не, я понимаю) Я хотел реализовать что-то типа секундомера.
Что бы знать сколько прошло с возможность сброса.
А так действительно фигней занимаюсь, когда можно подкинуть
акб с TP4056… Главное как это правильно сделать.
Или просто к самим часам…

Спасибо за ответы

Спасибо! Пятница удалась :smiley: