Крутые часы на адресных диодах

Введение

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

Вот здесь и будет удобно использование микросхемы 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.
Выбор частоты прямоугольных импульсов и уровня на выводе SQW/OUT микросхемы DS1307
RS1 RS0 Частота импульсов и уровень на выходе SQW/OUT SQWE OUT
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 Гц.

Заказ изготовления печатной платы

После окончания работы по проектированию печатной платы вы можете заказать ее изготовление на сайте JLCPCB.com. Для осуществления этого вам будет необходим Gerber файл печатной платы, для этого можно в редакторе EasyEDA нажать кнопку Fabrication Output (заказа изготовления) и затем подгрузить этот файл на странице заказа печатной платы.

При заказе печатной платы на сайте JLCPCB.com необходимо нажать на кнопку Quote Now или Buy Now, выбрать количество экземпляров печатной платы, число слоев меди, толщину печатной платы, вес меди и даже цвет печатной платы как показано на рисунке.

После выбора всех необходимых опций печатной платы необходимо нажать кнопку “Save to Cart” и тогда вас перебросит на страницу, где вы можете загрузить Gerber файл, который мы скачали с EasyEDA. Загрузите ваш Gerber файл и нажмите на “Save to Cart”. В завершение нажмите Checkout Securely чтобы завершить оформление заказа. В нашем случае стоимость изготовления печатной платы составила $2, сделали ее за 48 часов и доставили службой доставки DHL за 5 дней.

В результате печатная плата к нам пришла вот в такой вот коробке:

Внутри нее была наша печатная плата, к которой мы припаяли необходимые компоненты, потом загрузили программу в плату Arduino и, таким образом, завершили изготовление проекта.

Модуль 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В;

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

  • SQ – 1 МГц;
  • 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() и из нее уже вытаскивать необходимые показания.

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

  • компьютер с установленной Arduino IDE;
  • плата Arduino;
  • микросхема DS1307 или модуль RTC на ее основе;
  • перемычки;
  • макетная плата;
  • комплектующие из списка элементов.

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

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

Шаг 5: Корпус для умных часов

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

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

Напечатанный 3D-корпус нуждался в некотором «лечении»:

  1. Отшлифуйте корпус мелкой наждачной бумагой.
  2. Нанесите наполнитель из распылителя, убедитесь, что он хорошо покрывает корпус.
  3. Отшлифуйте корпус с помощью мелкой наждачной бумаги снова.
  4. Нанесите краску из распылителя, убедитесь, что она хорошо покрывает корпус. Следуйте инструкциям на баллончиках для достижения наилучших результатов.

Шаг 3 и 4, возможно, потребуется повторять до тех пор, пока не будет достигнута ровная поверхность. Мы повторили эти шаги три раза.

Как подключить нескольких устройств по I2C Arduino

В следующем примере к шине IIC Arduino будет подключено сразу три устройства — текстовый дисплей 1602, датчик давления bmp180 и RTC модуль часов. После сборки схемы можно сделать предварительное сканирование шины, но адреса у всех устройств разные и изменить адрес можно только у дисплея. У других устройств адреса «вшиты» производителем и используются в библиотеках по умолчанию.

Скетч. Подключение нескольких устройств к шине i2c

I2C интерфейс: подключение нескольких устройств

После сборки схемы, убедитесь, что у вас установлены необходимые библиотеки для работы с устройствами по IIC протоколу, и загрузите следующий пример кода в микроконтроллер. Данная программа будет выводить на текстовый экран текущую дату и время суток (устанавливаются в процедуре void setup и время можно поменять), а также данные о температуре воздуха и атмосферном давлении.

#include <Wire.h>  // подключаем библиотеку для интерфейса I2C 

#include <LiquidCrystal_I2C.h>  // подключаем библиотеку для 1602
LiquidCrystal_I2C LCD(0x27, 16, 2);  // создаем объект LCD

#include <SFE_BMP180.h>  // подключаем библиотеку для bmp180
SFE_BMP180 pressure;  // создаем объект pressure

#include <iarduino_RTC.h>  // подключаем библиотеку для часов
iarduino_RTC time(RTC_DS1307);  // создаем объект time

