Сейчас у всех есть телефоны и традиционные часы-будильники уже не так популярны, однако производители таких девайсов не сдаются и продолжают придумывать фишки, которые бы позволили им оставаться на плаву. Например, светобудильник, который синхронизируется с IPhone-ом:
Фактически это будильник + док станция. Я решил что мне нужен наподобие, только для Android-а… с беспроводной зарядкой… какой-нить весёленькой индикацией событий в телефоне… Ну и добавлю ещё каких-нить свистелок-перделок.
Первое, что нужно сделать – это конечно сами часы. Купил индикатор и часы реального времени (RTC) с батарейкой cr1220.
разместил это дело на макетке и подключил к Arduino
нашёл на сайте Амперки примеры для работы с часами реального времени и индикатором. Скачал библиотеки, необходимые для работы с ними и сделал простой скетч, который просто установил бы текущее время. Получилось примерно вот так:
Следующим шагом добавил кнопку, для изменения отображаемой информации и зуммер для индикации успешного нажатия. Для добавления Зуммера в свой проект не требуются дополнительной библиотеки – можно воспользоваться встроенной функцией 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.
Добавить его в проект не составляет труда: требуется один дополнительный пин,
#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-ом для прототипирования, для того, чтобы вынести часы реального времени и зуммер и освободить место для датчика влажности и температуры:
И хотя конечная цель проекта – это спарить Arduino с Android-ом, думаю что возможность устанавливать дату, время и будильник независимо от наличия телефона тоже пригодиться.
Добавлять ещё одну кнопку мне было лень, поэтому решил, что долгое нажатие на уже существующую и будет переводить “будильник” в режим установки времени и даты, а однакратные нажатия будут изменять значения, но это уже в следующей “серии”.
Pingback: Будильник своими руками: Част 2 – Пищалка | В поисках счастья