Часы на Arduino используя DS3231

Часы на Arduino используя DS3231

Сегодня поговорим о часах на Arduino из-за того что эта тема очень востребованная. Часы будут обычные, без температуры, даты, просто обычные часы с установкой времени кнопками.

Для этого нам понадобится 7-сигментный индикатор на TM1637

7-сегментный индикатор на TM1637

И модуль часов реального времени DS3231

Модуль часов реального времени на DS3231

Индикаторы бывают разных размеров, работать будут оба, подключать его необходимо на два свободных выхода Arduino.
7-сегментный индикатор на TM1637 меньшего размера

Модуль часов подключается к I2C шине и только нога SQW подключается на нулевое прерывание, на UNO это вторая нога. На этом выходе генерируется сигнал с периодом в одну секунду, который дергает прерывание и мигают двоеточие на  индикаторе, то есть если его отключить – точки остановятся, не будут мигать.

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

Подключение модуля часов и 7-сегментного индикатора к Arduino

 

По поводу кода смысла рассказывать нет, только основное.

Тут вот к 6-й и 7-й ноге подключен индикатор.

// 7сигментный индикатор
#define CLK 6         
#define DIO 7

 

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

// кнопки
#define keyHor 5 // Кнопка для настройки часов
#define keyMin 4 // Кнопка для настройки минут
#define keyPL  3 // Кнопка для для прибавления 1 к часам или минутам

 

Детальки на али:

Arduino UNO

Часы DS3231

Индикатор на TM1637

 

Весь код

#include <Wire.h>
#include "TM1637.h" // http://www.seeedstudio.com/wiki/File:DigitalTube.zip
// 7сигментный индикатор
#define CLK 6
#define DIO 7
#define brightness 6 // яркость, от 0 до 7
// кнопки
#define keyHor 5
#define keyMin 4
#define keyPL 3
TM1637 tm1637(CLK,DIO);
#define DS3231_I2C_ADDRESS 0x68
 
volatile boolean flag;
///// часы ..
byte decToBcd(byte val){
return ( (val/10*16) + (val%10) );
}
byte bcdToDec(byte val){
return ( (val/16*10) + (val%16) );
}
void setDateDs3231(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(DS3231_I2C_ADDRESS);
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 getDateDs3231(byte *second,
byte *minute,
byte *hour,
byte *dayOfWeek,
byte *dayOfMonth,
byte *month,
byte *year)
{
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0);
Wire.endTransmission();
Wire.requestFrom(DS3231_I2C_ADDRESS, 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());
}
void setINT(){ //включает выход SQW, который вроде выключен по умолчанию
Wire.beginTransmission(DS3231_I2C_ADDRESS);
Wire.write(0x0E);
Wire.write(0x80);
Wire.endTransmission();
}
void blink() {
digitalWrite(13, !digitalRead(13));
flag = !flag;
tm1637.point(flag);
}
void setup() {
// Serial.begin(9600);
Wire.begin();
pinMode(13, OUTPUT);
pinMode(keyHor, INPUT_PULLUP);
pinMode(keyMin, INPUT_PULLUP);
pinMode(keyPL, INPUT_PULLUP);
tm1637.init();
tm1637.set(brightness);
 
setINT();
attachInterrupt(0, blink, CHANGE);
}
void loop(){
// читаем время из модуля
byte second, minute, hour, dayOfWeek, dayOfMonth, month, year;
getDateDs3231(&second, &minute, &hour, &dayOfWeek, &dayOfMonth, &month, &year);
// забиваем массив значениями для отпарвки на экран
int8_t TimeDisp[4];
 
TimeDisp[0] = hour / 10;
TimeDisp[1] = hour % 10;
TimeDisp[2] = minute / 10;
TimeDisp[3] = minute % 10;
// обработка кнопок
if (!digitalRead(keyHor) && !digitalRead(keyPL)){ // часы
second = 0; // сбрасываем секунды
hour++; // пребавляем единицу к часам
if (hour > 23) hour = 0; // если вылезли за границы присваеваем 0
setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year); // пишим в модуль
delay(200);
}
if (!digitalRead(keyMin) && !digitalRead(keyPL)){ // минуты
second = 0;
minute++;
if (minute > 59) minute = 0;
setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year);
delay(200);
}
// отправляем массив на экран
tm1637.display(TimeDisp);
}

Видео подключения модуля часов и семисегментного индикатора к Arduino

6 комментариев к “Часы на Arduino используя DS3231”

  1. Юрий М.

    Почему-то не сразу начинают идти. Индикатор не горит. Потом вдруг пойдут . 

  2. Юрий М.

    Продолжу собрано на ардуино нано. При подаче питания индикатор не работает. Если я его отключу на ардуине мигает лампочка с f 1 Герц. Если снова подключаю интикатор к ВКЛ.ардуине индикатор может начнёт или не начнёт показывать время.

  3. «Для включения SQW нужно в контрольный регистр записывать 0x40»

    Тогда уж 0х00 надо писать.

  4. Повторил на Atmega8, всё заработало. добавил только мигание точек. ПОсмотрю на точность и можно придумывать модель корпуса и разводить платку. Спасибо!

Оставьте комментарий

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

Adblock
detector