void setup() {
  LCD.init();  // инициализация дисплея
  LCD.backlight();  // включение подсветки

  pressure.begin();  // запускаем датчик давления

  time.begin();  // запускаем модуль часов
  time.settime(0, 30, 16, 1, 4, 21, 5);  // сек, мин, часы, дата, мес, год, день недели
}

void loop() {
  char status;
  double T, P, p0, a;

  // если прошла 1 секунда обновляем информацию
  if (millis() % 1000 == 0) {

    // выводим время с секундами и дату (день, месяц)
    LCD.setCursor(0, 0);
    LCD.print(time.gettime("H:i:s - d.m"));

    // узнаем температуру и выводим на дисплей
    status = pressure.startTemperature();
    if (status != 0) {
      delay(status);
      status = pressure.getTemperature(T);
      if (status != 0) {
        LCD.setCursor(0, 1);
        LCD.print("T:");
        LCD.print(T, 2);

        // узнаем давление и выводим на дисплей
        status = pressure.startPressure(3);
        if (status != 0) {
          delay(status);
          status = pressure.getPressure(P, T);
          if (status != 0) {
            p0 = pressure.sealevel(P, 1655.0);
            LCD.print(" D:");
            LCD.print(p0, 2);

          }
          else { LCD.setCursor(0, 1); LCD.print("error retrieving pressure"); }
        }
        else { LCD.setCursor(0, 1); LCD.print("error starting pressure"); }
      }
      else { LCD.setCursor(0, 1); LCD.print("error retrieving temperature"); }
    }
    else { LCD.setCursor(0, 1); LCD.print("error starting temperature"); }
  }

}

Пояснения к коду:

  1. обновление информации на текстовом экране происходит каждую секунду, данный интервал можно увеличить по своему желанию;
  2. время выводится с секундами, формат вывода времени и даты также можно изменить в строчке

Элементы платы

Дисплей

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

Экран выполнен на жидкокристаллической матрице, которая отображает 2 строки по 16 символов. Каждый символ состоит из отдельного знакоместа 5×8 пикселей.

Контроллер дисплея

Матрица индикатора подключена к встроенному чипу КБ1013ВГ6 с драйвером расширителя портов, которые выполняют роль посредника между экраном и микроконтроллером.

Контроллер КБ1013ВГ6 аналогичен популярным чипам зарубежных производителей HD44780 и KS0066, что означает совместимость со всеми программными библиотеками.

Контакты подключения

На плате дисплея выведено 16 контактов для подведения питания и взаимодействия с управляющей электроникой.

Вывод Обозначение Описание
1 GND Общий вывод (земля)
2 VCC Напряжение питания (5 В)
3 VO Управление контрастностью
4 RS Выбор регистра
5 R/W Выбор режима записи или чтения
6 E Разрешение обращений к индикатору (а также строб данных)
7 DB0 Шина данных (8-ми битный режим)(младший бит в 8-ми битном режиме)
8 DB1 Шина данных (8-ми битный режим)
9 DB2 Шина данных (8-ми битный режим)
10 DB3 Шина данных (8-ми битный режим)
11 DB4 Шина данных (8-ми и 4-х битные режимы)(младший бит в 4-х битном режиме)
12 DB5 Шина данных (8-ми и 4-х битные режимы)
13 DB6 Шина данных (8-ми и 4-х битные режимы)
14 DB7 Шина данных (8-ми и 4-х битные режимы)
15 LED+ Питания подсветки (+)
16 LED– Питания подсветки (–)

Обратите внимания, что физические контакты подсветки экрана и расположены не в порядком соотношении с другими пинами экрана.

Питание

Экран совместим со всеми контроллерами с логическим напряжением от 3,3 до 5 вольт. Но для питания самого индикатора (пин VCC) необходимо строго 5 вольт

Если в вашем проекте нет линии 5 вольт, обратите внимание на дисплей текстовый экран 16×2 / I²C / 3,3 В.

Интерфейс передачи данных

Дисплей может работать в двух режимах:

  • 8-битный режим — в нём используются и младшие и старшие биты (-)
  • 4-битный режим — в нём используются только младшие биты (-)

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

Другие полезные функции библиотеки LiquidCrystal

