Всем доброго дня. Как-то захотел сделать часы с будильником на arduino до это я пытался воспользоваться встроенным 16-ти битным таймером, но на практике часы спешили на 4 секунды в час. Так как в своей разработке я использовал arduino nano китайского производства сразу под сомнения попал кварцевый генератор, но менять не хотелось его и большой точности я вряд ли добился бы, по этому было принято решение использовать отдельный модуль для часов реального времени. Поскольку у нас они дорогие а из китая долго ждать я решил спаять модуль часов реального времени самостоятельно. Почему я выбрал модуль часов на отдельной микросхеме:
- Независимые часы от нагрузки микроконтроллера
- Наличие дежурного источника (батарейка 3 вольта)
- Высокая точность
- Наличие своего тактового сигнала при необходимости
В качестве "часовой" микросхемы я выбрал DS1307Z от Maxim Semiconductor в корпусе SOIC-8. Можно взять и dip версию но в ней я не видел смысла, она больше и менять я ее не собирался. Особенности данной микросхемы:
- последовательный 2 проводной интерфейс I2C
- наличие 56 байт своей ОЗУ (вряд ли кто-то будет пользоваться, но все таки они есть)
- наличие независимого генератора прямоугольных импульсов (настраиваемый)
- потребление от батарейки менее 500 нA при 25ºС
- кроме даты присутствует встроенный календарь с учетом високосного года (до 2100 года)
В качестве альтернативы можно использовать DS1305, DS1302, DS1338, они отличаются возможностями и ценной естественно. Так как для наших скромных целей достаточно DS1307 мы ей и воспользуемся. Схема подключения довольно проста и используем минимум обвязок:
В качестве подтягивающих резисторов можно использовать резисторы номиналом 1...10Ком, так же я добавил конденсатор по питанию на 0.1 мкФ. Кварцевый резонатор обычный часовой 32768 Гц, а в качестве батарейки я выбрал формата CR2032 (таблетку). Ну и немного уточнил схему:
Прежде чем заниматься трассировкой платы немного о распиновке и размерах микросхемы:
Поскольку у нас все есть мы займемся трассировкой платы, набросав платку у нас получилось следующее:
Сразу хочу уточнить что прежде чем травить мою плату нужно либо убедиться в том что расстояние между ногами держателя для батарейки такое же, либо изменить на свое. Кварцевый резонатор можно брать толщиной 2-3 мм они сядут идеальной, можно больше но может быть мение идеально. Так же можно найти информацию что бы повысить точность рекомендуют напаивать "минус" на корпус кварцевого резонатора. В результате травления платы мы получим следующее:
Ну и наконец собрав все мы получим вот такой модуль:
Подключаем к arduino:
- VCC - 5В Arduino
- GND - GND Arduino
- SDA - A4 Arduino
- SLC - A5 Arduino
Для работы модуля с arduino я не стал придумывать велосипед и использовал готовую библеотеку RTClib . Пример работы часов:
// Пример RTC на DS1307
#include <Wire.h>
#include "RTClib.h"
RTC_DS1307 rtc;
char daysOfTheWeek[7][12] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void setup () {
while (!Serial); // for Leonardo/Micro/Zero
Serial.begin(57600);
if (! rtc.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (! rtc.isrunning()) {
Serial.println("RTC is NOT running!");
// если раскоментировать строку ниже, при компиляции установиться системное время
// rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
}
void loop () {
DateTime now = rtc.now();
Serial.print(now.year(), DEC);
Serial.print('/');
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print(" (");
Serial.print(daysOfTheWeek[now.dayOfTheWeek()]);
Serial.print(") ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
Serial.print(" since midnight 1/1/1970 = ");
Serial.print(now.unixtime());
Serial.print("s = ");
Serial.print(now.unixtime() / 86400L);
Serial.println("d");
// calculate a date which is 7 days and 30 seconds into the future
DateTime future (now + TimeSpan(7,12,30,6));
Serial.print(" now + 7d + 30s: ");
Serial.print(future.year(), DEC);
Serial.print('/');
Serial.print(future.month(), DEC);
Serial.print('/');
Serial.print(future.day(), DEC);
Serial.print(' ');
Serial.print(future.hour(), DEC);
Serial.print(':');
Serial.print(future.minute(), DEC);
Serial.print(':');
Serial.print(future.second(), DEC);
Serial.println();
Serial.println();
delay(3000);
}
При выполнении данного кода в терминале будет следующее:
Всем спасибо за внимание и как всегда во вложении можно найти Datasheet на русском языке (спасибо от ребят PIClist RUS) , печатную плату и схему.