Big Clock One Love

  • Tutorial

BigClock.jpg


Я никогда не хотел себе домой часы. Наручные или в телефоне — их вполне достаточно, чтоб ориентироваться во времени. А вот о какой-нибудь подсветке в комнату я периодически помышляю. При этом у меня, как и у многих других, стоит лампа на столе и с потолка свисает скучная люстра.


Сидеть в самоизоляции и полумраке — та ещё перспектива. Так светодиодная лента и картонные упаковки из Икеа на ресайклинг стали отличным условием «дано» для светодиодного табло, которое я полюбил.


Просто светильника — мало. Такой у меня уже есть. Я хотел, чтобы новый нёс какую-нибудь информацию. Например, мог отображать уровень температуры в комнате или что-то ещё...


Часы. Большие часы. Слышу доносящиеся откуда-то голоса, а воображение начинает выстраивать всяческие образы.


Самым простым и понятным мне показался вариант в виде семисегментных индикаторов. А что? Сделаю каркас из гофрокартона, нарежу отрезков светодиодной ленты и закреплю их на нём в форме восьмёрки. Звучит несложно.


Что для этого понадобится


Есть 100 вариантов, где можно достать железо для этого проекта. Никаких особых, редких или проприетарных модулей в нём нет; главное — концепция. Я, однако, работаю в Амперке, поэтому взял всё необходимое в конторе. Чего и вам желаю.
Итак, мой комплект:


Материалы:



Инструменты:



Как собрать


Я как ниндзя вырезал канцелярским ножом основу для будущего индикатора.


ninja-cut.gif


Подсвечивать каждый сегмент будет 10-сантиметровый отрезок светодиодной ленты, к которому я припаял пару проводов.


led-wire.jpg


На одну из сторон индикатора (теперь она будет тыльной) наклеил дополнительные «прямоугольнички», вырезанные из того же картона вдоль рёбер жёсткости. Сквозь эти рёбра я пущу провода от сегментов.


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


Wire-chanel.jpg


Рассеиватель для сегмента я сделал в форме цилиндра, который вырезал и свернул из обычной офисной бумаги А4 и склеил клеем-карандашом.


cylinder.gif


Готовые цилиндры приклеил к каркасу индикатора и пропустил провода в отверстия.


join-cylinder.jpg


После того, как все цилиндры приклеены, можно заняться кабель-менеджментом и спрятать все провода внутрь заранее подготовленных каналов.


cable-management.gif


Торцы цилиндров я закрыл заглушками, вырезанными всё из того же картона.


stub.jpg


Столько резки, склейки и прочего… Я начинал не выдерживать, поэтому резал эти кругляшки уже лазерным станком.


laser-cut.jpg


Иначе стоит запастись терпением, вырезая такое количество деталей канцелярским ножом.


Управление


Когда индикатор собран — самое время подумать, как им рулить.
И тут меня поджидало несколько «сюрпризов».


Сюрприз первый. Ток


Привычными индикаторами, каждый сегмент которых потребляет всего 20-30 мА, можно управлять напрямую контроллером. Например, с входов-выходов популярной Arduino Uno можно снять до 40 мА.


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


commutation.jpg


Реле — шумно и громоздко для такой задачи, а вот силовые ключи на MOSFET-транзисторах — кажется, то, что нужно.


Сюрприз второй. Контакты


Чтобы управлять одним индикатором, понадобится 7 выходов микроконтроллера. Четыре индикатора и разделитель — это 29, а у Ардуино Уно выходов всего 20.


В готовых индикаторных сборках используют выходные сдвиговые регистры — микросхемы для увеличения количества цифровых выходов. Они управляются тремя пинами, а на выходе дают целых восемь.


display.jpg


Третий сюрприз. Габариты


Собрав схему из восьми силовых ключей и сдвигового регистра, становится очевидно — такое управление много радости не принесёт.


a-lot-of-fets.jpg


Решение всех проблем!


С подобными задачами лучше всего справится модуль Octofet. Это компактная сборка из сдвигового регистра и 8-ми полевиков, каждый из которых может пропустить через себя пару ампер, выглядит гораздо веселее.


octofet.jpg


Подключение


Провода от каждого сегмента индикатора я подключил к клеммникам выходов Octofet’а.


Connection.png


А сам Octofet, чтобы не болтался, закрепил на основании, которое тоже вырезал из картона.


connectOctofet.jpg


Подключать модули к Ардуино я буду через Troyka Shield. Остаётся просто соединить всё шлейфами.


Arduino-Test-Connection.png


Теперь, в зависимости от состояния транзисторов в сборке, на индикаторе должны будут загораться необходимые сегменты, тем самым отображая цифру.


