Настройка модуля часов реального времени rtc для arduino

Подключение RTC часы реального времени DS1302, DS1307, DS3231 к Arduino

Для подключения RTC часов реального времени DS1302, DS1307, DS3231, была разработана универсальная библиотека.

Скачать библиотеку можно по ссылке : Универсальная библиотека для RTC DS1302, DS1307, DS3231 к Arduino

Подключение:

Подключение DS1307 к Arduino:

RTC DS1307Arduino UNO
GND GND
VCC +5V
SDA A4
SCL A5

Подключение DS1302 к Arduino:

RTC DS1302Arduino UNO
GND GND
VCC +5V
RST 10 (Можно изменить на другие в скетче)
CLK 13 (Можно изменить на другие в скетче)
DAT 12 (Можно изменить на другие в скетче)

Подключение DS3231 к Arduino:

RTC DS3231Arduino UNO
GND GND
VCC +5V
SDA A4
SCL A5

Программа:

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

Для DS1307:

time.begin(RTC_DS1307);

Для DS1302:

time.begin(RTC_DS1302,10,13,12);

Для DS3231:

time.begin(RTC_DS3231);

Пример установки текущего времени в RTC модуль (DS1307):

#include
iarduino_RTC time(RTC_DS1307);
void setup() { delay(300); Serial.begin(9600); time.begin(); time.settime(0,51,21,27,10,15,2); // 0 сек, 51 мин, 21 час, 27, октября, 2015 года, вторник
}
void loop(){ if(millis()%1000==0){ // если прошла 1 секунда Serial.println(time.gettime(“d-m-Y, H:i:s, D”)); // выводим время delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс }
}

Пример считывания текущего времени с RTC модуля (DS1307) и вывод в “Последовательный порт” :

#include
iarduino_RTC time(RTC_DS1307);
void setup() { delay(300); Serial.begin(9600); time.begin();
}
void loop(){ if(millis()%1000==0){ // если прошла 1 секунда Serial.println(time.gettime(“d-m-Y, H:i:s, D”)); // выводим время delay(1); // приостанавливаем на 1 мс, чтоб не выводить время несколько раз за 1мс }
}

Преимущества библиотеки:

– библиотека имеет внутренние функции аппаратной обработки протоколов передачи данных I2C и SPI, а следовательно не требует подключения дополнительных библиотек, но и не конфликтует с ними, если таковые всё же подключены.

– библиотека имеет внутренние функции программой обработки протокола передачи данных 3-Wire

– для инициализации модуля необходимо вызвать функцию begin с названием модуля.

– подключение модулей осуществляется к аппаратным выводам arduino используемой шины (за исключением 3-Wire)

– простота установки и чтения времени функциями settime и gettime

функция settime может устанавливать дату и время, как полностью, так и частично (например только минуты, или только день, и т.д.)

функция gettime работает как функция date в php, возвращая строку со временем, но если её вызвать без параметра, то функция ничего не вернёт, а время можно прочитать из переменных в виде чисел.

– библиотека расширяемая, то есть для того, чтоб она работала с новым модулем, нужно указать параметры этого модуля в уже существующих массивах файла RTC.h (тип шины, частота шины в кГц, режимы работы, адреса регистров и т.д.), как всё это сделать, описано в файле extension.txt

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

– при вызове функции begin, библиотека читает флаги регистров модуля и при необходимости устанавливает или сбрасывает их так, чтоб модуль мог работать от аккумуляторной батареи, а на программируемом выводе меандра (если таковой у модуля есть) установилась частота 1Гц, тогда этот вывод можно использовать в качестве внешнего посекундного прерывания.

– при работе с модулем DS1302 не нужны никакие резисторы на выводе GND (которые нужны для его работы с другими библиотеками этого модуля), это достигнуто тем, что для шины 3-Wire указана конкретная частота 10кГц, не зависимо от частоты CPU arduino.

– в библиотеке реализована еще одна не обязательная функция period, принимающая в качестве единственного аргумента – количество минут (от 1 до 255)

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

Функцию period достаточно вызвать один раз.

Подробное описание:

}// ОПИСАНИЯ ПАРАМЕТРОВ ФУНКЦИЙ:
//
// Подключение библиотеки:
// #include
// iarduino_RTC time(название модуля [, вывод SS/RST [, вывод CLK [, вывод DAT]]]);
// если модуль работает на шине I2C или SPI, то достаточно указать 1 параметр, например: iarduino_RTC time(RTC_DS3231);
// если модуль работает на шине SPI, а аппаратный вывод SS занят, то номер назначенного вывода SS для модуля указывается вторым параметром, например: iarduino_RTC time(RTC_DS1305,22);
// если модуль работает на трехпроводной шине, то указываются номера всех выводов, например: iarduino_RTC time(RTC_DS1302, 1, 2, 3); // RST, CLK, DAT
// // Для работы с модулями, в библиотеке реализованы 5 функции:
// инициировать модуль begin();
// указать время settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]);
// получить время gettime(“строка с параметрами”);
// мигать времем blinktime(0-не_мигать / 1-мигают_сек / 2-мигают_мин / 3-мигают_час / 4-мигают_дни / 5-мигают_мес / 6-мигает_год / 7-мигают_дни_недели / 8-мигает_полдень)
// разгрузить шину period (минуты);
// // Функция begin():
// функция инициирует модуль: проверяет регистры модуля, запускает генератор модуля и т.д.
// // Функция settime(секунды [, минуты [, часы [, день [, месяц [, год [, день недели]]]]]]):
// записывает время в модуль
// год указывается без учёта века, в формате 0-99
// часы указываются в 24-часовом формате, от 0 до 23
// день недели указывается в виде числа от 0-воскресенье до 6-суббота
// если предыдущий параметр надо оставить без изменений, то можно указать отрицательное или заведомо большее значение
// пример: settime(-1, 10); установит 10 минут, а секунды, часы и дату, оставит без изменений
// пример: settime(0, 5, 13); установит 13 часов, 5 минут, 0 секунд, а дату оставит без изменений
// пример: settime(-1, -1, -1, 1, 10, 15); установит дату 01.10.2015 , а время и день недели оставит без изменений
// // Функция gettime(“строка с параметрами”):
// функция получает и выводит строку заменяя описанные ниже символы на текущее время
// пример: gettime(“d-m-Y, H:i:s, D”); ответит строкой “01-10-2015, 14:00:05, Thu”
// пример: gettime(“s”); ответит строкой “05”
// указанные символы идентичны символам для функции date() в PHP
// s секунды от 00 до 59 (два знака)
// i минуты от 00 до 59 (два знака)
// h часы в 12-часовом формате от 01 до 12 (два знака)
// H часы в 24-часовом формате от 00 до 23 (два знака)
// d день месяца от 01 до 31 (два знака)
// w день недели от 0 до 6 (один знак: 0-воскресенье, 6-суббота)
// D день недели наименование от Mon до Sun (три знака: Mon Tue Wed Thu Fri Sat Sun)
// m месяц от 01 до 12 (два знака)
// M месяц наименование от Jan до Dec (три знака: Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec)
// Y год от 2000 до 2099 (четыре знака)
// y год от 00 до 99 (два знака)
// a полдень am или pm (два знака, в нижнем регистре)
// A полдень AM или PM (два знака, в верхнем регистре)
// строка не должна превышать 50 символов
// // если требуется получить время в виде цифр, то можно вызвать функцию gettime() без параметра, после чего получить время из переменных
// seconds секунды 0-59
// minutes минуты 0-59
// hours часы 1-12
// Hours часы 0-23
// midday полдень 0-1 (0-am, 1-pm)
// day день месяца 1-31
// weekday день недели 0-6 (0-воскресенье, 6-суббота)
// month месяц 1-12
// year год 0-99
// // Функция blinktime(параметр):
// указывает функции gettime мигать одним из параметров времени (заменять параметр пробелами)
// функция может быть полезна, для отображения на дисплее, устанавливаемого параметра времени
// функция получает один параметр в виде числа от 0 до 8
// 0 не мигать
// 1 мигают сек
// 2 мигают мин
// 3 мигают час
// 4 мигают дни
// 5 мигают мес
// 6 мигает год
// 7 мигают дни недели
// 8 мигает полдень
// // Функция period(минуты):
// устанавливает минимальный период обращения к модулю в минутах (от 0 до 255)
// функция может быть полезна, если шина сильно нагружена, на ней имеются несколько устройств
// period(10); период 10 минут, означает что каждые 10 минут к модулю может быть отправлен только 1 запрос на получение времени
// ответом на все остальные запросы будет результат последнего полученного от модуля времени + время прошедшее с этого запроса

Источник: https://lesson.iarduino.ru/page/podklyuchenie-rtc-chasy-realnogo-vremeni-ds1302-ds1307-ds3231-k-arduino

Обзор часов реального времени RTC DS1307 и подключение к Arduino – RobotChip

Автор: Сергей Мир · 24.11.2016

DS1307 это небольшой модуль, предназначенный для подсчета времени. Собранный на базе микросхемы DS1307ZN с реализацией питания от литиевой батарейки (LIR2032), что позволяет работать автономно в течение длительного времени. Также на модуле, установлена энергонезависимая память EEPROM объемом 32 Кбайт (AT24C32). Микросхема AT24C32 и DS1307ZN связаны обшей шиной интерфейсом I2C.

Технические параметры 

Напряжение питания: 5В
Рабочая температура: – 40℃ … + 85℃
Память: 56 байт (энергонезависимая)
Батарейка: LIR2032 (автоматическое определение источника питания)
Размеры: 28мм х 25мм х 8 мм
Интерфейса: I2C

Общие сведения

Использовании модуля DS1307 зачастую очень оправдано, например, когда данные считываются редко, интервалом более недели, использовать собственные ресурсы контроллера, неоправданно или невозможно. Обеспечивание бесперебойное питание, например платы Arduino, на длительный срок дорого, даже при использовании батареи.

Благодаря собственной памяти и автономностью, можно регистрировать события, (при автономном питании) например изменение температуры и так далее, данные сохраняются в памяти их можно считать из памяти модуля.

Так что модуль DS1307 часто используют, когда контроллерам Arduino необходимо знать точное время, для запуска какого то события и так далее.

На нижний стороне модуля, почти полностью занимает держатель батарейки.

Обмен данными с другими устройствами осуществляется по интерфейсу I2C с выводов SCL и SDA. Конденсаторы С1 и С2 необходимы для снижения помех по линию питания. Чтобы обеспечить надлежащего уровня сигналов SCL и SDA установлены резисторы R2 и R3 (подтянуты к питанию). Для проверки работоспособности модуля, на вывод 7 микросхему DS1307Z, подается сигнал SQ, прямоугольной формы с частотой 1 Гц.

Элементы R4, R5, R6, VD1 необходимы для подзарядку литиевой батарейки. Так же, на плате предусмотрено посадочное место (U1), для установки датчика температуры DS18B20 (при необходимости можно впаять его), считывать показания, можно с вывода DS, который подтянут к пиатнию, через резистор R1 сопротивлением 3.3 кОм. Принципиальную схему и назначение контактов можно посмотреть на рисунках ниже.

На плате расположено две группы контактов, шагом 2.54 мм, для удобного подключения к макетной плате, буду использовать штырьевые разъемы, их необходимо впаять.

Первая группа контактов:
  DS:     вывод DS18B20  (1-wire)
  SCL:   линия тактирования (Serial CLock)
  SDA:  линия данных (Serial Dфta)
  VCC:  «+» питание модуля
  GND: «-» питание модуля

Вторая группа контактов:
  SQ:    вход 1 МГц
  DS:    вывод DS18B20  (1-wire)
  SCL:  линия тактирования (Serial CLock)
  SDA: линия данных (Serial Dфta)
  VCC: «+» питание модуля
  GND:«-» питание модуля
  BAT:  

Подзарядка батареи
Как описывал ваше модуль может заряжать батарею, реализовано это, с помощью компонентов R4, R5, R6 и диода D1.

Но, данная схема имеет недостаток, через резистор R4 и R6 происходит разряд батареи (как подметил пользователь ALEXEY, совсем не большой).

Так как модуль потребляем незначительный ток, можно удалить цепь питания, для этого убираем R4, R5, R6 и VD1, вместо R6 поставим перемычку (после удаления компонентов, можно использовать обычную батарейку CR2032).

Подключение DS1307 к Arduino

Необходимые детали:
  Arduino UNO R3 x 1 шт.
  Провод DuPont, 2,54 мм, 20 см x 1 шт.
  Кабель USB 2.0 A-B x 1 шт.
  Часы реального времени RTC DS1307 x 1 шт.

Подключение:
Для подключения часы реального времени DS1307, необходимо впаять впаять штыревые разъемы в первую группу контактов.

Далее, подключаем провода SCL (DS1307) к выводу 4 (Arduino UNO) и SDA (DS1307) к выводу 5 (Arduino UNO), осталось подключить питания VCC к +5V и GND к GND.

Кстати, в различных платах Arduino вывода интерфейса I2C отличаются, назначение каждого можно посмотреть ниже.

Установка времени DS1307
Скачиваем и устанавливаем библиотеки «DS1307RTC» и «TimeLib» в среду разработки IDE Arduino (посмотрите в конец статьи). При первом включении необходимо запрограммировать время, откройте пример из библиотеки DS1307RTC «Файл» —> «Примеры» —> «DS1307RTC» —> «SetTime», или скопируйте код снизу.

Источник: http://blog.rchip.ru/obzor-chasov-realnogo-vremeni-ds1307/

Часы реального времени на RTC модулях Ардуино DS1302, DS1307, DS3231

Во многих проектах Ардуино требуется отслеживать и фиксировать время наступления тех или иных событий.

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

В этой статье мы поговорим о наиболее часто встречающихся модулях RTC DS1307, DS1302, DS3231, которые можно использовать с платой Arduino.

Модули часов реального времени в проектах Arduino

Модуль часов представляет собой небольшую плату, содержащей, как правило, одну из микросхем DS1307, DS1302, DS3231.Кроме этого, на плате практически можно найти механизм установки батарейки питания.

Такие платы часто  применяется для учета времени, даты, дня недели и других хронометрических параметров. Модули работают от автономного питания – батареек, аккумуляторов, и продолжают проводить отсчет, даже если на Ардуино отключилось питание.

Наиболее распространенными моделями часов являются DS1302, DS1307, DS3231. Они основаны на подключаемом к Arduino модуле RTC (часы реального времени).

Часы ведут отсчет в единицах, которые удобны обычному человеку – минуты, часы, дни недели и другие, в отличие от обычных счетчиков и тактовых генераторов, которые считывают «тики».

В Ардуино имеется специальная функция millis(), которая также может считывать различные временные интервалы. Но основным недостатком этой функции является сбрасывание в ноль при включении таймера.

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

Электронная схема включает в себя микросхему, источник питания, кварцевый резонатор и резисторы. Кварцевый резонатор работает на частоте 32768 Гц, которая является удобной для обычного двоичного счетчика. В схеме DS3231 имеется встроенный кварц и термостабилизация, которые позволяют получить значения высокой точности.

Сравнение популярных модулей RTC DS1302, DS1307, DS3231

В этой таблице мы привели список наиболее популярных модулей и их основные характеристики.

Название Частота Точность Поддерживаемые протоколы
DS1307 1 Гц, 4.096 кГц, 8.192 кГц, 32.768 кГц Зависит от кварца – обычно значение достигает 2,5 секунды в сутки, добиться точности выше 1 секунды в сутки невозможно. Также точность зависит от температуры. I2C
DS1302 32.768 кГц 5 секунд в сутки I2C, SPI
DS3231 Два выхода – первый на 32.768 кГц, второй – программируемый от 1 Гц до 8.192 кГц ±2 ppm при температурах от 0С до 40С.±3,5 ppm при температурах от -40С до 85С.Точность измерения температуры – ±3С I2C

Модуль DS1307

DS1307 – это модуль, который используется для отсчета времени. Он собран на основе микросхемы DS1307ZN, питание поступает от литиевой батарейки для реализации автономной работы в течение длительного промежутка времени.

Батарея на плате крепится на обратной стороне. На модуле имеется микросхема AT24C32 — это энергонезависимая память EEPROM на 32 Кбайт. Обе микросхемы связаны между собой шиной I2C.

DS1307 обладает низким энергопотреблением и содержит часы и календарь по 2100 год.

Модуль обладает следующими параметрами:

  • Питание – 5В;
  • Диапазон рабочих температур от -40С до 85С;
  • 56 байт памяти;
  • Литиевая батарейка LIR2032;
  • Реализует 12-ти и 24-х часовые режимы;
  • Поддержка интерфейса I2C.

Модуль оправдано использовать в случаях, когда данные считываются довольно редко, с интервалом в неделю и более. Это позволяет экономить на питании, так как при бесперебойном использовании придется больше тратить напряжения, даже при наличии батарейки. Наличие памяти позволяет регистрировать различные параметры (например, измерение температуры) и считывать полученную информацию из модуля.

Взаимодействие с другими устройствами и обмен с ними информацией производится с помощью интерфейса I2C с контактов SCL и SDA.

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

Контакты распределены в 2 группы, шаг 2,54 мм. В первой группе контактов находятся следующие выводы:

  • DS – вывод для датчика DS18B20;
  • SCL – линия тактирования;
  • SDA – линия данных;
  • VCC – 5В;
  • GND.

Во второй группе контактов находятся:

  • SQ – 1 МГц;
  • DS ;
  • SCL;
  • SDA;
  • VCC;
  • GND;
  • BAT – вход для литиевой батареи.

Для подключения к плате Ардуино нужны сама плата (в данном случае рассматривается Arduino Uno), модуль часов реального времени RTC DS1307, провода и USB кабель.

Чтобы подключить контроллер к Ардуино, используются 4 пина – VCC, земля, SCL, SDA.. VCC с часов подключается к 5В на Ардуино, земля с часов – к земле с Ардуино, SDA – А4, SCL – А5.

Для начала работы с модулем часов нужно установить библиотеки DS1307RTC, TimeLib и Wire. Можно использовать для работы и RTCLib.

Проверка RTC модуля

При запуске первого кода программа будет считывать данные с модуля раз в секунду.

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

Нужно подождать несколько секунд и вытащить батарею, в итоге часы перезагрузятся. Затем нужно выбрать пример в меню Examples→RTClib→ds1307. Важно правильно поставить скорость передачи на 57600 bps.

При открытии окна серийного монитора должны появиться следующие строки:

Будет показывать время 0:0:0. Это связано с тем, что в часах пропадает питание, и отсчет времени прекратится. По этой причине нельзя вытаскивать батарею во время работы модуля.

Чтобы провести настройку времени на модуле, нужно в скетче найти строку

RTC.adjust(DateTime(__DATE__, __TIME__));

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

Настройка произведена корректно и дополнительно перенастраивать часы реального времени не придется.

Считывание времени. Как только модуль настроен, можно отправлять запросы на получение времени. Для этого используется функция now(), возвращающая объект DateTime, который содержит информацию о времени и дате. Существует ряд библиотек, которые используются для считывания времени.

Например, RTC.year() и RTC.hour() – они отдельно получают информацию о годе и часе. При работе с ними может возникнуть проблема: например, запрос на вывод времени будет сделан в 1:19:59.

Прежде чем показать время 1:20:00, часы выведут время 1:19:00, то есть, по сути, будет потеряна одна минута. Поэтому эти библиотеки целесообразно использовать в случаях, когда считывание происходит нечасто – раз в несколько дней.

Существуют и другие функции для вызова времени, но  если нужно уменьшить или избежать погрешностей, лучше использовать now() и из нее уже вытаскивать необходимые показания.

Пример проекта с i2C модулем часов и дисплеем

Проект представляет собой обычные часы, на индикатор будет выведено точное время, а двоеточие между цифрами будет мигать с интервалом раз в одну секунду.

Для реализации проекта потребуются плата Arduino Uno, цифровой индикатор, часы реального времени (в данном случае вышеописанный модуль ds1307), шилд для подключения (в данном случае используется Troyka Shield), батарейка для часов и провода.

В проекте используется простой четырехразрядный индикатор на микросхеме TM1637. Устройство обладает двухпроводным интерфейсом и обеспечивает 8 уровней яркости монитора. Используется только для показа времени в формате часы:минуты.

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

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

Модуль часов подключается к контактам SCL/SDA, которые относятся к шине I2C. Также нужно подключить землю и питание. К Ардуино подключается так же, как описан выше: SDA – A4, SCL – A5, земля с модуля к земле с Ардуино, VCC -5V.

Индикатор подключается просто – выводы с него CLK и DIO подключаются к любым цифровым пинам на плате.

Скетч. Для написания кода используется функция setup, которая позволяет инициализировать часы и индикатор, записать время компиляции. Вывод времени на экран будет выполнен с помощью loop.

#include #include “TM1637.h” #include “DS1307.h” //нужно включить все необходимые библиотеки для работы с часами и дисплеем. char compileTime[] = __TIME__; //время компиляции. #define DISPLAY_CLK_PIN 10 #define DISPLAY_DIO_PIN 11 //номера с выходов Ардуино, к которым присоединяется экран; void setup() { display.set(); display.init(); //подключение и настройка экрана. clock.begin(); //включение часов. byte hour = getInt(compileTime, 0); byte minute = getInt(compileTime, 2); byte second = getInt(compileTime, 4); //получение времени. clock.fillByHMS(hour, minute, second); //подготовка для записывания в модуль времени. clock.setTime(); //происходит запись полученной информации во внутреннюю память, начало считывания времени. } void loop() { int8_t timeDisp[4]; //отображение на каждом из четырех разрядов. clock.getTime();//запрос на получение времени. timeDisp[0] = clock.hour / 10; timeDisp[1] = clock.hour % 10; timeDisp[2] = clock.minute / 10; timeDisp[3] = clock.minute % 10; //различные операции для получения десятков, единиц часов, минут и так далее. display.display(timeDisp); //вывод времени на индикатор display.point(clock.second % 2 ? POINT_ON : POINT_OFF);//включение и выключение двоеточия через секунду. } char getInt(const char* string, int startIndex) { return int(string[startIndex] – '0') * 10 + int(string[startIndex+1]) – '0'; //действия для корректной записи времени в двухзначное целое число. В ином случае на экране будет отображена просто пара символов. }

После этого скетч нужно загрузить и на мониторе будет показано время.

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

В функции setup каждый раз будет рассчитываться время, которое прошло с 00:00:00 до начала компиляции.

Этот хэш будет сравниваться с тем, что хранятся в EEPROM, которые сохраняются при отключении питания.

Для записи и чтения времени в энергонезависимую память или из нее нужно добавить функции EEPROMWriteInt и EEPROMReadInt. Они нужны для проверки совпадения/несовпадения хэша с хэшем, записанным в EEPROM.

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

В результате в коде нужно будет указать новую библиотеку (для жидкокристаллических экранов это LiquidCrystal), и добавить в функцию loop() строки для получения даты.

Алгоритм работы следующий:

  • Подключение всех компонентов;
  • Загрузка скетча;
  • Проверка – на экране монитора должны меняться ежесекундно время и дата. Если на экране указано неправильное время, нужно добавить в скетч функцию RTC.write (tmElements_t tm). Проблемы с неправильно указанным временем связаны с тем, что модуль часов сбрасывает дату и время на 00:00:00 01/01/2000 при выключении.
  • Функция write позволяет получить дату и время с компьютера, после чего на экране будут указаны верные параметры.

Заключение

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

С помощью широко распространенных и дешевых модулей вы можете создать такие проекты как будильник или регистратор данных с сенсоров, записывая информацию на SD-карту или показывая время на экране дисплея.

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

Источник: https://ArduinoMaster.ru/datchiki-arduino/arduino-chasy-rtc-ds1307-ds1302-ds3231/

Как использовать RTC (часы реального времени) с Arduino и LCD

В данной статье мы рассмотрим, как сделать точные часы на базе Arduino или AVR-микроконтроллера микросхемы часов реального времени DS1307. Время будет выводиться на LCD дисплей.

Что необходимо

Вы можете заменить плату Arduino на контроллер Atmel, но убедитесь, что у него достаточно входных и выходных выводов и есть аппаратная реализация интерфейса I2C. Я использую ATMega168A-PU. Если вы будете использовать отдельный микроконтроллер, то вам понадобится программатор, например, AVR MKII ISP.

Предполагается, что читатель знаком с макетированием, программированием в Arduino IDE и имеет некоторые знания языка программирования C. Обе программы, приведенные ниже, не нуждаются в дополнительном разъяснении.

Введение

Как микроконтроллеры отслеживают время и дату? Обычный микроконтроллер обладает функцией таймера, который стартует от нуля при подаче напряжения питания, а затем начинает считать.

В мире Arduino мы можем использовать функцию millis(), чтобы узнать, сколько прошло миллисекунд с того времени, когда было подано напряжение питания. Когда вы снимете и снова подадите питания, она начнет отсчет с самого начала.

Это не очень удобно, когда дело доходит до работы с часами и датами.

Вот здесь и будет удобно использование микросхемы RTC (Real Time Clock, часов реального времени). Эта микросхема с батарейкой 3В или каким-либо другим источником питания следит за временем и датой.

Часы/календарь обеспечивают информацию о секундах, минутах, часах, дне недели, дате, месяце и годе. Микросхема корректно работает с месяцами продолжительностью 30/31 день и с високосными годами.

Связь осуществляется через шину I2C (шина I2C в данной статье не обсуждается).

Если напряжение на главной шине питания Vcc падает ниже напряжения на батарее Vbat, RTC автоматически переключается в режим низкого энергопотребления от резервной батареи.

Резервная батарея – это обычно миниатюрная батарея (в виде «монетки», «таблетки») напряжением 3 вольта, подключенная между выводом 3 и корпусом.

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

В этом проекте мы будем использовать DS1307. У этой микросхемы вывод 7 является выводом SQW/OUT (выходом прямоугольных импульсов). Вы можете использовать этот вывод для мигания светодиодом и оповещения микроконтроллера о необходимости фиксации времени. Мы будем делать и то, и другое. Ниже приведено объяснение работы с выводом SQW/OUT.

Для управления работой вывода SQW/OUT используется регистр управления DS1307.

Ригистр управления DS1307Бит 7Бит 6Бит 5Бит 4Бит 3Бит 2Бит 1Бит 0
OUT SQWE RS1 RS0

Бит 7: управление выходом (OUT)Этот бит управляет выходным уровнем вывода SQW/OUT, когда выход прямоугольных импульсов выключен. Если SQWE = 0, логический уровень на выводе SQW/OUT равен 1, если OUT = 1, и 0, если OUT = 0. Первоначально обычно этот бит равен 0.Бит 4: включение прямоугольных импульсов (SQWE)Этот бит, когда установлен в логическую 1, включает выходной генератор. Частота прямоугольных импульсов зависит от значений битов RS0 и RS1. Когда частота прямоугольных импульсов настроена на значение 1 Гц, часовые регистры обновляются во время спада прямоугольного импульса. Первоначально обычно этот бит равен 0.Биты 1 и 0: выбор частоты (RS[1:0])Эти биты управляют частотой выходных прямоугольных импульсов, когда выход прямоугольных импульсов включен. Следующая таблица перечисляет частоты прямоугольных импульсов, которые могут быть выбраны с помощью данных битов. Первоначально обычно эти биты равны 1.

Выбор частоты прямоугольных импульсов и уровня на выводе SQW/OUT микросхемы DS1307RS1RS0Частота импульсов и уровень на выходе SQW/OUTSQWEOUT
1 Гц 1 x
1 4,096 кГц 1 x
1 8,192 кГц 1 x
1 1 32,768 кГц 1 x
x x
x x 1 1

 Данная таблица поможет вам с частотой:

Выбор частоты прямоугольных импульсов DS1307Частота импульсовБит 7Бит 6Бит 5Бит 4Бит 3Бит 2Бит 1Бит 0
1 Гц 1
4,096 кГц 1 1
8,192 кГц 1 1
32,768 кГц 1 1 1

Если вы подключили светодиод и резистор к выводу 7 и хотите, чтобы светодиод мигал с частотой 1 Гц, то должны записать в регистр управления значение 0b00010000.

Если вам нужны импульсы 4,096 кГц, то вы должны записать 0b000100001.

В этом случае, чтобы увидеть импульсы вам понадобится осциллограф, так как светодиод будет мигать так быстро, что будет казаться, что он светится постоянно. Мы будем использовать импульсы с частотой 1 Гц.

Аппаратная часть

Ниже показана структурная схема того, что нам необходимо.

Структурная схема часов на AVR микроконтроллере и RTC

Мы нужны:

  • разъем ISP (In System Programming, внутрисхемное программирование) для прошивки микроконтроллера;
  • кнопки для установки времени и даты;
  • микроконтроллер для связи с RTC через шину I2C;
  • дисплей для отображения даты и времени.

Принципиальная схема:

Часы на базе микроконтроллера AVR и RTC DS1307. Схема электрическая принципиальная

Перечень элементов

Ниже приведен скриншот из Eagle:

Часы на базе микроконтроллера AVR и RTC DS1307. Перечень элементов

Программное обеспечение

В этом руководстве мы будем использовать два различных скетча: один, который записывает время и дату в RTC, и один, который считывает время и дату из RTC. Мы сделали так потому, что так вы сможете получить более полное представление о том, что происходит. Мы будем использовать одну и ту же схему для обеих программ.

Сперва мы запишем время и дату в RTC, что аналогично установке времени на часах.

Мы используем две кнопки. Одну для увеличения часов, минут, даты, месяца, года и дня недели, а вторую для выбора между ними. Приложение не считывает состояния каких-либо критически важных датчиков, поэтому мы будем использовать прерывания для проверки, нажата ли кнопка, и обработки дребезга контактов.

Следующий код устанавливает значения и записывает их в RTC:

// Включение заголовочных файлов #include #include // Определение выводов LCD #define RS 9 #define E 10 #define D4 8 #define D5 7 #define D6 6 #define D7 5 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Прерывание 0 – это вывод 4 микроконтроллера (цифровой вывод 2 Arduino) int btnSet = 0; // Прерывание 1 – это вывод 5 микроконтроллера (цифровой вывод 3 Arduino) int btnSel = 1; // Флаги прерываний volatile int togBtnSet = false; volatile int togBtnSel = false; volatile int counterVal = 0; // Переменные для отслеживания, где в “меню” мы находимся volatile int menuCounter = 0; // Массив значений volatile int menuValues[6]; // 0=часы, 1=минуты, 2=день месяца, 3=месяц, 4=год, 5=день недели // Заголовки меню char* menuTitles[6] = { “Set hour. “, “Set minute. “, “Set date. “, “Set month. “, “Set year. “, “Set day (1=mon).” }; // Массив дней недели char* days[] = { “NA”, “Mon”, “Tue”, “Wed”, “Thu”, “Fre”, “Sat”, “Sun” }; void setup() { // Объявление прерываний, выполнение функций increaseValue/nextItem // по переднему фронту на btnXXX attachInterrupt(btnSet, increaseValue, RISING); attachInterrupt(btnSel, nextItem, RISING); Wire.begin(); lcd.begin(16,2); showWelcome(); } // Функция прерывания void increaseValue() { // Переменные static unsigned long lastInterruptTime = 0; // Создание метки времени unsigned long interruptTime = millis(); // Если timestamp – lastInterruptTime больше, чем 200 if (interruptTime – lastInterruptTime > 200) { togBtnSet = true; // Увеличить counterVal на 1 counterVal++; } // Установка lastInterruptTime равным метке времени // так мы знаем, что прошли дальше lastInterruptTime = interruptTime; } // Функция прерывания для следующего пункта меню void nextItem() { static unsigned long lastInterruptTime = 0; unsigned long interruptTime = millis(); if (interruptTime – lastInterruptTime > 200) { togBtnSel = true; // Увеличить счетчик меню, так мы переходим к следующему пункту меню menuCounter++; if (menuCounter > 6) menuCounter = 0; // Поместить counterVal в элемент массива счетчиков меню menuValues[menuCounter] = counterVal; // Сбросить counterVal, сейчас мы начинаем с 0 для следующего пункта меню counterVal = 0; } lastInterruptTime = interruptTime; } // Функция преобразования десятичных чисел в двоично-десятичный код byte decToBCD(byte val) { return ((val/10*16) + (val%10)); } // Функция проверки, была ли нажата кнопки листания меню, // и обновления заголовка на дисплее. void checkCurrentMenuItem() { if (togBtnSel) { togBtnSel = false; lcd.setCursor(0,0); lcd.print(menuTitles[menuCounter]); } } // Функция проверки, была ли нажата кнопка увеличения значения, // и обновления переменной в соответствующем элементе массива, // плюс вывод нового значения на дисплей. void checkAndUpdateValue() { // Проверить, если прерывание сработало = кнопка нажата if (togBtnSet) { // Обновить значение элемента массива с counterVal menuValues[menuCounter] = counterVal; // Сбросить флаг прерывания togBtnSet = false; lcd.setCursor(7,1); // Напечатать новое значение lcd.print(menuValues[menuCounter]); lcd.print(” “); } } // Короткое приветственное сообщение, теперь мы знаем, что всё нормально void showWelcome() { lcd.setCursor(2,0); lcd.print(“Hello world.”); lcd.setCursor(3,1); lcd.print(“I'm alive.”); delay(500); lcd.clear(); } // Запись данных в RTC void writeRTC() { Wire.beginTransmission(0x68); Wire.write(0); // начальный адрес Wire.write(0x00); // секунды Wire.write(decToBCD(menuValues[1])); // преобразовать минуты в BCD-код и записать Wire.write(decToBCD(menuValues[0])); // преобразовать часы в BCD-код и записать Wire.write(decToBCD(menuValues[5])); // преобразовать день недели в BCD-код и записать Wire.write(decToBCD(menuValues[2])); // преобразовать день месяца в BCD-код и записать Wire.write(decToBCD(menuValues[3])); // преобразовать месяц в BCD-код и записать Wire.write(decToBCD(menuValues[4])); // преобразовать год в BCD-код и записать Wire.write(0b00010000); // включить прямоугольные импульсы 1 Гц на выводе 7 Wire.endTransmission(); // закрыть передачу } // Показать время // Чтобы посмотреть, что RTC работает, вам необходимо посмотреть другую программу void showTime() { lcd.setCursor(0,0); lcd.print(” “); lcd.print(menuValues[0]); lcd.print(“:”); // часы lcd.print(menuValues[1]); lcd.print(“:”); lcd.print(“00 “); // минуты lcd.setCursor(3,1); lcd.print(days[menuValues[5]]); lcd.print(” “); // день недели lcd.print(menuValues[2]); lcd.print(“.”); // дата lcd.print(menuValues[3]); lcd.print(“.”); // месяц lcd.print(menuValues[4]); lcd.print(” “); // год // вызов функции writeRTC writeRTC(); } void loop() { if (menuCounter

Эта программа начинается с короткого приветственного сообщения. Это сообщение говорит нам, что подано питание, LCD работает, и что программа запустилась.

Так как скетч служит лишь для того, чтобы показать, как записать данные из Arduino в RTC DS1307, то в нем отсутствует вспомогательный функционал (проверка, попадают ли значения в допустимые диапазоны; зацикливание при нажимании на кнопку увеличения значения, то есть сброс на 0, когда значение, например, минут превысит 60, и т.д.)

// Включение заголовочных файлов #include #include // Определение выводов LCD #define RS 9 #define E 10 #define D4 8 #define D5 7 #define D6 6 #define D7 5 LiquidCrystal lcd(RS, E, D4, D5, D6, D7); // Вывод, который будет принимать импульсы от RTC volatile int clockPin = 0; // Переменные времени и даты byte second; byte minute; byte hour; byte day; byte date; byte month; byte year; // Массив дней недели char* days[] = { “NA”, “Mon”, “Tue”, “Wed”, “Thu”, “Fre”, “Sat”, “Sun” }; // Функция, которая выполняется только при запуске void setup() { pinMode(clockPin, INPUT); pinMode(clockPin, LOW); Wire.begin(); lcd.begin(16,2); showWelcome(); } // Короткое приветственное сообщение, теперь мы знаем, что всё нормально void showWelcome() { lcd.setCursor(2,0); lcd.print(“Hello world.”); lcd.setCursor(3,1); lcd.print(“I'm alive.”); delay(500); lcd.clear(); } byte bcdToDec(byte val) { return ((val/16*10) + (val%16)); } // Это выполняется постоянно void loop() { // Если уровень на выводе clockPin высокий if (digitalRead(clockPin)) { // Начать передачу I2C, адрес 0x68 Wire.beginTransmission(0x68); // Начать с адреса 0 Wire.write(0); // Закрыть передачу Wire.endTransmission(); // Начать чтение 7 двоичных данных от 0x68 Wire.requestFrom(0x68, 7); second = bcdToDec(Wire.read()); minute = bcdToDec(Wire.read()); hour = bcdToDec(Wire.read()); day = bcdToDec(Wire.read()); date = bcdToDec(Wire.read()); month = bcdToDec(Wire.read()); year = bcdToDec(Wire.read()); // Форматирование и отображение времени lcd.setCursor(4,0); if (hour

Заключение

В данной статье мы рассмотрели микросхему DS1307 от Maxim Integrated и написали две демонстрационные программы: одну для установки времени и даты и вторую для чтения времени и даты. Для проверки нажатия кнопок мы использовали прерывания, в которых также избавлялись от влияния дребезга контактов.

Фото и видео

Макет часов на микроконтроллере AVR и RTC DS1307Макет часов на микроконтроллере AVR и RTC DS1307

Установка времени

Считывание времени

Оригинал статьи:

  • Jens Christoffersen. How to Use RTC with Arduino and LCD

Arduino Uno

Отладочная плата Arduino Uno построена на микроконтроллере Atmega328P.

Она имеет 14 цифровых входных/выходных выводов (6 из которых могут использоваться в качестве ШИМ выходов), 6 аналоговых входов, кварцевый резонатор 16 МГц, подключение USB, разъем питания, разъем ICSP и кнопку перезагрузки. Она содержит всё необходимое для работы с микроконтроллером; для того, чтобы начать работу с ней, просто подключите…

Набор перемычек (папа-папа)

Набор перемычек папа-папа. 40 штук по 15 см.

RTC модуль DS1307 + EEPROM

Модуль часов реального времени (RTC) на базе микросхемы DS1307 с EEPROM. Данный модуль содержит в себе сразу две микросхемы: DS1307 (часы реального времени с интерфейсом I2C) и AT24C32 (микросхема памяти EEPROM на 32 килобита) Так же на плате выведен разъем для установки датчика DALLAS 18B20 (датчик в комплекте не идет).

Источник: https://radioprog.ru/post/126

Модуль RTC DS1307 подключение к Arduino

Опубликовано 04.07.2013 12:20:00

Модуль рассматриваемый в статье содержит в себе сразу две микросхемы: DS1307 (часы реального временис I2C- интерфейсом) и AT24C32 (микросхема памяти EEPROM на 32K bit).

В данной статье рассмотрим работу только микросхемы часов реального времени DS1307.

Компоненты для повторения (купить в Китае):

Arduino UNO, либо Arduino Nano, либо Arduino Mega

Модуль часов DS1307

Модуль часов DS3231

Соединительные провода (перемычки)

Основные технические характеристики:

• Подсчет реального времени в секундах, минутах, часах, датах месяца, месяцах, днях недели и годах с учетом высокосности текущего года вплоть до 2100 г.

• 56 байт энергонезависимого ОЗУ для хранения данных

• 2-х проводной последовательный интерфейс

• Программируемый генератор прямоугольных импульсов. Может выдавать 1 ГЦ, 4.096 кГЦ, 8,192 кГЦ и 32,768 кГц.

• Автоматическое определение отключения основного источника питания и подключение резервного

• 24-х часовой и 12-ти часовой режим

• Потребление не более 500 нA при питании от резервной батареи питания при температуре 25C°

Микросхема выпускается в восьмипиновых DIP и SOIC корпусах. Распиновка для всех одинакова. Далее приведу строки из даташита для полноты картины.

Документация на микросхему (datasheet)

Назначение выводов:

X1, X2 –  Служат для подключения 32.768 кГц кварцевого резонатора

Vbat – Вход для любой стандартной трёхвольтовой литиевой батареи или другого источника энергии. Для нормальной работы DS1307 необходимо, чтобы напряжение батареи было в диапазоне 2.0 … 3.5 В. Литиевая батарея с ёмкостью 48 мА/ч или более при отсутствии питания будет поддерживать DS1307 в
течение более 10 лет при температуре 25°C.

GND – общий минус

Vcc – Это вход +5 В. Когда питающее напряжение выше 1.25 * VBAT, устройство полностью,доступно, и можно выполнять чтение и запись данных.

Когда к устройству подключена батарея на 3 В, и Vcc ниже, чем 1.25 * VBAT, чтение и запись запрещены, однако функция отсчёта времени продолжает работать.

Как только Vcc падает ниже VBAT, ОЗУ и RTC переключаются на батарейное питание VBAT.

SQW/OUT – Выходной сигнал с прямоугольными импульсами.

SCL – (Serial Clock Input – вход последовательных синхроимпульсов) – используется для синхронизации данных по последовательному интерфейсу.

SDA – (Serial Data Input/Output – вход/выход последовательных данных) – вывод входа/выхода для двухпроводного последовательного интерфейса. 

Работа с выводом SQW/OUT

Для начала рассмотрим структуру регистров DS1307.

Структура регистров микросхемы DS1307

Нас интересует “Управляющий регистр” находящийся по адресу 0x7, т.к. он определяет работу вывода SQW/OUT.

Если бит SQWE = 1. то начинается формирование прямоугольных импульсов, если SQWE = 0, то на выходе вывода будет значение бита OUT.

За частоту импульсов отвечают биты RS0 и RS1, а именно:

     RS0          RS1          Частота     
     0      0      1 Гц
     0      1      4.096 кГц
     1      0      8.192 кГц
     1      1      32.768 кГц

Приведем пример:

Если нам нужно начать формирование прямоугольных импульсов с частотой 1  Гц, то необходимо в 0x7 регистр микросхемы, которая имеет адрес 0x68 отправить байт 00010000 или 0x10 в шестнадцатиричной системе счисления.

При помощи библиотеки Wire.h, это можно сделать следующим образом:

Wire.beginTransmission(0x68);
Wire.write(0x7);
Wire.write(0x10);
Wire.endTransmission();

 

Подключение к Arduino:

Выводы отвечающие за интерфейс I2C на платах Arduino на базе различных контроллеров разнятся.

 RTC модуль  На базе ATmega 328  Leonardo  MEGA, ADK, DUE
 SCL  A5  D3  D21
SDA  A4  D2  D20
 VCC  +5V  +5V  +5V
 GND  GND  GND  GND

Необходимые библиотеки:

для работы с DS1307: http://www.pjrc.com/teensy/td_libs_DS1307RTC.html
для работы со временем: http://www.pjrc.com/teensy/td_libs_Time.html

Установка времении

 

• Вручную в коде

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

#include 
#include  void setup() {
  Serial.begin(9600);
  while (!Serial) ; // Только для платы Leonardo
  setSyncProvider(RTC.get); // получаем время с RTC
  if (timeStatus() != timeSet)
    Serial.println(“Unable to sync with the RTC”); //синхронизация не удаласть
  else
    Serial.println(“RTC has set the system time”);
  //установим вручную 16.02.2016 12:53
  TimeElements te;
  te.Second = 0; //секунды
  te.Minute = 53; //минуты
  te.Hour = 12; //часы
  te.Day = 16; //день
  te.Month = 2; // месяц
  te.Year = 2016 – 1970; //год в библиотеке отсчитывается с 1970
  time_t timeVal = makeTime(te);
  RTC.set(timeVal);
  setTime(timeVal);
} void loop()
{
  digitalClockDisplay(); //вывод времени
  delay(1000);
} void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(” “);
  Serial.print(day());
  Serial.print(” “);
  Serial.print(month());
  Serial.print(” “);
  Serial.print(year());
  Serial.println();
} void printDigits(int digits) {
  //выводим время через “:”
  Serial.print(“:”);
  if (digits Serial.print('0');
  Serial.print(digits);
}

• Установкой из  “Монитора порта”

Более точный вариант установки времени. Время задается через “монитор порта” по ходу работы контроллера.

Открываем монитор, вводим данные в нужном формате, смотрим на эталонные часы, подлавливаем момент и шелкаем “отправить”.

//формат указания текущего времени “ДД.ММ.ГГ чч:мм:сс”
//где ДД – день, ММ – месяц, ГГ – год, чч – часы, мм – минуты, сс – секунлы
//ГГ – от 00 до 99 для 2000-2099 годов #include 
#include  bool isTimeSet = false; //флаг, указывающий на то, была ли уже задана дата void setup() {
  Serial.begin(9600);
  while (!Serial) ; // Только для платы Leonardo
  setSyncProvider(RTC.get); // получаем время с RTC
  if (timeStatus() != timeSet)
    Serial.println(“Unable to sync with the RTC”); //синхронизация не удаласть
  else
    Serial.println(“RTC has set the system time”);
} void loop()
{
  if (Serial.available()) { //поступила команда с временем
      setTimeFromFormatString(Serial.readStringUntil('
'));
      isTimeSet = true; //дата была задана
  }
  if (isTimeSet) //если была задана дата
  {
    digitalClockDisplay(); //вывод времени
  }
  delay(1000);
} void digitalClockDisplay() {
  Serial.print(hour());
  printDigits(minute());
  printDigits(second());
  Serial.print(” “);
  Serial.print(day());
  Serial.print(” “);
  Serial.print(month());
  Serial.print(” “);
  Serial.print(year());
  Serial.println();
} void printDigits(int digits) {
  //выводим время через “:”
  Serial.print(“:”);
  if (digits Serial.print('0');
  Serial.print(digits);
} void setTimeFromFormatString(String time)
{
  //ДД.ММ.ГГ чч:мм:сс
  int day = time.substring(0, 2).toInt();
  int month = time.substring(3, 5).toInt();
  int year = time.substring(6, 8).toInt();
  int hours = time.substring(9, 11).toInt();
  int minutes = time.substring(12, 14).toInt();
  int seconds = time.substring(15, 17).toInt();
  TimeElements te;
  te.Second = seconds;
  te.Minute = minutes;
  te.Hour = hours;
  te.Day = day;
  te.Month = month;
  te.Year = year + 30; //год в библиотеке отсчитывается с 1970. Мы хотим с 2000
  time_t timeVal = makeTime(te);
  RTC.set(timeVal);
  setTime(timeVal);
}

 

Статьи в похожей тематике:

• Модуль часов реального времени на микросхеме DS1307 своими руками

Купить в России  Модуль RTC (DS1307) + EEPROM (AT24C32)

В данный момент еще реализованы не все элементы нашего сообщества. Мы активно работаем над ним и в ближайшее время возможность комментирования статей будет добавлена.

Источник: http://zelectro.cc/RTC_DS1307_arduino

Ссылка на основную публикацию
Adblock
detector
",css:{backgroundColor:"#000",opacity:.6}},container:{block:void 0,tpl:"
"},wrap:void 0,body:void 0,errors:{tpl:"
",autoclose_delay:2e3,ajax_unsuccessful_load:"Error"},openEffect:{type:"fade",speed:400},closeEffect:{type:"fade",speed:400},beforeOpen:n.noop,afterOpen:n.noop,beforeClose:n.noop,afterClose:n.noop,afterLoading:n.noop,afterLoadingOnShow:n.noop,errorLoading:n.noop},o=0,p=n([]),h={isEventOut:function(a,b){var c=!0;return n(a).each(function(){n(b.target).get(0)==n(this).get(0)&&(c=!1),0==n(b.target).closest("HTML",n(this).get(0)).length&&(c=!1)}),c}},q={getParentEl:function(a){var b=n(a);return b.data("arcticmodal")?b:(b=n(a).closest(".arcticmodal-container").data("arcticmodalParentEl"),!!b&&b)},transition:function(a,b,c,d){switch(d=null==d?n.noop:d,c.type){case"fade":"show"==b?a.fadeIn(c.speed,d):a.fadeOut(c.speed,d);break;case"none":"show"==b?a.show():a.hide(),d();}},prepare_body:function(a,b){n(".arcticmodal-close",a.body).unbind("click.arcticmodal").bind("click.arcticmodal",function(){return b.arcticmodal("close"),!1})},init_el:function(d,a){var b=d.data("arcticmodal");if(!b){if(b=a,o++,b.modalID=o,b.overlay.block=n(b.overlay.tpl),b.overlay.block.css(b.overlay.css),b.container.block=n(b.container.tpl),b.body=n(".arcticmodal-container_i2",b.container.block),a.clone?b.body.html(d.clone(!0)):(d.before("
"),b.body.html(d)),q.prepare_body(b,d),b.closeOnOverlayClick&&b.overlay.block.add(b.container.block).click(function(a){h.isEventOut(n(">*",b.body),a)&&d.arcticmodal("close")}),b.container.block.data("arcticmodalParentEl",d),d.data("arcticmodal",b),p=n.merge(p,d),n.proxy(e.show,d)(),"html"==b.type)return d;if(null!=b.ajax.beforeSend){var c=b.ajax.beforeSend;delete b.ajax.beforeSend}if(null!=b.ajax.success){var f=b.ajax.success;delete b.ajax.success}if(null!=b.ajax.error){var g=b.ajax.error;delete b.ajax.error}var j=n.extend(!0,{url:b.url,beforeSend:function(){null==c?b.body.html("
"):c(b,d)},success:function(c){d.trigger("afterLoading"),b.afterLoading(b,d,c),null==f?b.body.html(c):f(b,d,c),q.prepare_body(b,d),d.trigger("afterLoadingOnShow"),b.afterLoadingOnShow(b,d,c)},error:function(){d.trigger("errorLoading"),b.errorLoading(b,d),null==g?(b.body.html(b.errors.tpl),n(".arcticmodal-error",b.body).html(b.errors.ajax_unsuccessful_load),n(".arcticmodal-close",b.body).click(function(){return d.arcticmodal("close"),!1}),b.errors.autoclose_delay&&setTimeout(function(){d.arcticmodal("close")},b.errors.autoclose_delay)):g(b,d)}},b.ajax);b.ajax_request=n.ajax(j),d.data("arcticmodal",b)}},init:function(b){if(b=n.extend(!0,{},a,b),!n.isFunction(this))return this.each(function(){q.init_el(n(this),n.extend(!0,{},b))});if(null==b)return void n.error("jquery.arcticmodal: Uncorrect parameters");if(""==b.type)return void n.error("jquery.arcticmodal: Don't set parameter \"type\"");switch(b.type){case"html":if(""==b.content)return void n.error("jquery.arcticmodal: Don't set parameter \"content\"");var e=b.content;return b.content="",q.init_el(n(e),b);case"ajax":return""==b.url?void n.error("jquery.arcticmodal: Don't set parameter \"url\""):q.init_el(n("
"),b);}}},e={show:function(){var a=q.getParentEl(this);if(!1===a)return void n.error("jquery.arcticmodal: Uncorrect call");var b=a.data("arcticmodal");if(b.overlay.block.hide(),b.container.block.hide(),n("BODY").append(b.overlay.block),n("BODY").append(b.container.block),b.beforeOpen(b,a),a.trigger("beforeOpen"),"hidden"!=b.wrap.css("overflow")){b.wrap.data("arcticmodalOverflow",b.wrap.css("overflow"));var c=b.wrap.outerWidth(!0);b.wrap.css("overflow","hidden");var d=b.wrap.outerWidth(!0);d!=c&&b.wrap.css("marginRight",d-c+"px")}return p.not(a).each(function(){var a=n(this).data("arcticmodal");a.overlay.block.hide()}),q.transition(b.overlay.block,"show",1*")),b.overlay.block.remove(),b.container.block.remove(),a.data("arcticmodal",null),n(".arcticmodal-container").length||(b.wrap.data("arcticmodalOverflow")&&b.wrap.css("overflow",b.wrap.data("arcticmodalOverflow")),b.wrap.css("marginRight",0))}),"ajax"==b.type&&b.ajax_request.abort(),p=p.not(a))})},setDefault:function(b){n.extend(!0,a,b)}};n(function(){a.wrap=n(document.all&&!document.querySelector?"html":"body")}),n(document).bind("keyup.arcticmodal",function(d){var a=p.last();if(a.length){var b=a.data("arcticmodal");b.closeOnEsc&&27===d.keyCode&&a.arcticmodal("close")}}),n.arcticmodal=n.fn.arcticmodal=function(a){return e[a]?e[a].apply(this,Array.prototype.slice.call(arguments,1)):"object"!=typeof a&&a?void n.error("jquery.arcticmodal: Method "+a+" does not exist"):q.init.apply(this,arguments)}}(jQuery)}var debugMode="undefined"!=typeof debugFlatPM&&debugFlatPM,duplicateMode="undefined"!=typeof duplicateFlatPM&&duplicateFlatPM,countMode="undefined"!=typeof countFlatPM&&countFlatPM;document["wri"+"te"]=function(a){let b=document.createElement("div");jQuery(document.currentScript).after(b),flatPM_setHTML(b,a),jQuery(b).contents().unwrap()};function flatPM_sticky(c,d,e=0){function f(){if(null==a){let b=getComputedStyle(g,""),c="";for(let a=0;a=b.top-h?b.top-h{const d=c.split("=");return d[0]===a?decodeURIComponent(d[1]):b},""),c=""==b?void 0:b;return c}function flatPM_testCookie(){let a="test_56445";try{return localStorage.setItem(a,a),localStorage.removeItem(a),!0}catch(a){return!1}}function flatPM_grep(a,b,c){return jQuery.grep(a,(a,d)=>c?d==b:0==(d+1)%b)}function flatPM_random(a,b){return Math.floor(Math.random()*(b-a+1))+a}