Часы реального времени ds1307 и arduino

Подключение и настройка

Часы реального времени общаются с управляющей электроникой по протоколу I²C / TWI. Для подключения используется два 3-проводных шлейфа. При подключении модуля к Arduino удобно использовать Troyka Shield.

Если хотите оставить минимум проводов —
воспользуйтесь Troyka Slot Shield.

Пример работы с Arduino

testClock.ino
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы с часами реального времени
#include "TroykaRTC.h"
 
// размер массива для времени
#define LEN_TIME 12
// размер массива для даты
#define LEN_DATE 12
// размер массива для дня недели
#define LEN_DOW 12
 
// создаём объект для работы с часами реального времени
RTC clock;
 
// массив для хранения текущего времени
char timeLEN_TIME;
// массив для хранения текущей даты
char dateLEN_DATE;
// массив для хранения текущего дня недели
char weekDayLEN_DOW;
 
void setup()
{
  // открываем последовательный порт
  Serial.begin(9600);
  // инициализация часов
  clock.begin();
  // метод установки времени и даты в модуль вручную
  // clock.set(10,25,45,27,07,2005,THURSDAY);    
  // метод установки времени и даты автоматически при компиляции
  clock.set(__TIMESTAMP__);
  // что бы время менялось при прошивки или сбросе питания
  // закоментируйте оба метода clock.set();
}
 
void loop()
{
  // запрашиваем данные с часов
  clock.read();
  // сохраняем текущее время, дату и день недели в переменные
  clock.getTimeStamp(time, date, weekDay);
  // выводим в serial порт текущее время, дату и день недели
  Serial.print(time);
  Serial.print("\t");
  Serial.print(date);
  Serial.print("\t");
  Serial.println(weekDay);
  // ждём одну секунду
  delay(1000);
}

Пример работы с Iskra JS

В качестве примера выведем в «поле консоли» текущее время, дату и день недели. Для запуска примера понадобится библиотека для Iskra JS. Она обеспечивает простую работу с модулем и прячет в себе все тонкости протокола обмена данными между часами реального времени и управляющей платой.

rtc.js
// Настраиваем шину I2C
PrimaryI2C.setup({sda SDA, scl SCL, bitrate 100000});
 
// Создаем новый объект Rtc
var rtc = require('@amperka/rtc').connect(PrimaryI2C);
 
// Устанавливаем на часах текущее время контроллера
rtc.setTime();
 
// Результат в виде строки ISO: 2016-21-1T12:1:14
print(rtc.getTime('iso'));

Alarm functions

The DS3232 and DS3231 have two alarms. Alarm1 can be set to seconds precision; Alarm2 can only be set to minutes precision.

setAlarm(ALARM_TYPES_t alarmType, byte seconds, byte minutes, byte hours, byte daydate)

Set an alarm time. Sets the alarm registers only. To cause the INT pin to be asserted on alarm match, use alarmInterrupt(). This function can set either Alarm 1 or Alarm 2, depending on the value of alarmType (use the ALARM_TYPES_t enumeration above). When setting Alarm 2, the seconds value must be supplied but is ignored, recommend using zero. (Alarm 2 has no seconds register.)

alarmType: A value from the ALARM_TYPES_t enumeration, above. (ALARM_TYPES_t)seconds: The seconds value to set the alarm to. (byte)minutes: The minutes value to set the alarm to. (byte)hours: The hours value to set the alarm to. (byte)dayOrDate: The day of the week or the date of the month. For day of the week, use a value from the Time library timeDayOfWeek_t enumeration, i.e. dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday. (byte)

None.

Example
//Set Alarm1 for 12:34:56 on Sunday
RTC.setAlarm(ALM1_MATCH_DAY, 56, 34, 12, dowSunday);

setAlarm(ALARM_TYPES_t alarmType, byte minutes, byte hours, byte daydate)

Set an alarm time. Sets the alarm registers only. To cause the INT pin to be asserted on alarm match, use alarmInterrupt(). This functiuon can set either Alarm 1 or Alarm 2, depending on the value of alarmType (use the ALARM_TYPES_t enumeration above). However, when using this function to set Alarm 1, the seconds value is set to zero. (Alarm 2 has no seconds register.)