bitmap.gif


Прошивка


Программировать контроллер буду через Arduino IDE.
Для работы с Octofet’ом и часами реального времени дополнительно надо будет скачать и установить пару библиотек.



Чтобы проверить, всё ли правильно собрано, в Arduino нужно загрузить тестовый скетч.


// библиотека для работы с модулями по интрефейсу SPI
#include <SPI.h>
// библиотека для работы со сборкой силовых ключей
#include <AmperkaFET.h>
// пин выбора устройства на шине 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);
  }
}

Если всё сделано верно, заветные цифры начнут загораться на индикаторе.


singleDigit.gif


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


fullSchem.png


Исходный код


Осталось научить получившийся четырёхразрядный индикатор показывать текущее время.


// библиотека для работы с модулями по интерфейсу SPI
#include <SPI.h>
// библиотека для работы I²C
#include <Wire.h>
// библиотека для работы со сборкой силовых ключей
#include <AmperkaFET.h>
// библиотека для работы с часами реального времени
#include <TroykaRTC.h>
// пин выбора сборки устройств на шине 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() и загрузите код снова;

То, что получилось, мне очень нравится. Зацените сами!


i-did-it.jpg


Добавлю сюда кнопку или даже ИК-приемник, чтобы дистанционно включать и выключать свет обычным пультом от телека или кондиционера. И будет вообще огонь!


Это лишь пример того, как поступил я. Вы можете сделать девайс по-своему. Добавьте сюда, что угодно! Модуль Bluetooth для настройки и управления, или звуковое оповещение зуммером, чтобы превратить часы в будильник. А лучше и то, и другое.


На этом у меня всё!


Пока!