Есть несколько полезных функций, которые вы можете использовать с объектом LiquidCrystal. Немногие из них перечислены ниже:

  • Если вы просто хотите расположить курсор в верхнем левом углу дисплея без очистки дисплея, используйте home().
  • Существует много приложений, таких как turbo C++ или notepad ++, в которых нажатие клавиши «insert» на клавиатуре меняет курсор. Точно так же вы можете изменить курсор на ЖК-дисплее с помощью blink() или lcd.Cursor().
  • Функция blink() отображает мигающий блок размером 5 × 8 пикселей, а lcd.Cursor() подчеркивание (линия) на позиции, в которую будет записан следующий символ.
  • Вы можете использовать функцию noblink(), чтобы отключить мигающий курсор на дисплее и lcd.noCursor() чтобы скрыть курсор.
  • Вы можете прокрутить содержимое дисплея на один пробел вправо, используя lcd.scrollDisplayRight() или один пробел влево используя lcd.scrollDisplayLeft(). Если вы хотите непрерывно прокручивать текст, вам нужно использовать эти функции внутри цикла for.

Код

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

Также не забываем, что мы в самом начале подключаем библиотеку LiquidCrystal, которую вы можете скачать в разделе Библиотеки на нашем сайте.

/*
 ###  Самые простые часы на Arduino UNO ###

 Для проекта часов нужны только жк-дисплей 16х2 LCD и 2 кнопки
 Никаких потенциометров для контраса, никаких резисторов 
 Функции кнопок:
 
 - короткое нажатие одной из кнопок включает подсветку на 30 с
 
 Настройка времени
 - Нажмите H для увеличения Часов
 - Нажмите M для увеличения Минут и сброса секунд
*/

#include "LiquidCrystal.h"

// Определяем соединение ЖК-дисплея с цифровыми контактами
const int rs = 2, en = 3, d4 = 4, d5 = 5, d6 = 6, d7 = 7;
LiquidCrystal lcd(rs, en, d4, d5, d6, d7);

// Настройка контрастности ЖК
int cs=9;// пин 9 для контраста ШИМ
const int contrast = 100;// контраст по умолчанию

// Начальное отображение времени 12:59:45 PM
int h=12;
int m=59;
int s=45;
int flag=1; //PM

// Кнопки установки времени
int button1;
int button2;

// Определение пинов для Кнопок установки времени
int hs=0;// pin 0 для настройки Часов
int ms=1;// pin 1 для настройки Минут

// Тайм-аут подсветки 
const int Time_light=150;
int bl_TO=Time_light;// Тайм-аут подсветки
int bl=10; // Пин подсветки
const int backlight=120; // НЕ БОЛЕЕ 7mA !!!

// Для точного считывания времени используйте часы реального времени Arduino, а не только задержку delay()
static uint32_t last_time, now = 0; // RTC

void setup()
{
  lcd.begin(16,2);
  pinMode(hs,INPUT_PULLUP);// избегать внешних Pullup резисторов для кнопки 1
  pinMode(ms,INPUT_PULLUP);// и кнопки 2
  analogWrite(cs,contrast);// Настроить контрастность VO
  analogWrite(bl,backlight);// Включить подсветку 
  now=millis(); // читать начальное значение RTC  
}