alarmType: A value from the ALARM_TYPES_t enumeration, above. (ALARM_TYPES_t)minutes: The minutes value to set the alarm to. (byte)hours: The hours value to set the alarm to. (byte)dayOrDate: The day of the week or the date of the month. For day of the week, use a value from the Time library timeDayOfWeek_t enumeration, i.e. dowSunday, dowMonday, dowTuesday, dowWednesday, dowThursday, dowFriday, dowSaturday. (byte)

None.

Example
//Set Alarm2 for 12:34 on the 4th day of the month
RTC.setAlarm(ALM2_MATCH_DATE, 34, 12, 4);

alarmInterrupt(byte alarmNumber, bool alarmEnabled)

Enable or disable an alarm «interrupt». Note that this «interrupt» just causes the RTC’s INT pin to be asserted. To use this signal as an actual interrupt to (for example) a microcontroller, the RTC «interrupt» pin needs to be connected to the microcontroller and the microcontroller application firmware must properly configure the interrupt and also provide for handling it.

alarmNumber: The number of the alarm to enable or disable, ALARM_1 or ALARM_2 (byte)alarmEnabled: true or false (bool)

None.

Example
RTC.alarmInterrupt(ALARM_1, true);      //assert the INT pin when Alarm1 occurs.
RTC.alarmInterrupt(ALARM_2, false);     //disable Alarm2

alarm(byte alarmNumber)

Tests whether an alarm has been triggered. If the alarm was triggered, returns true and resets the alarm flag in the RTC, else returns false.

Value of the alarm flag bit (bool)

Example
if ( RTC.alarm(ALARM_1) ) {		//has Alarm1 triggered?
	//yes, act on the alarm
}
else {
	//no alarm
}

checkAlarm(byte alarmNumber)

Tests whether an alarm has been triggered. If the alarm was triggered, returns true, else returns false. The alarm flag is not reset.

Value of the alarm flag bit (bool)

Example
if ( RTC.checkAlarm(ALARM_1) ) {		//has Alarm1 triggered?
	//yes, act on the alarm
}
else {
	//no alarm
}
Example
if ( RTC.checkAlarm(ALARM_1) ) {		//has Alarm1 triggered?
    //yes, act on the alarm
	RTC.clearAlarm(ALARM_1);           //clear the alarm flag
}
else {
	//no alarm
}

Библиотека RTC.h Arduino: описание команд

Для работы с модулями часов Ардуино, в библиотеке реализовано 5 функций:

// запуск модуля

// указать время
— год указывается без учета века, в формате 0-99
— часы указываются в 24-часовом формате, от 0 до 23
— день недели указывается в виде числа от 0-воскресенье, 6-суббота

// получить время
— gettime(«d-m-Y, H:i:s, D»); ответит строкой «12-06-2020, 18:30:05, Fri»
— gettime(«H»); ответит строкой «18»

функцией gettime можно получать различную информацию:

  • s — секунды от 00 до 59 (два знака)
  • i — минуты от 00 до 59 (два знака)
  • h — часы в 12-часовом формате от 01 до 12 (два знака)
  • H — часы в 24-часовом формате от 00 до 23 (два знака)
  • d — день месяца от 01 до 31 (два знака)
  • D — день недели наименование от Mon до Sun (три знака)
  • m — месяц от 01 до 12 (два знака)
  • M — месяц наименование от Jan до Dec (три знака)
  • Y — год от 2000 до 2099 (четыре знака)
  • y — год от 00 до 99 (два знака)

— указывает функции gettime мигать одним из параметров времени

— устанавливает период обращения к модулю в минутах (от 0 до 255)

Примечания

  1. Запасы углей стран мира / Железнова Н. Г., Кузнецов Ю. Я., Матвеев А. К., Череповский В. Ф., М.: Недра, 1983. — С.128
  2. Пригоровский М. М. Ископаемые угли СССР // Наука и жизнь : журнал. — 1935. — Январь (№ 1). — С. 24.
  3. Understanding Energy and Energy, Timothy F. Braun and Lisa M. Glidden 2014
  4. Дрёмов, Алексей Викторович. Обоснование рациональных параметров обеспыливания в комбайновом проходческом забое : диссертация кандидата технических наук : 05.26.01; . — Москва, 2010. — 148 с
  5. Кузьмичёв А. С. ред. «Справочник по борьбе с пылью в горонодобывающей промышленности» М.: Недра, 1982. — 240с.

Как подключить DS1302 к Arduino (RTC)

