У меня есть модуль часов ds3231 и плата esp32. В интернете полно примеров когда начальное время устанавливается при компилировании скетча и загрузки в начальных данных в часы. Только ни где не нашел примеров синхронизации.
Пришла идея раз в месяц/год синхронизировать модуль с сетевым временем. Для этого запустил таймер, установил время срабатывания прерывания, повесил на него функцию.
Вот тут и засада.
Если в лупе висят строки получения времени и запись в модуль часов,(часть которая закоментирована) то все работает. Если эти же операции переношу в функцию , то происходит крах и перезапуск программы.
Может опытные расскажут в чем проблема?
//------библиотеки и переменные модуля часов ds3231------------------------------------------
#include "RTClib.h" //библиотека модуля часов ds3231
RTC_DS3231 rtc;
//-------------------------------------------------------------------------------------------
//-------------библиотеки и переменные для подключения по wi-fi и Синхронизация часов -------
#include <WiFi.h>
#include <NTPClient.h>
#include <WiFiUdp.h>
// Введите свои сетевые учетные данные в следующих переменных
const char* ssid = "**********"; // заменить на имя сети
const char* password = "**********";// заменить на пароль сети
/*
* по умолчанию подключается к серверу "pool.ntp.org",
* Задать другой сервер вы можете при инициализации клиента, передав его вторым параметром.
* NTPClient timeClient(ntpUDP, "europe.pool.ntp.org", 3600, 60000);
*/
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);
String formattedDate;
//-------------------------секция переменных для таймера синхронизации часов-----------------
hw_timer_t *My_timer = NULL; // Переменная-указатель с именем My_timer для настройки
//-------------------------секция переменных модуля наличия напряжения------------------------
const int motionSensor = 34;
volatile boolean flagpower = true; // флаг наличия сетевого напряжения
volatile uint32_t debounce=0; // максимальное число 4 294 967 295
//----------конец секции переменных и библиотек------------------------------------------------
void IRAM_ATTR detectsMovement() {
if (millis() - debounce >= 1000 && digitalRead(motionSensor))
{
Serial.println("Падение сетевого напряжения!!! это дребезг");
flagpower = true;
}
else if (digitalRead(motionSensor))
{
flagpower = false;
Serial.println("Падение сетевого напряжения!!! Окончательно");
}
else
{
flagpower = true;
Serial.println("Напряжение в норме!!!");
}
debounce = millis();
}
//--------------подпрограмма обработки прерывания таймера для синхронизации времни по wi-fi--------------
void IRAM_ATTR sinhrotime() {
while(!timeClient.update()) {// обновляем дату из сети, если не обновилась, то повторяем
timeClient.forceUpdate();
}
formattedDate = timeClient.getFormattedDate();// строка в виде 2018-04-30T16:00:13Z
rtc.adjust(formattedDate.c_str()); // преобразуем string в char для передачи в функцию adjust
}
//-------------------секция setup---------------------------------------------------------------------
void setup() {
// инициализируем порт
Serial.begin(115200);
//---------секция часов-----------------------------------------------------------------------
if (! rtc.begin()) {
Serial.println("Не найден модуль часов RTC 3231");
Serial.flush();
while (1) delay(10);
}
WiFi.begin(ssid, password); // подключанмся к сети
while (WiFi.status() != WL_CONNECTED) {
delay(500);
Serial.print(".");
}
timeClient.begin(); // запускаем получение времени из интернет
timeClient.setTimeOffset(10800); // сдвиг +3 часа для москвы
//---------------------------------------------------------------------------------------------------
/*Для инициализации таймера есть функция timerbegin ()
- Номер таймера, который мы хотим использовать (от 0...3),
- Значение предварительного делителя
- Флаг, указывающий, должен ли счетчик считать вверх true/false */
My_timer = timerBegin(0, 40, true);
timerAttachInterrupt(My_timer, &sinhrotime, true);// прерывание будут запускать функцию sinhtime
timerAlarmWrite(My_timer, 60000000, true); // делитель устанавливающий на сутки.clock.setDateTime(t2); сейчас 30 секунд
timerAlarmEnable(My_timer);// включаем таймер
//---------------------------------------------------------------------------------------------------
pinMode(motionSensor, INPUT);
attachInterrupt(digitalPinToInterrupt(motionSensor), detectsMovement, FALLING);
}
void loop() {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(' ');
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.println(now.second(), DEC);
// while(!timeClient.update()) {
// timeClient.forceUpdate();// условие не должно быть больше 5 раз переделать!!!! иначе при отсутствии сети зависнет
// }
// formattedDate = timeClient.getFormattedDate();// строка в виде 2018-04-30T16:00:13Z
// Serial.println(formattedDate);
// rtc.adjust(formattedDate.c_str()); // преобразуем string в char для передачи в функцию adjust
// Serial.println(formattedDate.c_str());
//
delay(1000);
}