Настройка функции времени с помощью библиотеки DS3232
Я пытаюсь установить время на моем DS3231, а затем прочитать это время на моем arduino nano. Это для проекта цифровых часов. Я использую библиотеку DS3232 от JChristensen.
У него есть пример, который может установить время DS3231 через последовательный монитор, и он отлично работает, но я не понимаю, как реализовать это в моем скетче.
Я могу подтвердить, что после установки внешнего RTC с использованием указанного примера я могу загрузить свой код, и часы будут показывать время, когда они отключены. Это установка времени в скетче, который я не могу понять. Сегодня я занимался этим около 8 часов и читал ресурсы github.
Вот мой код. Вверху вы можете увидеть мою попытку установить системное время, а затем установить его на RTC.
#include "SevSeg.h";
#include <DS3232RTC.h>; //Джек Кристенсен
https://github.com/JChristensen/DS3232RTC
#include <Streaming.h>; //Микал Харт https://github.com/janelia-
arduino/Streaming
//Также требуется библиотека времени https://github.com/PaulStoffregen/Time
SevSeg sevseg;
void setup() {
// поместите сюда код установки для однократного запуска:
//Серийный.начало(9600);
setSyncProvider(RTC.get);// функция для получения времени от RTC
setTime(8,0,0,20,1,2020);
time_t t = now();
RTC.set(now());
byte numDigits = 4;
byte digitPins[] = {2, 3, 4, 5};
byte segmentPins[] = {6, 7, 8, 9, 10, 11, 12};
bool resistorsOnSegments = false; // 'false' означает, что резисторы находятся на цифре
pins
byte hardwareConfig = COMMON_CATHODE; // См. README.md для опций
bool updateWithDelays = false; // Рекомендуется значение по умолчанию false
bool leadingZeros = false; // Используйте 'true', если хотите сохранить начальный
zeros
bool disableDecPoint = true; // Используйте 'true', если ваша десятичная точка не
exist or isn't connected. Then, you only need to specify 7 segmentPins[]
sevseg.begin(hardwareConfig, numDigits, digitPins, segmentPins,
resistorsOnSegments,
updateWithDelays, leadingZeros, disableDecPoint);
}
void loop() {
sevseg.setChars("hola");
sevseg.refreshDisplay();
if(millis()>6000) {
int adj = 0;
int timenumber;
int hr = hourFormat12();
int Min = minute();
timenumber = (hr*100) + Min; //преобразует время в число для семи
segment display
sevseg.setNumber(timenumber);
sevseg.refreshDisplay();
}
}
И пример кода JChristensen:
// Библиотека Arduino DS3232RTC
// https://github.com/JChristensen/DS3232RTC
// Copyright (C) 2018 Джек Кристенсен и под лицензией
// GNU GPL v3.0, https://www.gnu.org/licenses/gpl.html
//
// Пример скетча для отображения даты и времени с DS3231
// или DS3232 RTC каждую секунду. Отображение температуры один раз в
// минута. (DS3231 выполняет преобразование температуры один раз в
// 64 секунды. Это также значение по умолчанию для DS3232.)
//
// Установите дату и время, введя следующее на Arduino
// серийный монитор:
// год, месяц, день, час, минута, секунда,
//
// Где
// год может состоять из двух или четырех цифр,
// месяц 1-12,
// день 1-31,
// час 0-23, и
// минуты и секунды 0-59.
//
// Ввод последней запятой (после "секунды") позволит избежать
// тайм-аут в одну секунду и позволит более точно установить RTC.
//
// Проверка правильности не выполняется, недопустимые значения или неполный синтаксис
// на входе приведет к неправильной настройке RTC.
//
// Джек Кристенсен, 08 августа 2013 г.
#include <DS3232RTC.h> // https://github.com/JChristensen/DS3232RTC
#include <Streaming.h> // http://arduiniana.org/libraries/streaming/
void setup()
{
Serial.begin(115200);
// setSyncProvider() заставляет библиотеку времени синхронизироваться с
// внешний RTC, вызывая RTC.get() каждые пять минут по умолчанию.
setSyncProvider(RTC.get);
Serial << F("RTC Sync");
if (timeStatus() != timeSet) Serial << F(" FAIL!");
Serial << endl;
}
void loop()
{
static time_t tLast;
time_t t;
tmElements_t tm;
// проверка ввода для установки RTC, минимальная длина 12, т.е. yy,m,d,h,m,s
if (Serial.available() >= 12) {
// обратите внимание, что член tmElements_t Year является смещением от 1970,
// но RTC нужны две последние цифры календарного года.
// используйте удобные макросы из библиотеки времени для выполнения преобразований.
int y = Serial.parseInt();
if (y >= 100 && y < 1000)
Serial << F("Error: Year must be two digits or four digits!") << endl;
else {
if (y >= 1000)
tm.Year = CalendarYrToTm(y);
else // (у < 100)
tm.Year = y2kYearToTm(y);
tm.Month = Serial.parseInt();
tm.Day = Serial.parseInt();
tm.Hour = Serial.parseInt();
tm.Minute = Serial.parseInt();
tm.Second = Serial.parseInt();
t = makeTime(tm);
RTC.set(t); // используем значение time_t, чтобы убедиться, что установлен правильный день недели
setTime(t);
Serial << F("RTC set to: ");
printDateTime(t);
Serial << endl;
// сбрасываем любой посторонний ввод
while (Serial.available() > 0) Serial.read();
}
}
t = now();
if (t != tLast) {
tLast = t;
printDateTime(t);
if (second(t) == 0) {
float c = RTC.temperature() / 4.;
float f = c * 9. / 5. + 32.;
Serial << F(" ") << c << F(" C ") << f << F(" F");
}
Serial << endl;
}
}
// печать даты и времени в Serial
void printDateTime(time_t t)
{
printDate(t);
Serial << ' ';
printTime(t);
}
// вывод времени в Serial
void printTime(time_t t)
{
printI00(hour(t), ':');
printI00(minute(t), ':');
printI00(second(t), ' ');
}
// печать даты в Serial
void printDate(time_t t)
{
printI00(day(t), 0);
Serial << monthShortStr(month(t)) << _DEC(year(t));
}
// Вывести целое число в формате «00» (с ведущим нулем),
// за которым следует символ-разделитель для Serial.
// Предполагается, что входное значение находится в диапазоне от 0 до 99.
void printI00(int val, char delim)
{
if (val < 10) Serial << '0';
Serial << _DEC(val);
if (delim > 0) Serial << delim;
return;
}
@BobaJFET, 👍0
Обсуждение1 ответ
Лучший ответ:
Я разобрался. Вы должны сначала установить встроенный RTC Arduino, используя библиотеку времени, а затем установить DS3232 оттуда. Раньше это не работало для моего кода, потому что его нужно было вызывать вне функции настройки.
Например, я сделал функцию, которая корректирует часы:
void adjHr() { // функция корректировки часов
if(millis() >= time_now + period){
time_now += period;
time_now = millis();
setTime(hour()+1,minute(),second(),day(),month(),year());
RTC.set(now());
}
Моя функция настройки также включает в себя:
setSyncProvider(RTC.get);
Позволяет коду получать время от DS3232.
это не лучший способ, @Juraj
Это способ «а». Но если у вас есть лучший способ, поделитесь, и я отмечу ваш ответ как ответ, @BobaJFET
у вас есть лучший способ в рассматриваемом коде. tmElements_t, @Juraj
Я предполагаю, что вы имеете в виду использование последовательного монитора для установки времени. Это кажется очень простым способом сделать это, но мне еще предстоит понять это. На данный момент достаточно установить время с помощью моего альтернативного метода., @BobaJFET
это не имеет ничего общего с Serial. в примере значения считываются из Serial (читаются parseInt) и устанавливаются в структуру tmElements_t. но вы можете использовать переменные для установки элементов даты и времени. Затем функция makeTime из TimeLib вычисляет значение «эпохи» и устанавливает его в RTC. Кстати в вашем ответе будет проблема, потому что время работает в TimeLib, @Juraj
С какой проблемой он столкнется? Мои часы, кажется, работают просто отлично и держат время с резервной батареей., @BobaJFET
- Преобразование в Unix Timestamp и обратно
- Разница между «time_t» и «DateTime»
- Создание таймера с использованием часов реального времени с указанием времени начала и остановки
- DS1307RTC Выводит загадочную дату 165/165/2165. Какие возможны исправления?
- RtcDateTime' не называет тип
- Библиотека времени Arduino и библиотеки RTC
- Не удалось выделить SSD1306 при добавлении константы
- Как получить текущую дату
Можете ли вы немного отформатировать свой код? Так читать невозможно... С неправильными табами и множеством переводов строки. Ошибка такая:
if(millis()>6000)
. Это означает, что ваш цикл ничего не будет делать в течение 6 секунд, а затем он обновит дисплей настолько быстро, насколько это возможно... Если вы просто хотите обновить свои часы, вы можете делать это 1 раз в секунду с задержкой, а лучше обновить отображение только в том случае, если изменилось второе значение., @AdrianoВы понимаете, как примерный скетч задает время? Если да, то в чем именно заключается ваша проблема при его реализации?, @chrisl
Он устанавливается через последовательный монитор. Поэтому мне нужно сделать функцию для отправки ввода в серийный номер. Я еще не понял, как пример кода может это сделать, @BobaJFET