Часы реального времени на rtc модулях ардуино ds1302, ds1307, ds3231

Отличительные особенности DS3231

  • Точность ±2 ppm в диапазоне температур от 0°C до +40°C
  • Точность ±3.5 ppm в диапазоне температур от-40°C до +85°C
  • Вход для подключения автономного источника питания, позволяющего обеспечить непрерывную работу
  • Рабочий температурный диапазонкоммерческий: от 0°C до +70°C
  • индустриальный: -от 40°C до +85°C
  • Низкое потребление
  • Часы реального времени, отсчитывающие секунды, минуты, часы, дни недели, дни месяца, месяц и год с коррекцией високосного года вплоть до 2100
  • Два ежедневных будильника
  • Выход прямоугольного сигнала с программируемой частотой
  • Быстродействующие (400 кГц) I2C интерфейс
  • 3.3 В питание
  • Цифровой температурный датчик с точностью измерения ±3°C
  • Регистр, содержащий данные о необходимой подстройке
  • Вход/выход сброса nonRST

Battery Backup

The DS1307 incorporates a battery input, and maintains accurate timekeeping when main power to the device is interrupted.

The built-in power-sense circuit continuously monitors the status of VCC to detect power failures and automatically switches to the backup supply. So, you need not worry about power outages, your MCU can still keep track of time.

The bottom side of the board holds a battery holder for 20mm 3V lithium coincells. Any CR2032 battery can fit well.

Assuming a fully charged CR2032 battery with capacity 47mAh is used and chip consumes its minimum 300nA, the battey can keep the RTC running for a minimum of 17.87 years without an external 5V power supply.

47mAh/300nA = 156666.67 hours = 6527.78 days = 17.87 years

DS1307 RTC chip

At the heart of the module is a low-cost, quite accurate RTC chip from Maxim – DS1307. It manages all timekeeping functions and features a simple two-wire I2C interface which can be easily interfaced with any microcontroller of your choice.

The chip maintains seconds, minutes, hours, day, date, month, and year information. The date at the end of the month is automatically adjusted for months with fewer than 31 days, including corrections for leap year (valid up to 2100). The clock operates in either the 24-hour or 12-hour format with an AM/PM indicator.

The other cool feature of this board comes with SQW pin, which outputs one of four square-wave frequencies 1Hz, 4kHz, 8kHz or 32kHz and can be enabled programmatically.

DS1307 come with an external 32kHz crystal for time-keeping. The problem with these crystals is that external temperature can affect their oscillation frequency. This change in frequency is negligible but it surely adds up.

This may sound like a problem, but it’s not. It actually results with the clock being off by around five or so minutes per month.

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

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

Откроем пример Файл → Образцы → DS1307RTC → SetTime и загрузим его в Arduino.

Отобразить/скрыть пример кода SetTime

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>

const char *monthName = {
«Jan», «Feb», «Mar», «Apr», «May», «Jun»,
«Jul», «Aug», «Sep», «Oct», «Nov», «Dec»
};

tmElements_t tm;