Для этого занятия нам потребуется:

  • плата Arduino Uno / Arduino Nano / Arduino Mega;
  • модуль DS1302, DS1307 или DS3231;
  • LCD монитор 1602 i2c;
  • провода «папа-мама».

DS1307 схема подключения к Ардуино Уно

Модули часов DS1307 и DS3231 подключаются к плате Ардуино через I2C протокол, как LCD дисплей I2C. Контакт SDA подключается к пину A4, контакт SCL к пину A5 Ардуино Уно. При подключении данных модулей к плате Arduino Mega следует использовать порты SDA (20 пин) и SCL (21 пин). При этом в скетче необходимо снять комментарий в строчке с нужным модулем, а строчку с модулем 1302 наоборот закомментировать.

Скетч. Часы реального времени Ардуино DS1307

#include <iarduino_RTC.h>

iarduino_RTC time(RTC_DS1302,6,8,7);  // для модуля DS1302 - RST, CLK, DAT
// iarduino_RTC time(RTC_DS1307);       // для модуля DS1307 с i2C
// iarduino_RTC timeRTC_DS3231);        // для модуля DS3231 с i2C

void setup() {
   delay(300);
   Serial.begin(9600);
   time.begin();
   time.settime(0, 30, 18, 12, 6, 20, 5); // 0  сек, 30 мин, 18 часов, 12, июня, 2020, четверг
}

void loop() {
   // если прошла 1 секунда выводим время
   if (millis() % 1000 == 0) {
      Serial.println(time.gettime("d-m-Y, H:i:s, D"));
      delay(1);
   }
}
  1. для работы с программой необходимо скачать библиотеку iarduino_RTC.h.
  2. с помощью команды можно установить дату и время.

Схема подключения часов реального времени с дисплеем

К сожалению, следующий пример с подключением дисплея 1602 I2C, возможен только с модулем 1302, так как порты SDA(A4) и SCL(A5) на микроконтроллеры Ардуино Уно необходимы для подключения дисплея LCD.

Скетч. Часы на Ардуино с LCD 1602 и DS1302

#include <iarduino_RTC.h>
iarduino_RTC time(RTC_DS1302,6,8,7);  // для модуля DS1302 - RST, CLK, DAT

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

void setup() {
   delay(300);
   LCD.init();            // инициализация LCD дисплея
   LCD.backlight();  // включение подсветки дисплея
   time.begin();
   time.settime(0, 30, 18, 12, 6, 20, 5); // 0  сек, 30 мин, 18 часов, 12, июня, 2020, четверг
}

void loop() {
   // если прошла 1 секунда выводим время на дисплей
   if (millis() % 1000 == 0) {
      LCD.setCursor(0,0);
      LCD.print(time.gettime("d M Y, D"));
      LCD.setCursor(4,1);
      LCD.print(time.gettime("H:i:s"));
      delay(1);
   }
}

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

Микросхема DS1307

Микросхема, занимающаяся подсчетом времени. Связь с микросхемой происходит по протоколу I2C. Её I2C-адрес 0b1101000.

Кварцевый резонатор

Для точной работы часов используется кварцевый резонатор на частоте 32768 Гц. Та же частота используется в кварцевых часах. Такая частота обеспечивает 215 циклов в секунду, что очень удобно для простых двоичных счётчиков

Гнездо для батарейки

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

Контакты подключения 3-проводных шлейфов

Контакты питания:

  • Земля (G) — чёрный провод. Соедините с пином Arduino.
  • Питание (V) — красный провод. Соедините с пином Arduino.
  • Не используется.

Контакты шины I²C:

  • Сигнальный (D) — Подключите к пину Arduino.
  • Сигнальный (С) — Подключите к пину Arduino.
  • Не используется.

Functions for setting and reading the time

get(void)

Description

Reads the current date and time from the RTC and returns it as a time_t value. Returns zero if an I2C error occurs (RTC not present, etc.).

None.

Current date and time (time_t)

Example
time_t myTime;
myTime = RTC.get();

set(time_t t)

Description

Sets the RTC date and time to the given time_t value. Clears the oscillator stop flag (OSF) bit in the control/status register. See the function and also the DS323x datasheet for more information on the OSF bit.

t: The date and time to set the RTC to (time_t)

