Создаем и подключаем часы на Ардуино: 2 способа

часы Ардуино Программирование

В данной статье обсудим план действий при созданий часов на плате Arduino и создадим свои собственные часы, используя модифицированный стандартный код-заготовку. Отметим, что проект реализовывался с использованием микроконтроллера, основанного на Arduino UNO. Данный проект реализовывался с использованием семисегментного индикатора ТМ1637, модулем часов реального времени DS3231 и возможностью установки времени кнопками.

1 2

Программная часть

#include <Wire.h>

#include «TM1637.h» // в гугл введите запрос DigitalTube library

/*

* В файл TM1637.h требуется добавить следующее:

static int8_t TubeTab[] = {0x3f,0x06,0x5b,0x4f,

0x66,0x6d,0x7d,0x07,

0x7f,0x6f,0x77,0x7c,

0x39,0x5e,0x79,0x71, 0x63, 0x00};//0~9,A,b,C,d,E,F

*/

// дефайны отвечают за кнопки

#define keyP 4

#define keySET 3

#define keyM 2

 

TM1637 tm1637(6, 7);

 

#define DS3231_I2C_ADDRESS 0x68

int8_t decToBcd(byte val){

return ( (val/10*16) + (val%10) );

}

int8_t bcdToDec(byte val){

return ( (val/16*10) + (val%16) );

}

void setDateDs3231(int8_t second, // 0-59 секунд

int8_t minute, // 0-59 минут

int8_t hour, // 1-23 час

int8_t dayOfWeek, // 1-7 день // в перспективе можно доделать и подключить экран для показа даты

int8_t dayOfMonth, // 1-28/29/30/31 месяц

int8_t month, // 1-12

int8_t 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,

int8_t *minute,

int8_t *hour,

int8_t *dayOfWeek,

int8_t *dayOfMonth,

int8_t *month,

int8_t *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 setup() {

// Serial.begin(9600);

Wire.begin();

pinMode(keyP, INPUT_PULLUP);

pinMode(keySET, INPUT_PULLUP);

pinMode(keyM, INPUT_PULLUP);

tm1637.init();

tm1637.set(0);

tm1637.point(1);

analogReference(INTERNAL);

 

}

void loop(){

// читаем время из модуля

int8_t 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(keySET)){ // Если надавили сет

delay(200); // противодребезговая защита

second = 0; // сброс секундомера

tm1637.point(1); // включаем двоеточие между часами и минутами

do{ /// Крутим цикл! /// часы

if (!digitalRead(keyP)){ // если в цикле надавили на «+»

hour++; // прибавляем единицу к часу

if (hour > 23) hour = 0; // если вылезли за границы присваиваем 0

setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year); // пишим в модуль

delay(200);

}

if (!digitalRead(keyM)){ // если на «-«

hour—; // убавляем единицу

if (hour < 0) hour = 23; // если вылезли за границы

setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year); // пишим в модуль

delay(200);

}

TimeDisp[0] = hour / 10; // в цикле также показываем что получилось

TimeDisp[1] = hour % 10;

TimeDisp[2] = 17; // 17 это 0xff, выключение

TimeDisp[3] = 17;

tm1637.display(TimeDisp); // отправляем массив на экран

}while(digitalRead(keySET)); // крутимся пока не надавили сет

delay(500); // антидребезг

 

do{ // снова крутимся, но уже для минут.

if (!digitalRead(keyP)){ // также смотрим не нажато ли «+»

minute++; // прибавляем минуту

if (minute > 59) minute = 0; // проверяем

setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

delay(200);

}

if (!digitalRead(keyM)){ // также смотрим на «-«

minute—;

if (minute < 0) minute = 59;

setDateDs3231(second, minute, hour, dayOfWeek, dayOfMonth, month, year);

delay(200);

}

TimeDisp[0] = 17;

TimeDisp[1] = 17;

TimeDisp[2] = minute / 10;

TimeDisp[3] = minute % 10;

tm1637.display(TimeDisp); // отправляем массив на экран

 

}while(digitalRead(keySET)); // крутимся пока не надавили сет

delay(200); // задумываемся перед выходом

}

 

// таймер на RTC )

static byte oldSec;

