Настройка функции времени с помощью библиотеки DS3232

rtc

Я пытаюсь установить время на моем 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;
}

, 👍0

Обсуждение

Можете ли вы немного отформатировать свой код? Так читать невозможно... С неправильными табами и множеством переводов строки. Ошибка такая: if(millis()>6000). Это означает, что ваш цикл ничего не будет делать в течение 6 секунд, а затем он обновит дисплей настолько быстро, насколько это возможно... Если вы просто хотите обновить свои часы, вы можете делать это 1 раз в секунду с задержкой, а лучше обновить отображение только в том случае, если изменилось второе значение., @Adriano

Вы понимаете, как примерный скетч задает время? Если да, то в чем именно заключается ваша проблема при его реализации?, @chrisl

Он устанавливается через последовательный монитор. Поэтому мне нужно сделать функцию для отправки ввода в серийный номер. Я еще не понял, как пример кода может это сделать, @BobaJFET


1 ответ


Лучший ответ:

0

Я разобрался. Вы должны сначала установить встроенный 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