====== Как сделать ретро-часы Nixie Clock ======
В этой статье мы разберёмся, как сделать модные олдскульные часы Nixie Clock и при этом обойтись без дефицитных газоразрядных ламп. Вместо них используем акриловые пластины с выгравированными цифрами, которые подсветим адресными светодиодами WS2812B.
Если вы хотите приобрести светодиодные часы Nixie себе или в подарок, обратите внимание на готовый набор [[:nixie|Nixie Clock]].
===== Видеообзор =====
{{youtube>GA11S7jgIas?large}}
===== Что это? =====
Каждая цифра — это вырезанный лазерным резаком из прозрачного акрила толщиной 3 мм прямоугольник, на котором сделана гравировка. Если посветить в торец такого прямоугольника цветным светодиодом, то выгравированная цифра также начнёт светиться. Собрав 10 таких цифр в блок и подсвечивая каждую пластинку акрила отдельным светодиодом, можно по отдельности зажигать каждую цифру.
В качестве подсветки будем использовать адресные светодиоды WS2812B. Они занимают всего один контакт управляющей платы, при этом их можно объединить в цепочку и отдельно задавать яркость и цвет свечения каждому из них. Блоки цифр объединим по парам для отображения часов и минут. Управлять светодиодами будет Iskra Mini с Troyka-модулем часов реального времени.
===== Что понадобится? ======
* [[amp>product/iskra-mini?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Iskra Mini (с ногами)]]
* [[amp>product/troyka-mini-io?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Troyka Mini IO]]
* [[amp>product/troyka-rtc?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Часы реального времени (Troyka-модуль)]]
* [[amp>product/troyka-button?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Кнопка (Troyka-модуль)]]
* [[amp>product/troyka-potentiometer?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Потенциометр (Troyka-модуль)]]
* [[amp>product/usb-cable-micro?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Кабель USB (A — Micro USB)]]
* [[amp>product/power-supply-adapter-robiton-tn1000s?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Импульсный блок питания (1000 мА)]]
* [[amp>product/battery-cr1225?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Батарейка CR1225]]
* [[amp>product/troyka-pad-1x1?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Troyka Pad 1×1 (Troyka-модуль)]]
* [[amp>product/handle_olimp_11mm?utm_source=proj&utm_campaign=led-nixie-clock&utm_medium=wiki | Ручка для потенциометра «Олимп»]]
* Адресные светодиоды WS2812B (41 штука, но лучше взять с запасом)
* Прозрачный акрил. Фактическая толщина 2,93 мм.
* Чёрный непрозрачный акрил 3 мм.
Заказать лазерную резку акрила по своим чертежам можно на сервисе [[https://figuro.me|Figuro]]. А если хотите поработать на лазере самостоятельно — обратитесь, например, в [[http://fablab77.ru/#/equipment|ФАБ ЛАБ]].
===== Как собрать? =====
А вот и {{:projects:led-nixie-clock:led-nixie-clock.zip|векторные файлы CorelDRAW}} для резки. Обратите внимание, что я исходил из конкретной толщины прозрачного акрила (2,93 мм) и допусков, которые варьируются от материала к материалу и модели лазера.
- Каждая цифра будущих часов — отдельная пластинка из прозрачного акрила с двумя ножками для крепления и световодом, куда будет светить светодиод. {{ :projects:led-nixie-clock:1.png?nolink |}}
- Чтобы светодиоды не засвечивали соседние пластинки в блоке цифр, сделаем панель из чёрного непрозрачного акрила с отверстиями, ограничивающими световой поток. {{ :projects:led-nixie-clock:2.png?nolink |}}
- Вставим пластинки с цифрами в светоограничивающую панель. Туда же отправим разделительные точки для индикации хода часов. {{ :projects:led-nixie-clock:4.png?nolink |}} Снизу в панели будут видны торчащие световоды каждой из цифр. {{ :projects:led-nixie-clock:6.png?nolink |}} Длина этих световодов такая, чтобы светодиод прилегал к ним вплотную.
- Сделаем площадку для адресных светодиодов так, чтобы каждый из них светил точно в световод пластинки с цифрой, и наденем её на торчащие световоды. {{ :projects:led-nixie-clock:3.png?nolink |}}{{ :projects:led-nixie-clock:5.png?nolink |}}
- Обратите внимание, что у светодиодов есть один срезанный угол. Он нужен, чтобы сориентироваться, где какой контакт. {{ :projects:led-nixie-clock:clock_9.png?nolink |}} Распиновка светодиода WS2812B: {{ :projects:led-nixie-clock:ws2812b.png?nolink |}}
- Самое время установить светодиоды на свои места. Отогнём контактные ножки светодиодов, чтобы к ним было удобнее подпаяться, и вставим их в посадочные места.
- Спаяйте все светодиоды между собой, как показано на схеме, и подключите сигнальные провода к ''11'' и ''12'' пинам Iskra Mini. Нажмите на схему спайки, чтобы увеличить картинку.{{ :projects:led-nixie-clock:scheme_big.png?direct |}}
- Для точной работы часов добавим к Iskra Mini Troyka-модуль RTC. Это удобно сделать с помощью платы расширения Troyka Mini IO. {{ :projects:led-nixie-clock:7.png?nolink |}}
- Подключим кнопку и потенциометр. {{ :projects:led-nixie-clock:8.png?nolink |}}
- Теперь питание и линии DI светодиодов. {{ :projects:led-nixie-clock:9.png?nolink |}}
===== Исходный код =====
Осталось прошить Iskra Mini кодом программы.
[[продукты:iskra-mini#подключение_и_настройка|Как прошить Iskra Mini.]]
// библиотека для работы с адресными светодиодами
#include
// библиотека для работы I²C
#include
// библиотека для работы с часами реального времени
#include "TroykaRTC.h"
// библиотека для работы с кнопками
#include "TroykaButton.h"
// инициализируем подключенную кнопку
TroykaButton button(10);
// номер пина, к которому подключена RGB-матрица
#define MATRIX_PIN 11
// количество светодиодов в матрице
#define LED_COUNT 40
// инициализация цепочки светодиодов подсветки цифр
Adafruit_NeoPixel matrix = Adafruit_NeoPixel(LED_COUNT, MATRIX_PIN, NEO_GRB + NEO_KHZ800);
// инициализация светодиода разграничителя
Adafruit_NeoPixel dot = Adafruit_NeoPixel(1, 12, NEO_GRB + NEO_KHZ800);
// размер массива для времени
#define LEN_TIME 12
// размер массива для даты
#define LEN_DATE 12
// размер массива для дня недели
#define LEN_DOW 12
// создаём объект для работы с часами реального времени
RTC clock;
// переменные для мигания
int ledState = 0;
unsigned long previousMillis = 0;
unsigned long currentMillis ;
// массив для хранения текущего времени
char time[LEN_TIME];
// массив для хранения текущей даты
char date[LEN_DATE];
// массив для хранения текущего дня недели
char weekDay[LEN_DOW];
int hour;
int minute;
int one;
int two;
int three;
int four;
int displaysettings=0;
int red=150;
int green=200;
int blue= 50;
void setup()
{
// инициализация
button.begin();
matrix.begin();
dot.begin();
clock.begin();
// метод установки времени и даты в модуль вручную
// clock.set(hour,minute,0,27,07,2005,THURSDAY);
// метод установки времени и даты автоматически при компиляции
clock.set(__TIMESTAMP__);
// что бы время не менялось при прошивки или сбросе питания
// закоментируйте оба метода clock.set();
pinMode(10, INPUT_PULLUP);
}
void loop()
{
// считываем состояние кнопки
button.read();
// запрашиваем данные с часов
clock.read();
// считаем нажатия чтоб переходить из режима в режим
if (button.justPressed()){
displaysettings = displaysettings + 1;
}
if(displaysettings==0){
// сохраняем текущее время
hour = clock.getHour();
minute = clock.getMinute();
}
if(displaysettings == 1){
// присваиваем значение считываемое с потенциометра
hour = map (analogRead(A0),2, 1020, 0, 23);
clock.set(hour,minute,0,27,07,2005,THURSDAY);
}
if(displaysettings == 2){
// присваиваем значение считываемое с потенциометра
minute = map (analogRead(A0), 2, 1018, 0, 59);
clock.set(hour,minute,0,27,07,2005,THURSDAY);
}
if(displaysettings == 3){
// присваиваем значение считываемое с потенциометра
red = map (analogRead(A0),0, 1023, 0, 255);
}
if(displaysettings == 4){
// присваиваем значение считываемое с потенциометра
green = map (analogRead(A0),0, 1023, 0, 255);
}
if(displaysettings == 5){
// присваиваем значение считываемое с потенциометра
blue = map (analogRead(A0),0, 1023, 0, 255);
}
if(displaysettings == 6){
displaysettings = 0;
}
// делим минуты и часы на разряды
one = hour / 10;
two = hour % 10;
three = minute / 10;
four = minute % 10;
matrix.clear();
// зажигаем нужные светодиоды
matrix.setPixelColor(four, red, green, blue);
matrix.setPixelColor(three + 10, red, green, blue);
matrix.setPixelColor(two + 20, red, green, blue);
matrix.setPixelColor(one + 30, red, green, blue);
matrix.show();
// ждём одну секунду
delay(10);
// мигание разделителя
blinking();
}
void blinking(){
if (millis() - previousMillis >= 1000) {
previousMillis = millis();
if (ledState == 0) {
ledState = 1;
dot.setPixelColor(0, red, green, blue);
} else {
ledState = 0;
dot.setPixelColor(0, 0, 0, 0);
}
dot.show();
}
}