void setup()
{
bool parse=false;
bool config=false;

// получаем дату и время на момент компиляции
if (getDate(__DATE__) && getTime(__TIME__))
{
parse = true;
// и конфигурируем RTC используя эту информацию
if (RTC.write(tm))
{
config = true;
}
}

Serial.begin(9600);
while (!Serial) ; // ожидаем ответа порта
delay(200);
if (parse && config)
{
Serial.print(«DS1307 configured Time=»);
Serial.print(__TIME__);
Serial.print(«, Date=»);
Serial.println(__DATE__);
}
else if (parse)
{
Serial.println(«DS1307 Communication Error :-{«);
Serial.println(«Please check your circuitry»);
}
else
{
Serial.print(«Could not parse info from the compiler, Time=\»»);
Serial.print(__TIME__);
Serial.print(«\», Date=\»»);
Serial.print(__DATE__);
Serial.println(«\»»);
}
}

void loop()
{
}

bool getTime(const char *str)
{
int Hour, Min, Sec;

if (sscanf(str, «%d:%d:%d», &Hour, &Min, &Sec) != 3) return false;
tm.Hour = Hour;
tm.Minute = Min;
tm.Second = Sec;
return true;
}

bool getDate(const char *str)
{
char Month;
int Day, Year;
uint8_t monthIndex;

if (sscanf(str, «%s %d %d», Month, &Day, &Year) != 3) return false;
for (monthIndex = 0; monthIndex < 12; monthIndex++)
{
if (strcmp(Month, monthName) == 0) break;
}
if (monthIndex >= 12) return false;
tm.Day = Day;
tm.Month = monthIndex + 1;
tm.Year = CalendarYrToTm(Year);
return true;
}

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84

#include <Wire.h>
#include <Time.h>
#include <DS1307RTC.h>
 

constchar*monthName12={

«Jan»,»Feb»,»Mar»,»Apr»,»May»,»Jun»,

«Jul»,»Aug»,»Sep»,»Oct»,»Nov»,»Dec»

};

tmElements_ttm;

voidsetup()

{

boolparse=false;

boolconfig=false;

// получаем дату и время на момент компиляции

if(getDate(__DATE__)&&getTime(__TIME__))

{

parse=true;

// и конфигурируем RTC используя эту информацию

if(RTC.write(tm))

{

config=true;

}

}

Serial.begin(9600);

while(!Serial);// ожидаем ответа порта

delay(200);

if(parse&&config)

{

Serial.print(«DS1307 configured Time=»);

Serial.print(__TIME__);

Serial.print(«, Date=»);

Serial.println(__DATE__);

}

elseif(parse)

{

Serial.println(«DS1307 Communication Error :-{«);

Serial.println(«Please check your circuitry»);

}

else

{

Serial.print(«Could not parse info from the compiler, Time=\»»);

Serial.print(__TIME__);

Serial.print(«\», Date=\»»);

Serial.print(__DATE__);

Serial.println(«\»»);

}

}
 

voidloop()

{
}
 

boolgetTime(constchar*str)

{

intHour,Min,Sec;

if(sscanf(str,»%d:%d:%d»,&Hour,&Min,&Sec)!=3)returnfalse;

tm.Hour=Hour;

tm.Minute=Min;

tm.Second=Sec;

returntrue;

}
 

boolgetDate(constchar*str)

{

charMonth12;

intDay,Year;

uint8_tmonthIndex;

if(sscanf(str,»%s %d %d»,Month,&Day,&Year)!=3)returnfalse;

for(monthIndex=;monthIndex<12;monthIndex++)

{

if(strcmp(Month,monthNamemonthIndex)==)break;

}

if(monthIndex>=12)returnfalse;

tm.Day=Day;

tm.Month=monthIndex+1;

tm.Year=CalendarYrToTm(Year);

returntrue;

}

Открыв монитор порта, видим, что время теперь установлено правильно

Вновь вернемся к примеру ReadTest, скомпилируем его, загрузим в микроконтроллер и посмотрим на результат.

Теперь мы видим, что время актуально и часы тикают.  

Код из видео:

#include <Wire.h>
#include <OLED_I2C.h>

OLED  myOLED(SDA, SCL, 8);

extern uint8_t SmallFont[];
extern uint8_t MediumNumbers[];
extern uint8_t BigNumbers[];
 
   
 ///// часы ..
byte decToBcd(byte val){
  return ( (val/10*16) + (val%10) );
}

byte bcdToDec(byte val){
  return ( (val/16*10) + (val%16) );
}

void setDateDs1307(byte second,        // 0-59
                   byte minute,        // 0-59
                   byte hour,          // 1-23
                   byte dayOfWeek,     // 1-7
                   byte dayOfMonth,    // 1-28/29/30/31
                   byte month,         // 1-12
                   byte year)          // 0-99
{
   Wire.beginTransmission(0x68);
   Wire.write(0);
   Wire.write(decToBcd(second));    
   Wire.write(decToBcd(minute));
   Wire.write(decToBcd(hour));     
   Wire.write(decToBcd(dayOfWeek));
   Wire.write(decToBcd(dayOfMonth));
   Wire.write(decToBcd(month));
   Wire.write(decToBcd(year));
   Wire.endTransmission();
}

void getDateDs1307(byte *second,
          byte *minute,
          byte *hour,
          byte *dayOfWeek,
          byte *dayOfMonth,
          byte *month,
          byte *year)
{

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

  Wire.requestFrom(0x68, 7);

  *second     = bcdToDec(Wire.read() & 0x7f);
  *minute     = bcdToDec(Wire.read());
  *hour       = bcdToDec(Wire.read() & 0x3f); 
  *dayOfWeek  = bcdToDec(Wire.read());
  *dayOfMonth = bcdToDec(Wire.read());
  *month      = bcdToDec(Wire.read());
  *year       = bcdToDec(Wire.read());
}
  
///// температура ..
float get3231Temp(){
  byte tMSB, tLSB; 
  float temp3231;

  Wire.beginTransmission(0x68);
  Wire.write(0x11);
  Wire.endTransmission();
  Wire.requestFrom(0x68, 2);

  if(Wire.available()) {
    tMSB = Wire.read(); //2's complement int portion
    tLSB = Wire.read(); //fraction portion

    temp3231 = (tMSB & B01111111); //do 2's math on Tmsb
    temp3231 += ( (tLSB >> 6) * 0.25 ); //only care about bits 7 & 8
  }
  else {
    //oh noes, no data!
  }

  return temp3231;
}


void setup()
{
  Serial.begin(9600);
  myOLED.begin();
  Wire.begin();
 

 /*  // установка часов
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  second = 30;
  minute = 0;
  hour = 14;
  dayOfWeek = 3; // день недели
  dayOfMonth = 1; // день
  month = 4;
  year = 14;

  setDateDs1307(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
 */
}

void loop(){
  byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
  char week = {"Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"};
 
  getDateDs1307(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
  
  char time;
  char data;
  
  snprintf(time, sizeof(time),"%02d:%02d:%02d",           
           hour, minute, second);
           
  snprintf(data, sizeof(data), "%02d/%02d/%02d",            
            dayOfMonth, month, year);
  
  myOLED.setFont(SmallFont);
 
  myOLED.print(time, LEFT, 0);
  myOLED.print(data, LEFT, 15);
  myOLED.printNumF(get3231Temp(), 2, LEFT, 30);
  myOLED.print("C", 32, 30);
  myOLED.update();

 delay(1000);
}

////// конец
 

DS1307

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

Скачать:   на официальном сайте       зеркало1    зеркало2

Введение: 

   Эта библиотека была написана для легкого взаимодействия и использования модуля на микросхеме DS1307 с Arduino или chipKit без необходимости использования библиотеки Wire.   Данная библиотека использует по умолчанию режим Fast Mode (400 кГц) аппаратного интерфейса I2C.    Работа этой библиотека не гарантируется в режиме одновременной работы с библиотекой Wire и совместного использования контактов.

Структура:

Time;Структура управления данными времени и даты.Переменныеhour, min, sec: Для определения данных времениdate, mon, year: Для определения данных датыdow: День недели, начиная с понедельникаПример: Time t; // Определяем структуру с именем t класса «время»DS1307_RAM;Буфер для использования совместно с ReadBuffer () и WriteBuffer ().Переменные: Cell : Байт-массив для хранения данных, с возможностью чтения или записи в ОЗУ микросхемы.Пример: DS1307_RAM ramBuffer; // Объявляем буфер для использования

Определенные литералы:

Дни неделиИспользуется совместно с setDOW() и Time.dowMONDAY:          1TUESDAY:         2WEDNESDAY:  3THURSDAY:      4FRIDAY:             5SATURDAY:      6SUNDAY:           7Длина названияИспользуется совместно с getTimeStr(), getDateStr(), getDOWStr() and getMonthStr()FORMAT_SHORT: 1 (полное название)FORMAT_LONG:  2 (сокращенное (3 буквенное) название)Формат датыИспользуется совместно с getDateStr()FORMAT_LITTLEENDIAN:    1  (дд.мм.гггг)FORMAT_BIGENDIAN:          2  (гггг.мм.дд)FORMAT_MIDDLEENDIAN:  3  (мм.дд.гггг)

Частота на выходе SQW

Используется совместно с setSQWRate()

SQW_RATE_1:     1  (1 Гц)

SQW_RATE_4K:  2  (4096 Гц)

SQW_RATE_8K:  3  (8192 Гц)

SQW_RATE_32K:  4  (32768 Гц)

Функции:

DS1307(SDA, SCL);Инициализация библиотеки с помощью интерфейса I2CПараметры:SDA: Вывод подключения SDA-пина DS1307 (Вывод 5, данные)SCL: Вывод подключения SCL-пина DS1307 (вывод 6, тактирование)Пример: DS1307 rtc(SDA, SCL); // Инициализация библиотеки DS13071 с помощью  интерфейса I2CПримечание: DS1307 можно подключать с любым свободным выводам Arduino. Если в схеме уже используется шина I2C и Вы попытаетесь подключиться к тем же выводам, то данная библиотека работать не будет, т.к. любой TWI-совместимый протокол требует исключительного доступа к пинам.
begin();Инициализация подключения к DS1307Параметры: НетВозврат: НетПример:  rtc.begin(); //Инициализация подключения к DS1307
getTime();Считать текущие данные из DS3231.Параметры: НетВозврат: формат Time-structureПример: t = rtc.getTime(); // Считать текущую дату и время.

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

DS1307 RTC Module Pinout

The DS1307 RTC module has total 7 pins that interface it to the outside world. The connections are as follows:

SQW pin outputs one of four square-wave frequencies 1Hz, 4kHz, 8kHz or 32kHz and can be enabled programmatically.

DS pin is supposed output temperature readings if your module has a DS18B20 temperature sensor installed right next to the battery holder(labled as U1).

SCL is the clock input for the I2C interface and is used to synchronize data movement on the serial interface.

SDA is the data input/output for the I2C serial interface.

VCC pin supplies power for the module. It can be anywhere between 3.3V to 5.5V.

GND is a ground pin.

BAT is a backup supply input for any standard 3V lithium cell or other energy source to maintain accurate timekeeping when main power to the device is interrupted.

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

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

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

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

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

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

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

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

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

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

Arduino Code – Reading Date & Time

The following sketch will give you complete understanding on how to set/read date & time on DS1307 RTC module and can serve as the basis for more practical experiments and projects.

Here’s how the output looks like in the serial monitor.


DS1307 Output On Serial Monitor

Code Explanation:

The sketch starts with including wire.h & RTClib.h libraries for communicating with the module. We then create an object of RTClib library and define 2D character array to store days information.

In setup and loop sections of the code, we use following functions to interact with the RTC module.

begin() function ensures that the RTC module is connected.

isrunning() function reads the DS1307’s internal I2C registers to check if the chip has lost track of time. If the function returns false, we can then set the date & time.

adjust() function sets the date & time. This is an overloaded function.

  • One overloaded method sets the date & time at which the sketch was compiled.
  • Second overloaded method sets the RTC with an explicit date & time. For example to set January 27 2017 at 12:56 you would call:

now() function returns current date & time. Its return value is usually stored in the variable of datatype DateTime.

year() function returns current year.

month() function returns current month.

day() function returns current day.

dayOfTheWeek() function returns current day of the week. This function is usually used as an index of a 2D character array that stores days information like the one defined in above program

hour() function returns current hour.

minute() function returns current minute.

second() function returns current seconds.

unixtime() function returns unix time in seconds. Unix time is a system for describing a point in time. It is the number of seconds that have elapsed since 00:00:00(known as Coordinated Universal Time – Thursday, 1 January 1970).

TimeSpan() function is used to add/subtract time to/from current time. You can add/subtract days, hours, minutes & seconds. It’s also an overloaded function.

  • returns the future time with seconds added into current time.
  • returns the past time.

Wiring DS1307 RTC module to Arduino UNO

Let’s hook the RTC up to the Arduino.

Connections are fairly simple. Start by connecting VCC pin to the 5V output on the Arduino and connect GND to ground.

Now we are remaining with the pins that are used for I2C communication. Note that each Arduino Board has different I2C pins which should be connected accordingly. On the Arduino boards with the R3 layout, the SDA (data line) and SCL (clock line) are on the pin headers close to the AREF pin. They are also known as A5 (SCL) and A4 (SDA).

If you have a Mega, the pins are different! You’ll want to use digital 21 (SCL) and 20 (SDA). Refer below table for quick understanding.

SCL SDA
Arduino Uno A5 A4
Arduino Nano A5 A4
Arduino Mega 21 20
Leonardo/Micro 3 2

The following diagram shows you how to wire everything.


Wiring DS1307 RTC module with Arduino

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Adblock
detector