Example
//this example first sets the system time (maintained by the Time library) to
//a hard-coded date and time, and then sets the RTC from the system time.
//the setTime() function is part of the Time library.
setTime(23, 31, 30, 13, 2, 2009);   //set the system time to 23h31m30s on 13Feb2009
RTC.set(now());                     //set the RTC from the system time

read(tmElements_t &tm)

Description

tm: Address of a tmElements_t structure to which the date and time are returned.

I2C status (byte). Returns zero if successful. The date and time read from the RTC are returned to the tm parameter.

Example
tmElements_t tm;
RTC.read(tm);
Serial.print(tm.Hour, DEC);
Serial.print(':');
Serial.print(tm.Minute,DEC);
Serial.print(':');
Serial.println(tm.Second,DEC);
Description

Sets the RTC to the date and time given by a tmElements_t structure. Clears the oscillator stop flag (OSF) bit in the control/status register. See the function and also the DS323x datasheet for more information on the OSF bit.

Example
tmElements_t tm;
tm.Hour = 23;             //set the tm structure to 23h31m30s on 13Feb2009
tm.Minute = 31;
tm.Second = 30;
tm.Day = 13;
tm.Month = 2;
tm.Year = 2009 - 1970;    //tmElements_t.Year is the offset from 1970
RTC.write(tm);            //set the RTC from the tm structure

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

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

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

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

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

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

Ссылки для заказа оборудования, которое использовалось в проекте из Китая

На часах реального премени 5 пинов: 5V, GND, SCL, SDA и SQW.

  • 5V используется для питания чипа модуля часов реального времени, когда вы делаете к нему запрос для получения данных о времени. Если сигнал 5 В не поступает, чип переходит в «спящий» режим.
  • GND — общая земля. Обязательно подключается в схему.
  • SCL — контакт i2c часов — необходим для обмена данными с часами реального времени.
  • SDA — контакт, по которому через i2c передаются данные с часов реального времени.
  • SQW дает возможность настроить вывод данных в виде square-wave. В большинстве случаев этот контакт не используется.

Если вы настроили аналоговый пин 3 (цифровой 17) в режим OUTPUT и HIGH, а аналоговый пин 2 (цифровой 16) в режим OUTPUT и LOW, вы можете запитывать часы реального времени непосредственно от этих контактов!

Подключите аналоговый пин 4 на Arduino к SDA. Аналоговый пин 5 на Arduino подключите к SCL.

Constructor

Description

For AVR architecture only (for backwards compatibility with the DS1307RTC library), the DS3232RTC library instantiates a DS3232RTC object named ; the user should not use the constructor for AVR boards. For other architectures, the user’s code must instantiate a DS3232RTC object.

Parameters

initI2C: An optional parameter to control whether the constructor initializes the I2C bus. The default is true (again for backwards compatibility). (bool)

Example
// For non-AVR boards only. Not needed for AVR boards.
DS3232RTC myRTC(false);     // tell constructor not to initialize the I2C bus.

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

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

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

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

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

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

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

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

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

Сборка модуля часов реального времени

Сборка часов реального времени DS1307 компании Adafruit
Фото
Пояснения

Подготовьтесь к сборке. Проверьте наличие всех необходимых деталей и инструментов. Установите монтажную плату в тисках.

Нанесите немного припоя на отрицательный контакт батареи.

Установите два резистора 2.2 КОм и керамический конденсатор

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

Внимательно посмотрите на фото слева, там чип установлен верно.

Чтобы холдер для батарейки не выпадал, лучше его припаять сверху.
После этого переверните плату и и припаяйте оставшиеся контакты.

Удалите остатки контактов от резисторов, кристалла и конденсатора.

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

Установите батарейку. Плоская часть батареи должна быть сверху. В среднем батарейка будет служить около 5 лет.
Даже если батарейка села, не оставляйте слот для нее пустым.

Написание прошивки

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

Код для этого выглядит следующим образом:

rtc.ino
#include <Wire.h>
#include <EEPROM.h>
#include "TM1637.h"
#include "DS1307.h"
 
 
//Массив, содержащий время компиляции
char compileTime = __TIME__;
 
 
//Номера пинов Arduino, к которым подключается индикатор
#define DISPLAY_CLK_PIN 12  
#define DISPLAY_DIO_PIN 13
 
