Big Clock One Love
Я никогда не хотел себе домой часы. Наручные или в телефоне — их вполне достаточно, чтоб ориентироваться во времени. А вот о какой-нибудь подсветке в комнату я периодически помышляю. При этом у меня, как и у многих других, стоит лампа на столе и с потолка свисает скушная люстра.
Сидеть в самоизоляции и полумраке — та ещё перспектива. Так светодиодная лента и картонные упаковки из Икеа на ресайклинг стали отличным условием «дано» для светодиодного табло, которое я полюбил.
Просто светильника — мало. Такой у меня уже есть. Я хотел, чтобы новый нёс какую-нибудь информацию. Например, мог отображать уровень температуры в комнате или что-то ещё…
Часы. Большие часы. Слышу доносящиеся откуда-то голоса, а воображение начинает выстраивать всяческие образы.
Самым простым и понятным мне показался вариант в виде семисегментных индикаторов. А что? Сделаю каркас из гофрокартона, нарежу отрезков светодиодной ленты и закреплю их на нём в форме восьмёрки. Звучит несложно.
Что для этого понадобится
Есть 100 вариантов, где можно достать железо для этого проекта. Никаких особых, редких или проприетарных модулей в нём нет; главное — концепция. Я, однако, работаю в Амперке, поэтому взял всё необходимое в конторе. Чего и вам желаю.
Итак, мой комплект:
Материалы:
Инструменты:
Как собрать
Я как ниндзя вырезал канцелярским ножом основу для будущего индикатора.
Подсвечивать каждый сегмент будет 10-сантиметровый отрезок светодиодной ленты, к которому я припаял пару проводов.
На одну из сторон индикатора (теперь она будет тыльной) наклеил дополнительные «прямоугольнички», вырезанные из того же картона вдоль рёбер жёсткости. Сквозь эти рёбра я пущу провода от сегментов.
Сейчас мне это кажется простым решением, а тогда я уже начинал аккуратненько замахиваться микроскопом по гвоздю, чтобы спрятать бухту торчащих проводов.
Рассеиватель для сегмента я сделал в форме цилиндра, который вырезал и свернул из обычной офисной бумаги А4 и склеил клеем-карандашом.
Готовые цилиндры приклеил к каркасу индикатора и пропустил провода в отверстия.
После того, как все цилиндры приклеены, можно заняться кабель-менеджментом и спрятать все провода внутрь заранее подготовленных каналов.
Торцы цилиндров я закрыл заглушками, вырезанными всё из того же картона.
Столько резки, склейки и прочего… Я начинал не выдерживать, поэтому резал эти кругляшки уже лазерным станком.
Иначе стоит запастись терпением, вырезая такое количество деталей канцелярским ножом.
Управление
Когда индикатор собран — самое время подумать, как им рулить.
И тут меня поджидало несколько «сюрпризов».
Сюрприз первый. Ток
Привычными индикаторами, каждый сегмент которых потребляет всего 20–30 мА, можно управлять напрямую контроллером. Например, с входов-выходов популярной Arduino Uno можно снять до 40 мА.
Каждый из сегментов моего индикатора потребляет в два раза больше допустимого тока Uno. Для управления ими придётся дополнительно использовать транзисторы или реле, способные пропустить через себя такой ток.
Реле — шумно и громоздко для такой задачи, а вот силовые ключи на MOSFET-транзисторах — кажется, то, что нужно.
Сюрприз второй. Контакты
Чтобы управлять одним индикатором, понадобится 7 выходов микроконтроллера. Четыре индикатора и разделитель — это 29, а у Ардуино Уно выходов всего 20.
В готовых индикаторных сборках используют выходные сдвиговые регистры — микросхемы для увеличения количества цифровых выходов. Они управляются тремя пинами, а на выходе дают целых восемь.
Третий сюрприз. Габариты
Собрав схему из восьми силовых ключей и сдвигового регистра, становится очевидно — такое управление много радости не принесёт.
Решение всех проблем!
С подобными задачами лучше всего справится модуль Octofet. Это компактная сборка из сдвигового регистра и 8-ми полевиков, каждый из которых может пропустить через себя пару ампер, выглядит гораздо веселее.
Подключение
Провода от каждого сегмента индикатора я подключил к клеммникам выходов Octofet«а.
А сам Octofet, чтобы не болтался, закрепил на основании, которое тоже вырезал из картона.
Подключать модули к Ардуино я буду через Troyka Shield. Остаётся просто соединить всё шлейфами.
Теперь, в зависимости от состояния транзисторов в сборке, на индикаторе должны будут загораться необходимые сегменты, тем самым отображая цифру.
Прошивка
Программировать контроллер буду через Arduino IDE.
Для работы с Octofet«ом и часами реального времени дополнительно надо будет скачать и установить пару библиотек.
Чтобы проверить, всё ли правильно собрано, в Arduino нужно загрузить тестовый скетч.
// библиотека для работы с модулями по интрефейсу SPI
#include
// библиотека для работы со сборкой силовых ключей
#include
// пин выбора устройства на шине SPI
#define PIN_CS 2
// кол-во сегментов в индикаторе
#define SEGMENT_COUNT 8
// префикс «0b» означает, что целое число за ним записано в
// в двоичном коде. Единицами мы обозначим номера сегментов
// индикатора, которые должны быть включены для отображения
// арабской цифры. Всего цифр 10, поэтому в массиве 10 чисел.
// Нам достаточно всего байта (англ. byte, 8 бит) для хранения
// комбинации сегментов для каждой из цифр.
byte numberSegments[10] = {
0b11101110, 0b00100100, 0b11110010, 0b10110110, 0b00111100,
0b10011110, 0b11011110, 0b00100110, 0b11111110, 0b10111110,
};
// создаём объект mosfet для работы со сборкой силовых ключей
// передаём номер пина выбора устройства на шине SPI
FET mosfet(PIN_CS);
void setup()
{
// начало работы с силовыми ключами
mosfet.begin();
}
void loop()
{
// определяем число, которое собираемся отображать. Пусть им
// будет номер текущей секунды, зацикленный на десятке
int number = (millis() / 1000) % 10;
// получаем код, в котором зашифрована арабская цифра
int mask = numberSegments[number];
// для каждого из 7 сегментов индикатора...
for (int i = 0; i < SEGMENT_COUNT; ++i) {
// ...определяем, должен ли он быть включён. Для этого
// считываем бит (англ. read bit), соответствующий текущему
// сегменту «i». Истина — он установлен (1), ложь — нет (0)
boolean enableSegment = bitRead(mask, i);
// включаем/выключаем сегмент на основе полученного значения
mosfet.digitalWrite(i, enableSegment);
}
}
Если всё сделано верно, заветные цифры начнут загораться на индикаторе.
Теперь можно соединить оставшиеся три индикатора в одну цепочку, добавить модуль часов реального времени и разделительный сегмент в виде точки.
Исходный код
Осталось научить получившийся четырёхразрядный индикатор показывать текущее время.
// библиотека для работы с модулями по интерфейсу SPI
#include
// библиотека для работы I²C
#include
// библиотека для работы со сборкой силовых ключей
#include
// библиотека для работы с часами реального времени
#include
// пин выбора сборки устройств на шине SPI
#define PIN_CS 2
// префикс «0b» означает, что целое число за ним записано в
// в двоичном коде. Единицами мы обозначим номера сегментов
// индикатора, которые должны быть включены для отображения
// арабской цифры. Всего цифр 10, поэтому в массиве 10 чисел.
// Нам достаточно всего байта (англ. byte, 8 бит) для хранения
// комбинации сегментов для каждой из цифр.
byte numberSegments[10] = {
0b11101110, 0b00100100, 0b11110010, 0b10110110, 0b00111100,
0b10011110, 0b11011110, 0b00100110, 0b11111110, 0b10111110,
};
// создаём объект mosfet для работы со сборкой силовых ключей
// передаём номер пина выбора устройств на шине SPI
// и количество устройств подключённых в цепочке
FET mosfet(PIN_CS, 4);
// создаём объект для работы с часами реального времени
RTC clock;
void setup() {
// начало работы с силовыми ключами
mosfet.begin();
// инициализация часов
clock.begin();
// метод установки времени и даты в модуль вручную
// clock.set(10,25,45,27,07,2005,THURSDAY);
// метод установки времени и даты автоматически при компиляции
clock.set(__TIMESTAMP__);
}
void loop() {
// запрашиваем данные с часов
clock.read();
// делим минуты и часы на разряды и отображаем на индикаторах
showDigit (0, clock.getHour() / 10);
showDigit (1, clock.getHour() % 10);
showDigit (2, clock.getMinute() / 10);
showDigit (3, clock.getMinute() % 10);
// мигаем разделителем
mosfet.digitalWrite(1, 0, HIGH);
delay(1000);
mosfet.digitalWrite(1, 0, LOW);
delay(1000);
}
void showDigit (int module, int digit ){
// получаем код, в котором зашифрована арабская цифра
int mask = numberSegments[digit];
// для каждого из 7 сегментов индикатора...
for (int i = 0; i < 8; ++i) {
// ...определяем, должен ли он быть включён. Для этого
// считываем бит (англ. read bit), соответствующий текущему
// сегменту «i». Истина — он установлен (1), ложь — нет (0)
boolean enableSegment = bitRead(mask, i);
// включаем/выключаем сегмент на основе полученного значения
mosfet.digitalWrite(module, i, enableSegment);
}
}
Чтобы после прошивки и включения часов время считывалось с модуля RTC,
закомментируйте оба методаclock.set()
и загрузите код снова;
То, что получилось, мне очень нравится. Зацените сами!
Добавлю сюда кнопку или даже ИК-приемник, чтобы дистанционно включать и выключать свет обычным пультом от телека или кондиционера. И будет вообще огонь!
Это лишь пример того, как поступил я. Вы можете сделать девайс по-своему. Добавьте сюда, что угодно! Модуль Bluetooth для настройки и управления, или звуковое оповещение зуммером, чтобы превратить часы в будильник. А лучше и то, и другое.
На этом у меня всё!
Пока!