DS3231 Не совпадает время при выключении Arduino

Я пытаюсь сделать светодиодные часы с помощью DS3231 для отслеживания времени, но по какой-то причине они не отсчитывают время, когда Arduino выключен. Я пытался отключить часы от источника питания на 5 минут, и когда я снова включил их, часы показывают время, которое они отображали, прежде чем выключиться. Сначала я подумал, что аккумулятор, который я использовал, разрядился, поэтому заменил его на новый, но проблема не устранена. Потом я прочитал, что, возможно, я использую неперезаряжаемый аккумулятор, и чтобы это исправить, я удалил несколько резисторов и диодов, чтобы отключить функцию зарядки, но это тоже не решило проблему. На данный момент я не уверен, что это больше связано с аппаратным или программным обеспечением: часы не ведут отсчет времени, когда Arduino выключен. Возможно, купленный мною модуль оказался дешевой подделкой и не работает должным образом, поэтому я заказал модуль получше.

Я предоставлю фрагмент кодов, которые я использовал:

#include <RTClib.h>
#include <Wire.h>

RTC_3231 rtc;

int hoursNow;
int minutesNow;
int secondsNow;

void setup() {
  Serial.begin(9600);
  Wire.begin();
  rtc.begin();
  rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
//  rtc.adjust(DateTime(2023, 6, 31, 14, 21, 0));
}

void loop() {
  DateTime now = rtc.now();
  hoursNow = now.hour();
  minutesNow = now.minute();
  secondsNow = now.second();
  Serial.print(hoursNow);
  Serial.print(":");
  Serial.print(minutesNow);
  Serial.print(":");
  Serial.print(secondsNow);
  delay(1000);
}

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

, 👍2


3 ответа


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

У вас есть эта строка в настройке, которая устанавливает дату и время в соответствии с датой и временем компиляции кода. Это нормально, если установить один раз, но это время никогда не меняется. Это то время, когда вы скомпилировали код. Поэтому каждый раз, когда он запускается, вы возвращаете время обратно на это значение. RTC поддерживает отсчет времени, пока Arduino выключен, но как только он включается, ваш код возвращает его к тому, что было раньше.

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

,

Как это будет работать? Должен ли я использовать условный оператор? Я попробовал закомментировать эту конкретную строку, как вы предложили, и, конечно же, RTC поддерживает реальное время. Однако без этой строки время не будет обновляться в соответствии с моим текущим временем., @Win Win Tjong

Я сказал это в своем ответе. Загрузите скетч, позволяющий установить время. Запустите его ОДИН РАЗ. Теперь время установлено. Затем загрузите НОВЫЙ скетч, в котором не установлено время, и RTC по-прежнему будет иметь правильное время, которое было установлено скетчем ранее., @Delta_G


1

Вы можете рассмотреть возможность использования EEPROM для управления выполнением вашей команды установки времени на основе логического флага. Сначала запишите false (или 0) по определенному адресу в EEPROM, чтобы обозначить, что команда еще не выполнена. Затем ваша программа может проверить этот флаг при запуске. Если флаг ложный, он запускает команду установки времени и впоследствии обновляет флаг до true (или 1) в EEPROM. Это гарантирует, что команда будет выполняться только при необходимости.

#include <EEPROM.h>

// Предположим, что флаг хранится по адресу 0
const int flagAddress = 0;

void setup() {
  EEPROM.begin(512); // Отрегулируйте размер по мере необходимости
  bool timeSetFlag;
  EEPROM.get(flagAddress, timeSetFlag); // Прочитать флаг

  if (!timeSetFlag) {
    // Здесь находится команда установки времени
    timeSetFlag = true; // Обновить флаг
    EEPROM.put(flagAddress, timeSetFlag);
    EEPROM.commit(); // Сохраняем изменения в EEPROM
  }
}

void loop() {
  // Основной код
}
,

Вы, вероятно, никогда раньше не использовали DS3231, __DATE__ и __TIME__ - это информация о дате и времени, когда скетч компилируется, попробуйте распечатать любой скетч Arduino и посмотрите сами. Сохранение в EEPROM не решает проблему., @hcheung


0

rtc.adjust(ДатаВремя(F(__ДАТА__), F(__ВРЕМЯ__)));

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

__DATE__, __TIME__ — это время, когда компилятор скомпилировал ваш код, если вы скомпилировали код вчера, и вы никогда не меняли код и никогда не компилировали код снова, две константы будут содержать дату и время вчерашнего дня, когда код был скомпилирован. Это не реальное время дата время, как вы думали.

Вам нужно выполнить следующие шаги.

  1. Выньте резервную батарею;
  2. Используйте __DATE__ и __TIME__ только один раз при первом включении модуля, используя следующий код:
if (! rtc.isrunning()) {
    Serial.println("Setup time based on compiled date and time");
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
  1. Подключите модуль и немедленно загрузите новый скетч, дата и время должны быть установлены в соответствии с датой и временем компиляции скетча. Если вы сделаете это быстро, RTC, скорее всего, установит время на 10–15 секунд раньше (т. е. когда код был скомпилирован).
  2. вставьте батарею, пока модуль питается от VCC.

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

,