//Для работы с микросхемой часов и индикатором мы используем библиотеки
//Классы TM1637 и DS1307 объявлены именно в них
TM1637 display(DISPLAY_CLK_PIN, DISPLAY_DIO_PIN);
DS1307 clock;
 
 
void setup()
{
 
  //Включаем и настраиваем индикатор
  display.set();
  display.init();
 
  //Запускаем часы реального времени
  clock.begin();
 
  //Получаем число из строки, зная номер первого символа
  byte hour = getInt(compileTime, );
  byte minute = getInt(compileTime, 3);
  byte second = getInt(compileTime, 6);
 
  //Готовим для записи в RTC часы, минуты, секунды
  clock.fillByHMS(hour, minute, second);
 
  //Записываем эти данные во внутреннюю память часов.
  //С этого момента они начинают считать нужное для нас время
  clock.setTime();
 
}
 
 
void loop()
{
  //Значения для отображения на каждом из 4 разрядов
  int8_t timeDisp4;
 
  //Запрашиваем время с часов
  clock.getTime();
 
  //Получаем десятки часов с помощью целочисленного деления
  timeDisp = clock.hour  10;
 
  //Получаем единицы часов с помощью остатка от деления
  timeDisp1 = clock.hour % 10;
 
  //Проделываем то же самое с минутами
  timeDisp2 = clock.minute  10;
  timeDisp3 = clock.minute % 10;
 
  //... а затем выводим его на экран
  display.display(timeDisp);
 
  //у нас нет отдельных разрядов для секунд, поэтому
  //будем включать и выключать двоеточие каждую секунду
  display.point(clock.second % 2 ? POINT_ON  POINT_OFF);
 
}
 
//Содержимое функции объяснено ниже
char getInt(const char* string, int startIndex) {
  return int(stringstartIndex - '0') * 10 + int(stringstartIndex+1) - '0';
}

Теперь загружаем этот код в среду разработки, компилируем и заливаем. Смотрим на дисплей — бинго! Время на дисплее — время компиляции.

Объяснение функции getInt

Для начала необходимо понять, откуда же в массиве появляется время.
Оно появляется в этой строчке:

Компилятор вместо подставляет строку, содержащую время компиляции в виде , где hh — часы, mm — минуты, ss — секунды.

Вернемся к коду, который необходимо объяснить:

char getInt(const char* string, int startIndex) {
  return int(stringstartIndex - '0') * 10 + int(stringstartIndex+1) - '0';
}

В массиве , передаваемом в качестве параметра в функцию , мы получаем символ с индексом и следующий за ним, чтобы в итоге получить двухзначное целое число. Однако, изначально это не число, а пара символов. Чтобы получить число по символу, нам необходимо вычесть из этого символа символ нуля (‘): ведь в таблице ASCII все символы цифр идут одна за другой, начиная с символа нуля. Поэтому код , дословно, делает следующее: «Берем символ номер , вычитаем из него символ нуля и переводим в целочисленный тип».

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

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

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

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

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

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


#include <Wire.h>

#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; //отображение на каждом из четырех разрядов.

clock.getTime();//запрос на получение времени.

timeDisp = clock.hour / 10;

timeDisp = clock.hour % 10;

timeDisp = clock.minute / 10;

timeDisp = 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 - '0') * 10 + int(string) - '0'; //действия для корректной записи времени в двухзначное целое число. В ином случае на экране будет отображена просто пара символов.

}

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

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

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

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

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

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

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

Подключение

Модуль часов реального времени необходимо подключить к выводам SCL/SDA, относящимся к шине I²C. Также необходимо подключить линии питания (Vcc) и земли (GND).

Линии SDA/SCL имеют собственные отдельные пины на Arduino, однако внутри они так или иначе подключены к пинам общего назначения. Если рассмотреть Arduino Uno, линии SDA соответствует пин A4, а SCL — A5.

В комплекте с модулем поставляется шлейф с мама-контактами, которые удобнее подключать к Troyka Shield. Однако отдельные пины SDA и SCL на ней не выведены, поэтому мы осуществили подключение прямо через пины A5 и A4.

В плане подключения индикатора — все гораздо проще. Выводы CLK и DIO можно подключить к любым цифровым выводам. В данном случае используются 12-й и 11-й выводы соответственно.

Оцените статью
Рейтинг автора
5
Материал подготовил
Илья Коршунов
Наш эксперт
Написано статей
134
Добавить комментарий