if (oldSec != second){ // true каждую секунду.

oldSec = second; // сохраняем прошедшую

// мигание точкой

static bool point;

point = !point;

tm1637.point(point);

// Устанавливаем яркость LED

byte brightness = map(analogRead(A1), 0, 1023, 0, 7); // Читаем вход и мапим, приделы подкорректировать !!!

tm1637.set(brightness); // Пишем в дисплей

} ///

 

// Отображение температуры

// if (second == 15 || second == 16 || second == 17 || !digitalRead(keyP)){ // Отображаем каждые 3 секунды или кнопкой

if (!digitalRead(keyP)){ // Отображаем при нажатой кнопки «+»

tm1637.point(0); // Выключаем двоеточие

 

/// Получение температуры !!!

// int8_t tempC = (analogRead(A0) / 9.31; // Для LM35 и атмеги328 (опорное 1,1)

int8_t tempC = (((analogRead(A0) * 2.54) / 1024.0) — 0.5) * 100; // для TMP36 и атмеги8 (опорное 2,56)

// int8_t tempC = (((analogRead(A0) * 1.1) / 1024.0) — 0.5) * 100; // для TMP36 и атмеги328 (опорное 1,1)

// int8_t tempC = (analogRead(A0)/1024.0)*5.0*1000/10; // для 5 вольт LM35.

 

TimeDisp[0] = tempC / 10; // Заполняем массив

TimeDisp[1] = tempC % 10;

TimeDisp[2] = 16; // градус (нужно добавить «0x63» в «TubeTab[]» в «TM1637.h»)

TimeDisp[3] = 12; // C

delay(200);

}

 

// отправляем массив на экран

tm1637.display(TimeDisp);

 

}

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

Установка времени осуществляется кнопками, притянутые к массе. Первая кнопка переключает нас на настройку чаcов, вторая-на минуты, а третьей осуществляем непосредственно настройку по единице .

Модуль часов подключаем непосредственно к Ардуино, однако нога SQW подключается на прерывание. Принцип работы:

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

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

3

Однако есть и более простой способ реализовать часы

Синхронизация часов происходит при подключении их к ПК, ПК передает время на контроллер во время перепрошивки.

Для данного способа советуем использовать Shot Shield похожий на этот:

Вставьте Quad Display в разъёмы E и F. Пин CS подключите к пину номер 10 Arduino. Прошейте плату следующим программным кодом:

#include <QuadDisplay2.h>

// создаём объект класса QuadDisplay и передаём номер пина CS

QuadDisplay qd(10);

// создаем объекты класса bute для хранения текущего значения Часов, Минут, Секунд

int hours = 0;

int minutes = 0;

int seconds = 0;

// создаем объект класса long для хранения счетчика

long lastTime = 0;

 

void setup() {

// инициализация дисплея

qd.begin();

// инициализируем время

setTime(__TIMESTAMP__);

}

 

void loop() {

// как только разница между текущим временем и временем записанным в lastTime становится больше 1000 миллисекунд…

while(millis()-lastTime > 1000) {

//…обновляем lastTime и добавляем к счетчику Секунд +1

lastTime = millis();

seconds++;

// как только счетчик секунд достигнет 60, обнуляем его и добавляем к счетчику Минут +1…

if (seconds >= 60) {

seconds = 0;

minutes++;

}

// …тоже самое для Часов…

if (minutes >= 60) {

minutes = 0;

hours++;

}

// … и обнуляем счетчик Часов в конце дня

if (hours >= 24) {

hours = 0;

}

}

// выводим время на дисплей

qd.displayScore(hours, minutes, true);

}

 

// функция записи текущего времени в переменные

 

void setTime(const char* compileTimeStamp)

{

hours = ((compileTimeStamp[11] — ‘0’) * 10

+ (compileTimeStamp[12] — ‘0’));

 

minutes = ((compileTimeStamp[14] — ‘0’) * 10

+ (compileTimeStamp[15] — ‘0’));

 

seconds = ((compileTimeStamp[17] — ‘0’) * 10

+ (compileTimeStamp[18] — ‘0’));

}

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

 

Оцените статью
Информация об Ардуино
Добавить комментарий

Нажимая на кнопку "Отправить комментарий", я принимаю политику конфиденциальности.