Comments 33

    +10
    Очень странная тенденция в среде DIY — «если для чего-то не существует модуля, это нельзя сделать». Несмотря на работу на достаточно низком уровне, люди перестают думать, как оно там работает, и просто берут модули, соединяя в кучку. А потом идут в коммерческую разработку и рождают чудовищ.
    Я понимаю, что это корпоративный блог, но хотелось бы хотя бы упомянуть о том, что подключить транзисторы к сдвиговому регистру — это просто, и можно сделать самому, не воспринимая эти модули как нечто, данное высшими силами.
    А кроме этого, почему не использовать WS2812 или аналоги?
      +4
      На WS2812 есть планы, а эта лента у меня была дома.
      Её находка и стала поводом сделать такой ночничок. Не пропадать же ей.

      Подробную информацию о том, как это работает, можно найти на нашей вики. Мне же хотелось скорее поделиться самим детищем и восторгом от того, что получилось. Справочной информации и так достаточно.
        +3
        Спасибо, что поделились своим восторгом. Питаю слабость к крупным часам, а технология изготовления индикаторов вполне повторима.
        Лазерный станок, несомненно, дело в хозяйстве нужное, однако аккуратных кругляшков из картона (а также резины, паронита и прочая) можно нарубить и просечкой.

        Просечка
          +1
          За просечку (пробойник) 5+
          Но просечка обычно бывает диаметром до 0,5 дюйма, а дальше приходится ножничками :)
          p.s. Пробойником удобно внутренние(и-е еле вспомнЕл) отверстия пробивать, а внешние — НОЖНИЦЫ.
            +2
            для картона и бумаги можно сообразить «циркуль» из пластиковой полоски:
            image
            Источник
              0
              Прикольно! Спасибо. Мне нравятся такие штучки.
        +4
        Потому что корпоративный блог Амперки, а не SHININGLED.
        +4
        Светодиодная лента 1 290 ₽
        Arduino Uno 1 990 ₽
        Импульсный блок питания 1 290 ₽
        Часы реального времени 440 ₽
        Сборка силовых ключей P-FET 990 ₽х4
        Итого 8970 ₽.
        Не дороговато для DIY часов?
          0

          Ардуину у китайцев можно взять собранную по тем же чертежам из тех же (или нет, если не повезёт) деталей где-то так на порядок дешевле, ленту — там же.
          До кучи лента, блок питания — обычно у DIYщика валяются россыпью на балконе в коробке с надписью "ну а вдруг".
          RTC у китайцев тоже подешевле будет.
          Сборка ключей — единственный компонент хрен знамо зачем, ибо это всё делается на макетке из россыпи транзисторов за сотку-две и пары 74HC595 в течение часа. Но это, опять же, корпоративный рекламный блог амперки, а не личный блог "дёшево, сердито и с получением знаний по теме".

            +2
            До кучи лента, блок питания — обычно у DIYщика валяются россыпью на балконе в коробке с надписью «ну а вдруг».

            Справедливости ради замечу, что от этого они бесплатными не становятся.
          0

          Слегка по коду заинтересовало.


            // метод установки времени и даты автоматически при компиляции
            clock.set(__TIMESTAMP__);

          Сдаётся мне, что несмотря на наличие батарейки в RTC модуле, при любом отключении питания часы будут слетать на дату сборки в момент следующего включения.
          Лучше это завернуть в какой-то if, чтобы устанавливать время только, если оно раньше даты сборки прошивки, так как тогда оно очевидно неправильное.


          boolean enableSegment = bitRead(mask, i);

          Откуда взялась эта функция? Почему бы не использовать просто оператор смещения, если для неё нужно подтягивать внешнюю библиотеку?

            0
            Почему бы не использовать просто оператор смещения, если для неё нужно подтягивать внешнюю библиотеку?


            Потому что ардуино — это про готовые блоки, а не «я знаю как собрать сдвиговые регистры на рассыпухе/я знаю как получить бит числа смещением».
              0
              А можно подробнее — какая функция и какая внешняя библиотека?
                +1

                Ниже уже подсказали, что она встроенная в стандартную. Функция bitRead.

                0
                Почему бы не использовать просто оператор смещения, если для неё нужно подтягивать внешнюю библиотеку?


                Не надо ничего подтягивать

                arduino-1.8.8/hardware/arduino/avr/cores/arduino/Arduino.h:
                #define bitRead(value, bit) (((value) >> (bit)) & 0x01)


                  0
                  Идея с if классная. Я же решил просто закомментировать метод. Таков мой путь наименьшего сопротивления.
                  0
                  Идея с реализацией индикаторов часов классная. Но это на фоне готовых модулей по цене 1к-2к убивает изящность проекта. Либо делать все по дендрально-фикальной технологии, либо по ИлонноМасочной с 3d печатью, VR, и прочими высокотехнологическими плюшками. /сарказмOFF
                    +3
                    либо по ИлонноМасочной с 3d печатью, VR, и прочими высокотехнологическими плюшками

                    image
                    +2
                    Ах да, кстати не всегда сдвиговые ригистры используются. Засветить индикаторы можно и динамической индикацией.
                      0
                      Кстати, это первое, что приходит в голову.
                      Правда вторая мысль — «а может, мерцание будет на большом-то размере — ведь заявлено в первую очередь как светильник».
                      Третья — так можно ж частоту сканирования задрать под сотню кГц, и к каждой ленте конденсатор поставить, вообще пульсации не всякий прибор заметит.
                      0
                      Реле — шумно и громоздко для такой задачи

                      Если не динамическая подсветка, то может быть интересный эффект — своеобразное «тиканье» часов раз в минуту. Или сделать только для второй цифры — раз в час. И на слух можно будет узнавать который час прощелкал.
                        0
                        Хорошая идея! Взял на заметку.
                        +1
                        <Зануда>
                        Интересно: авторы хоть когда-нибудь перестанут называть припой «оловом»? На страничке по ссылке, кстати, слово «олово» не вдруг найдешь, там эта вещь называется (внезапно!) «припой».
                        Флюс, почему-то, называют «флюсом», а не «канифолью», а «припой» уже ниасилили…
                        </Зануда>
                          0
                          Справедливое замечание! Я как-то даже не обратил на это внимания. Видимо часто на слуху.
                            0
                            Ну формально в «зелёных» бессвинцовых припоях олово то осталось.
                            +3
                            Смахнуть пыль с конструкции — квест. Не подпустить к конструкции кота — нереальный квест ;).
                              +1
                              Там еще третий квест будет — оперативно подклеивать, когда все это от нагрева расклеиваться будет.

                              По моему мнению, клей-карандаш — далеко не лучший клей, а бумага — не лучший выбор, когда мы говорим о 12В светодиодных лентах.
                                +1
                                Нагрева вообще нет. Не такая мощная там лента. А материальная база была только из картона которым я запасся, чтоб поиграться лазером.
                                0
                                Про это будет отдельный рассказ.
                                +1
                                Часы получились клевые. Если бы я работал у вас в Амперке, я бы тоже много чего бы набрал «в конторе» для поделок.
                                  0
                                  Спасибо! Вот и я решил не упускать такую возможность.
                                  0
                                  Хоть и раз в минуту, но мигающий ночник не мешает спать/не вызывает раздражения?
                                    0
                                    Смотрится красиво. И статья написана подробно, с анимированными картинками. С удовольствием плюсую (считайте, что дважды).

                                    Only users with full accounts can post comments. Log in, please.