void loop()
{ 
  lcd.begin(16,2);// каждую секунду
// Обновить ЖК-дисплей
// Вывести время TIME в Hour, Min, Sec + AM/PM (часы, минуты, секунды)
 lcd.setCursor(0,0);
 lcd.print("Time ");
 if(h<10)lcd.print("0");// всегда 2 цифры
 lcd.print(h);
 lcd.print(":");
 if(m<10)lcd.print("0");
 lcd.print(m);
 lcd.print(":");
 if(s<10)lcd.print("0");
 lcd.print(s);

 if(flag==0) lcd.print(" AM");
 if(flag==1) lcd.print(" PM");
 
 lcd.setCursor(0,1);// для Line 2
 lcd.print("Precision clock");

// улучшенная замена delay(1000) 
// гораздо лучшая точность, менее зависимая от времени выполнения цикла

for ( int i=0 ;i<5 ;i++)// сделать 5-кратный цикл 200 мс, для более быстрого ответа кнопок
{
  while ((now-last_time)<200) //задержка delay 200ms
  { 
    now=millis();
  }
 // внутренний цикл 200ms
 last_time=now; // готовим следующий цикл 

 // read Setting Buttons (читаем кнопки настройки)
 button1=digitalRead(hs);// Read Buttons
 button2=digitalRead(ms);

 //Время подсветки 
 bl_TO--;
 if(bl_TO==0)
 {
  analogWrite(bl,0);// ВЫКЛ подсветки
  bl_TO++;
 }
 
 // Нажмите что-либо, чтобы активировать подсветку 
 if(  ((button1==0)|(button2==0)) & (bl_TO==1)  )
 {
  bl_TO=Time_light;
  analogWrite(bl,backlight);
  // дождитесь отпускания кнопки
  while ((button1==0)|(button2==0))
  {
   button1=digitalRead(hs);// Read Buttons
   button2=digitalRead(ms);
  }
 }
 else
 // Поведение Кнопки 1 или Кнопки 2 пока подсветка ВКЛ 
 {
  if(button1==0){
   h=h+1;
   bl_TO=Time_light;
   analogWrite(bl,backlight);
  }

 if(button2==0){
  s=0;
  m=m+1;
  bl_TO=Time_light;
  analogWrite(bl,backlight);
  }

/* ---- управлять секундами, минутами, часами am / pm ----*/
 if(s==60){
  s=0;
  m=m+1;
 }
 if(m==60)
 {
  m=0;
  h=h+1;
 }
 if(h==13)
 {
  h=1;
  flag=flag+1;
  if(flag==2)flag=0;
 }

 if((button1==0)|(button2==0))// Обновить дисплей, если нажата кнопка
 {
  // Обновить ЖК
  // Вывести время TIME в часах, минутах, секундах + AM/PM
  lcd.setCursor(0,0);
  lcd.print("Time ");
  if(h<10)lcd.print("0");// всегда 2 цифры
  lcd.print(h);
  lcd.print(":");
  if(m<10)lcd.print("0");
  lcd.print(m);
  lcd.print(":");
  if(s<10)lcd.print("0");
  lcd.print(s);

  if(flag==0) lcd.print(" AM");
  if(flag==1) lcd.print(" PM");
 
  lcd.setCursor(0,1);// для Line 2
  lcd.print("Precision clock");
 }

 } // end if else
}// end for

// outer 1000ms loop (завершение цикла)
 s=s+1; //увеличение секунд
        
// ---- управлять секундами, минутами, часами + am/pm ----
 if(s==60){
  s=0;
  m=m+1;
 }
 if(m==60)
 {
  m=0;
  h=h+1;
 }
 if(h==13)
 {
  h=1;
  flag=flag+1;
  if(flag==2)flag=0;
 }  
// Loop end (конец цикла)
}

Что такое часы реального времени?

Часы реально времени — это… часы. Модуль работает от автономного питания — батарейки и продолжает вести отсчет времени, даже если на вашем проекте на Arduino пропало питание. Используя модуль реального времени, вы можете отслеживать время, даже если вы захотите внести изменения в ваш скетч и перепрограммировать микроконтроллер.

На большинстве микроконтроллеров, в том числе и Arduino, есть встроенный счетчик временни, который называется millis(). Есть и встроенные в чип таймеры, которые могут отслеживать более длительные промежутки времени (минуты или дни). Так зачем же вам отдельным модуль часов? Основная проблема в том, что millis() отслеживает время только с момента подачи питания на Arduino. То есть, как только вы отключили плату, таймер сбрасывается в 0. Вша Arduino не знает, что сейчас, например, четверг или 8-е марта. Все, чего вы можете добиться от встроенного счетчика — это «Прошло 14000 миллисекунд с момента последнего включения».

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

В некоторых проектах Arduino вам понадобится надежный контроль времени без прерываний. Именно в таких случаях используется внешний модуль часов реального времени. Чип, который используется в подобных часах, отслеживает года и даже знает сколько дней в месяце (единственно, что обычно не учитывается — это переход на летнее и зимнее время, так как подобные переводы разные в разных частях мира).

На рисунке ниже показана материнская плата компьютера с часами реального времени DS1387. В часах используется литиевая батарея, поэтому они разрослись в размерах.

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

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