Будильник своими руками: Часть 1 – Время, дата и день недели

Сейчас у всех есть телефоны и традиционные часы-будильники уже не так популярны, однако производители таких девайсов не сдаются и продолжают придумывать фишки, которые бы позволили им оставаться на плаву. Например, светобудильник, который синхронизируется с IPhone-ом:

20160305_220218Фактически это будильник + док станция. Я решил что мне нужен наподобие, только для Android-а… с беспроводной зарядкой… какой-нить весёленькой индикацией событий в телефоне… Ну и добавлю ещё каких-нить свистелок-перделок.

Первое, что нужно сделать – это конечно сами часы. Купил индикатор и часы реального времени (RTC) с батарейкой cr1220.

20160305_160942 20160305_160952

разместил это дело на макетке и подключил к Arduino

20160305_221732нашёл на сайте Амперки примеры для работы с часами реального времени и индикатором. Скачал библиотеки, необходимые для работы с ними и сделал простой скетч, который просто установил бы текущее время. Получилось примерно вот так:

20160305_222041Следующим шагом добавил кнопку, для изменения отображаемой информации и зуммер для индикации успешного нажатия. Для добавления Зуммера в свой проект не требуются дополнительной библиотеки – можно воспользоваться встроенной функцией tone.

Кнопку пока сделал как переключатель между временем, датой и днём недели. То есть по умолчанию “будильник” показывает часы и минуты, нажимаешь на кнопку – показывает дату, нажимаешь ещё раз – показывает день недели и так по кругу.

Вот как это выглядит и работает:

Ниже приведён полный исходный текст программы.

// библиотека для работы I²C
#include <Wire.h>
#include <QuadDisplay.h>
// библиотека для работы с часами реального времени
#include "TroykaRTC.h"

// EEPROM — энергонезависимая память
// библиотека для записи и считывания информации с EEPROM
#include <EEPROM.h>

// размер массива для времени с учётом завершающего нуля
#define DISPLAY_PIN 7 // Ножка QuadDisplay-я
#define KEY_PIN 8  // Ножка для кнопки
#define MODE_NUM 3  // Количество вариантов отображения инфы
#define FREQ 250  // Задержка в основном цикле
#define BUZ_PIN 11  // Ножка для зуммера

// создаём объект для работы с часами реального времени
RTC clock;

unsigned short mode = 0;

uint8_t dot = 0x4;

void setup()
{
  pinMode(KEY_PIN,INPUT);
  pinMode(BUZ_PIN,OUTPUT);

  Serial.begin(9600);
 
  // инициализация часов
  clock.begin();
  // метод установки времени и даты в модуль вручную
  // clock.set(10,25,45,27,07,2005,THURSDAY);
  // метод установки времени и даты автоматически при компиляции
  //clock.set(__TIMESTAMP__);
}

void loop()
{
  // Проверяем нажата ли кнопка
  if (digitalRead(KEY_PIN) == HIGH)
  {
    // Меняем индекс отображаемой инфорамции
    mode++;
    // Издаем короткий звук для подтверждения что нажатие кнопки считано
    tone(BUZ_PIN, 3500, 40);
  }

  // Проверяем не вышел ли наш индекс за границы
  if (mode == MODE_NUM)
    mode = 0;  // Если да то меняем на начальный

  // запрашиваем данные с часов
  clock.read();

  if (mode == 0)
    DisplayHourMinute(); // Отображаем Часы и Минуты
  else if (mode == 2)
    DisplayDate();  // Отображаем день и месяц
  else
    DisplayDay();   // Отображаем день недели

  delay(FREQ);
}

void DisplayHourMinute()
{
  int hm = clock.getHour() * 100 + clock.getMinute();  
  uint8_t dot = 0x4;  // Нам нужна точка между второй и третьей цифрами
  uint8_t sec = clock.getSecond();
  if (sec % 2) // Для эффекта мигания отображаем точку только
    dot = 0x0;  // на нечётной секунде
 
  displayInt(DISPLAY_PIN, hm,true,dot);
}

void DisplayDate()
{
  int dm = clock.getDay()*100 + clock.getMonth();
  displayInt(DISPLAY_PIN, dm, true, 0x4);
}

// Ниже я просто отображаю константы заданные в .h файле
// для часов, чтобы получились три буквы дня недели...
// ну или что-то похожее
void DisplayDay()
{
  uint8_t dow = clock.getDOW();
  if (dow == 7)
    displayDigits(DISPLAY_PIN, QD_NONE, QD_S, QD_U, QD_n);
  else if (dow == 1)
    displayDigits(DISPLAY_PIN, QD_NONE, QD_H, QD_O, QD_n);
  else if (dow == 2)
    displayDigits(DISPLAY_PIN, QD_NONE, QD_t, QD_U, QD_E);
  else if (dow == 3)
    displayDigits(DISPLAY_PIN, QD_NONE, QD_H, QD_E, QD_d);
  else if (dow == 4)
    displayDigits(DISPLAY_PIN, QD_NONE, QD_t, QD_h, QD_u);
  else if (dow == 5)
    displayDigits(DISPLAY_PIN, QD_NONE, QD_F, QD_r, QD_I);
  else
    displayDigits(DISPLAY_PIN, QD_NONE, QD_S, QD_a, QD_t);
    
}

Ещё одна полезная функция – это датчик влажности и температуры на основе уже знакомого мне DHT22.

20160130_130724Добавить его в проект не составляет труда: требуется один дополнительный пин,

#define DHT_PIN 6

новый объект для работы с датчиком,

#define DHT_TYPE DHT22

DHT dht(DHT_PIN,DHT_TYPE);

две процедуры DisplayTemperature() и DisplayHumidity(), которые будут отображать температуру и влажность соответственно и будут работать аналогично DisplyaHourMinute()

void DisplayHumidity()
{
  float h = dht.readHumidity();
  displayFloat(DISPLAY_PIN, h, 2, true);
}

void DisplayTemperature()
{
  float t = dht.readTemperature();
  displayFloat(DISPLAY_PIN, t, 2, true);
}

и изменение количество вариантов отображаемой информации с 3х на 5, так как устройство теперь может показывать температуру и влажность.

#define MODE_NUM 5

Правда на половинной макетке, которую я использовал для прототипирования закончилось место, и я решил воспользоваться Troyka Shield-ом для прототипирования, для того, чтобы вынести часы реального времени и зуммер и освободить место для датчика влажности и температуры:

20160329_224355И хотя конечная цель проекта – это спарить Arduino с Android-ом, думаю что возможность устанавливать дату, время и будильник независимо от наличия телефона тоже пригодиться.

Добавлять ещё одну кнопку мне было лень, поэтому решил, что долгое нажатие на уже существующую и будет переводить “будильник” в режим установки времени и даты, а однакратные нажатия будут изменять значения, но это уже в следующей “серии”.

1 thought on “Будильник своими руками: Часть 1 – Время, дата и день недели

  1. Pingback: Будильник своими руками: Част 2 – Пищалка | В поисках счастья

Leave a Reply