Круглые часы на адресной светодиодной ленте

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Всем здравствуйте! В общем, пришла идея сварганить часы, но семисегментники как-то не интересовали. В общем, дотумкал до вот такой конструкции :



DSC_0398.JPG

Конструкция из себя представляет следующее:
Ардуино нано
Непрозрачное колесо с пазом под адресную светодиодку (2812, 60диодов/метр);
Крышка паза с отверстиями под рассеиватели;
И сами рассеиватели.

Посмотреть вложение 498

Нарисовано в SolidWork 2015 и распечатано небольшими сегментами (маленький 3д принтер у меня), подточено и склеено.

И, собственно, хочу обратиться к сообществу: помогите с прошивочкой. Кодер из меня никакой, только недавно решил побаловаться программированием, да и то опосля видосов Алекса про светомузыки и околоардуиновские приколюхи.
На текущий момент часики идут с точностью примерно около +/-5минут в сутки, с модулем DS3231 пока подружиться не смог. Или модуль у меня багнутый, помимо кривизны рук, хз короче.
Подставка/подвес тоже еще не придуман, на проводочке от ленты висит, прищепкой прижат)
 

Вложения

  • Лойс +1
Реакции: EandV

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Собственно, ежели чертежи нужны или стл-ки - выложу, не проблема.
Ну, и заранее спасибо откликнувшемся! (ток про код не надо, сам знаю:))

Ай, валенок, забыл уточнить, что именно мне не даётся... В обычных мех. часах часовая стрелка плавно шевелится, как полагается. В данной конструкции можно смещать только каждые 12 минут, и вроде все растёт, но переход через 0 (12) часов - и писесь. Как его победить? Во вложенном скетче этого нету, ибо меня этот кусочек выбесил и я его даже не сохранял. Вот.
 
Последнее редактирование:

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Все привет. Замутил простенькую подставочку, теперь часы почти как человеческие выглядят.

Подставк.jpg

IMG_20180915_110118.jpgIMG_20180915_110127.jpgIMG_20180915_110142.jpg

Правда, несколько маловата коробочка получилась, ну да и хрен с ним. Может, нарисую/напечатаю поболее, что бы в подставке тайник пожирнее был. Крышки снизу нет, так пока поживет.


Хех, почти готовый прожект получается.... Ток мозги им вправить осталось, но это со временем произойдет:)
 
  • Лойс +1
Реакции: rick85

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
@feniragon, слухай, друже, я аж помыслить, что подсказка к программированию нарисовалась))) а смотрятся весьма кошерной, можно сильно стилизовать. Я чпу-шку как дособеру, так ещё вариант исполнения покажу.
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len, чтобы помочь с кодом - нужно от чего-то отталкиваться. С нуля врядли кто поможет..
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len, сорян не заметил. Посмотрел - пока что раздражает и мешает слишком много магических цифр. Если пойму что-то отпишу
 

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Я вечером выложу читабельный вариант с комментами, не дотумкал сразу
 

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
//17:11 start timing - это пометка для "опытного пути" настройки счетчика
#include <SPI.h>

#include "Adafruit_NeoPixel.h"
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 12, NEO_GRB + NEO_KHZ800);

int m = 0; //минуты
int h = 0; //часы
#define keyHor 5 //кнопки
#define keyMin 4
unsigned long timing; //для счетчика времени
unsigned long pause; //для обработки кнопок




void setup() {
Serial.begin(9600);


strip.begin(); // Функция begin() настроит порт Arduino и выставит значения по умолчанию.
strip.show(); // Функция show() передаст команду на выключение всем пикселям.
//strip.setBrightness(64);
int r = 10; //сделано для упрощения подбора цветов и яркости
int g = 10;
int b = 10;
int i = 0;
int plus = 50;
pinMode(keyHor, INPUT_PULLUP);
pinMode(keyMin, INPUT_PULLUP);
timing = millis();
pause = millis();

}

void loop() {
int r = 10; //не знаю, нахрена дублируется, ну да пофиг
int g = 10;
int b = 10;
int plus = 50; //а вот этой фигней делаем выделяющиеся сегменты
int reg = 0; // регистр "сдвига". по задумке должен был меняться на значения от 0 до 4 каждые 12 минут

if (millis() - timing > 50997) { //опытным путем подобранная "минута"
timing = millis();
Serial.println(timing); //собссно, "опытный путь"
m++;
Serial.print("__");
Serial.print(m);
if (m > 59){
h++;
m = 0;

}
}

if (h > 11){
h = 0;
}

int i = 0;
for (i = 0; i<=59; i++){
strip.setPixelColor(i, r, g, b ); //заливаем контур (60 светодиодов)
strip.setPixelColor(5, 0, g + plus, b ); //выделяем 12 сегментов (они зеленоватые на фотке
strip.setPixelColor(10, 0, g + plus, b );
strip.setPixelColor(15, 0, g + plus, b );
strip.setPixelColor(20, 0, g + plus, b );
strip.setPixelColor(25, 0, g + plus, b );
strip.setPixelColor(30, 0, g + plus, b );
strip.setPixelColor(35, 0, g + plus, b );
strip.setPixelColor(40, 0, g + plus, b );
strip.setPixelColor(45, 0, g + plus, b );
strip.setPixelColor(50, 0, g + plus, b );
strip.setPixelColor(55, 0, g + plus, b );
strip.setPixelColor(0, 0, g + plus, b );
}


strip.setPixelColor(h*5, 250 ,0 ,0 ); //обрабатываем и рисуем часы (по 3 светодиода, светят красным)
if (h == 0){
strip.setPixelColor(59, 250 ,0 ,0 ); //вот это для корректного отображения 12 часов
strip.setPixelColor(h*5, 250 ,0 ,0 );
strip.setPixelColor(h*5+1, 250 ,0 ,0 );
}
else {
strip.setPixelColor(h*5-1, 250 ,0 ,0 ); //для всех остальных часов
strip.setPixelColor(h*5 , 250 ,0 ,0 );
strip.setPixelColor(h*5+1, 250 ,0 ,0 );

}
// if (h != 0){ вот это остаток от попытки реализовать ту фигню, о которой просил помочь
// strip.setPixelColor(h*5-1+ reg, 250 ,0 ,0 );
// strip.setPixelColor(h*5+reg , 250 ,0 ,0 );
// strip.setPixelColor(h*5+1+reg, 250 ,0 ,0 );

// }


strip.setPixelColor(m, 250 ,0 ,250 ); //Рисуем "минуту"


strip.show(); //заливаем картинку

// обработка кнопок
if (millis() - pause > 200) {
pause = millis();
if (!digitalRead(keyHor)){
h++;
}
if (!digitalRead(keyMin)){
m++;
}
}
}


А хотел я, соббсно, что бы часовая "стрелка" смещелась на один светодиод каждые 12 минут. Меня попытка это реализовать чуть до сумашествия не довела:)
 
Последнее редактирование:

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Тут на картинке время без 2 минут 6, а часовая стрелк на 5 стоит. путаешься иногда. Нумерация на картинке - это типа часы. а так диоды с 0 до 59 по часовой

11.jpg


Хех, еще одна хрень выползла))) Пока часы висели на проводочке - было хорошо. А с подставочкой 0 светодиод-то теперь внизу, мативо.
теперь в половину "какого-нибудь" часовая стрелк перещелкивается)) во хрень, блин, надо покубатурить


Покубатурил. и воткнул
if (m == 30){
h++;
}



вместо

if (m > 59){
h++;


Вроде работает:)
 
Последнее редактирование:

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Очередные попытки заставить часовую стрелочку двигаться не привели ни к чему. Ниже привожу скетч, там пыталась эта затея реализоваться, закомментированные участки - это мои потуги:confused:
#include <SPI.h>

#include "Adafruit_NeoPixel.h"
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 6, NEO_GRB + NEO_KHZ800);

int m = 0; //минуты
int h = 0; //часы
byte z = 0;
#define keyHor 5 //кнопки
#define keyMin 4
unsigned long timing; //для счетчика времени
unsigned long pause; //для обработки кнопок




void setup() {
Serial.begin(9600);


strip.begin(); // Функция begin() настроит порт Arduino и выставит значения по умолчанию.
strip.show(); // Функция show() передаст команду на выключение всем пикселям.
//strip.setBrightness(64);
int r = 10; //сделано для упрощения подбора цветов и яркости
int g = 10;
int b = 10;
int i = 0;
int plus = 50;
pinMode(keyHor, INPUT_PULLUP);
pinMode(keyMin, INPUT_PULLUP);
timing = millis();
pause = millis();

}

void loop() {
int r = 10; //не знаю, нахрена дублируется, ну да пофиг
int g = 10;
int b = 10;
int plus = 50; //а вот этой фигней делаем выделяющиеся сегменты
//int z = 0; // регистр "сдвига". по задумке должен был меняться на значения от 0 до 4 каждые 12 минут

if (millis() - timing > 100) { //опытным путем подобранная "минута"
timing = millis();
//Serial.println(timing); //собссно, "опытный путь"
m++;
//Serial.print("__");
//Serial.print(m);
if (m > 59){
h++;
m = 0;
/*
if (m < 12){
z = 0;
}
if (m >= 12, m < 24){ // вот с этим кусочком и тем, что ниже (с переменной z) начинается разброд и шатания
z = 1;
}
if (m >= 24, m < 36){
z = 2;
}
if (m >= 36, m < 48){
z = 3;
}
if (m >= 48, m < 59){
z = 4;
}
if (z>4){
z = 0;
} */
}
}

if (h > 11){
h = 0;
}

int i = 0;
for (i = 0; i<=59; i++){
strip.setPixelColor(i, r, g, b ); //заливаем контур (60 светодиодов)
strip.setPixelColor(5, 0, g + plus, b ); //выделяем 12 сегментов (они зеленоватые на фотке
strip.setPixelColor(10, 0, g + plus, b );
strip.setPixelColor(15, 0, g + plus, b );
strip.setPixelColor(20, 0, g + plus, b );
strip.setPixelColor(25, 0, g + plus, b );
strip.setPixelColor(30, 0, g + plus, b );
strip.setPixelColor(35, 0, g + plus, b );
strip.setPixelColor(40, 0, g + plus, b );
strip.setPixelColor(45, 0, g + plus, b );
strip.setPixelColor(50, 0, g + plus, b );
strip.setPixelColor(55, 0, g + plus, b );
strip.setPixelColor(0, 0, g + plus, b );
}


//strip.setPixelColor(h*5, 250 ,0 ,0 ); //обрабатываем и рисуем часы (по 3 светодиода, светят красным)
if (h == 0){
strip.setPixelColor(59, 250 ,0 ,0 ); //вот это для корректного отображения 12 часов
strip.setPixelColor(h*5, 250 ,0 ,0 );
strip.setPixelColor(h*5+1, 250 ,0 ,0 );
}
else {
strip.setPixelColor((h*5)-1, 250 ,0 ,0 ); //для всех остальных часов
strip.setPixelColor((h*5), 250 ,0 ,0 );
strip.setPixelColor((h*5)+1, 250 ,0 ,0 );

}
// if (h != 0){ вот это остаток от попытки реализовать ту фигню, о которой просил помочь
// strip.setPixelColor(h*5-1+z, 250 ,0 ,0 );
// strip.setPixelColor(h*5+z , 250 ,0 ,0 );
// strip.setPixelColor(h*5+1+z, 250 ,0 ,0 );

// }


strip.setPixelColor(m, 250 ,0 ,250 ); //Рисуем "минуту"


strip.show(); //заливаем картинку
Serial.println(" ");
Serial.print(h);
Serial.print(" ");
Serial.print(m);
Serial.print(" ");
Serial.print(z);

// обработка кнопок
if (millis() - pause > 200) {
pause = millis();
if (!digitalRead(keyHor)){
h++;
}
if (!digitalRead(keyMin)){
m++;
}
}
}

Скажите, люди добрые, куда копать?
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len, 1. Я лично все еще не понял что у тебя не получается. 2, Проверь отдельно модуль - правильно ли работает? (просто выводи значение в сериал)
3. Внутри loop выпиливай, Лишнее действие.
C++:
int r = 10; //не знаю, нахрена дублируется, ну да пофиг
int g = 10;
int b = 10;
4. И я все еще не понимаю твои магические числа. Сделай дефайнами - будет понятнее и тебе и мне.

if (millis() - timing > 50997) { //опытным путем подобранная "минута" -- вот что это за фигня? Для чего? Лучше бы поставил комменты с объяснением что ты хотел сделать в каждом блоке...

5, И еще раз объясни, что не получается? не двигается минутная стрелка каждую минуту, а часовая каждый час?
 

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
@feniragon,


2 - В порт модуль все выводит, вроде ништяк.
3 - Дубликат убрал.
4 - Я не знаю, для чего можно юзать дефайны, извиняй))
- if (millis() - timing > 50997) { //опытным путем подобранная "минута" -
- у меня в конструкции модуля часов нет. Ход часов организован на
- самуй дуинке. Логично предположить, что 60000 миллисекунд = 1 минута.
Но нифига, при значении в 60к за 20 минут реального времени
эта конструкция вместе со всей подноготной могла насчитать только
17 минут. Поэтому такое странное (причем еще и усредненное) значение.
Не знаю, куда 9 секунд девается.

Блин, как бы еще объяснить понятно, да не запутаться...

В общем, по блокам:


int r = 10; //не знаю, нахрена дублируется, ну да пофиг
int g = 10;
int b = 10;

Сие цвет всей ленты по дефолту. В каждом цикле отрисовки они определяются
в первую очередь.
for (i = 0; i<=59; i++){
strip.setPixelColor(i, r, g, b );

Далее из всей ленты выделяются сегменты, 12 штук, для визуального понимания
происходящего (сегменты соответствуют положению часовой стрелки в
1,2, ...12 часов)
strip.setPixelColor(5, 0, g + plus, b );
strip.setPixelColor(10, 0, g + plus, b );
strip.setPixelColor(15, 0, g + plus, b );
strip.setPixelColor(20, 0, g + plus, b );
strip.setPixelColor(25, 0, g + plus, b );
strip.setPixelColor(30, 0, g + plus, b );
strip.setPixelColor(35, 0, g + plus, b );
strip.setPixelColor(40, 0, g + plus, b );
strip.setPixelColor(45, 0, g + plus, b );
strip.setPixelColor(50, 0, g + plus, b );
strip.setPixelColor(55, 0, g + plus, b );
strip.setPixelColor(0, 0, g + plus, b );
Где plus - смещение по цвету. Согласен, через очко сделано, но мне на тот момент
это было понятно и удобно.


Далее, поверх пустого "циферблата" обозначаем положение часовой стрелки
strip.setPixelColor(h*5, 250 ,0 ,0 );
if (h == 0){
strip.setPixelColor(59, 250 ,0 ,0 ); //вот это для корректного отображения 12 часов
strip.setPixelColor(h*5, 250 ,0 ,0 );
strip.setPixelColor(h*5+1, 250 ,0 ,0 );
}
else {
strip.setPixelColor(h*5-1, 250 ,0 ,0 ); //для всех остальных часов
strip.setPixelColor(h*5 , 250 ,0 ,0 );
strip.setPixelColor(h*5+1, 250 ,0 ,0 );
Где первая строка - это по недоразумению не удаленная, первый вариант часовой стрелки
рисовался одним светодиодом
А далее вот что: зарисовываем красным положение часовой стрелки и
рядом стоящие. Иначе минутная перерисовывала часовую (в случае с отображением одним светодиодом)
Только для 12 часов исключение - там должны светиться 0,1 и 59 диод, функцию такую мне сваять
не под силу.

"рисуем" минуту
strip.setPixelColor(m, 250 ,0 ,250 );

И выводим все нарисованное на ленту
strip.show();

Собственно, вот и действующий алгоритм.
В ускоренном виде (и без части рассеивателей, но и так должно быть понятно) выглядит так:
https://cloud.mail.ru/public/JgDw/tB615BDtm
Извиняйте, не знаю, как правильно воткнуть видеозапись.
Циферблат такой конструкции подразумевает плавное (или относительно плавное) перемещение
часовой стрелки, а тут она резко перепрыгивает с, например, 6 на 7 часов. Я же же хотел реализовать
смещение на один диод каждые 12 минут. Для этого добавил
int z = 0;

и пытался его использовать вот так:

if (m < 12){
z = 0;
}
if (m >= 12, m < 24){
z = 1;
}
if (m >= 24, m < 36){
z = 2;
}
if (m >= 36, m < 48){
z = 3;
}
if (m >= 48, m < 59){
z = 4;
}
.................
// strip.setPixelColor(h*5-1+z, 250 ,0 ,0 );
// strip.setPixelColor(h*5+z , 250 ,0 ,0 );
// strip.setPixelColor(h*5+1+z, 250 ,0 ,0 );

И тут (данные я в сом порт выводил) с этой переменной z творилось все, что угодно, но не то, что нужно.
 
Последнее редактирование:

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len,
Я посмотрю детально код, но сразу же хрень:
C++:
int i = 0;
for (i = 0; i<=59; i++){
    strip.setPixelColor(i, r, g, b ); //заливаем контур (60 светодиодов)
    strip.setPixelColor(5, 0, g + plus, b ); //выделяем 12 сегментов (они зеленоватые на фотке
    strip.setPixelColor(10, 0, g + plus, b );
    strip.setPixelColor(15, 0, g + plus, b );
    strip.setPixelColor(20, 0, g + plus, b );
    strip.setPixelColor(25, 0, g + plus, b );
    strip.setPixelColor(30, 0, g + plus, b );
    strip.setPixelColor(35, 0, g + plus, b );
    strip.setPixelColor(40, 0, g + plus, b );
    strip.setPixelColor(45, 0, g + plus, b );
    strip.setPixelColor(50, 0, g + plus, b );
    strip.setPixelColor(55, 0, g + plus, b );
    strip.setPixelColor(0, 0, g + plus, b );
}
ты 60 раз заливаешь i пиксель и каждый 5й.. закрывающая скобка не там. Делай отступы и будет проще

Вместо этого можно так:
C++:
    for (i = 0; i < 60; i++)
        strip.setPixelColor(i, r, g, b ); //заливаем контур (60 светодиодов)
    for (i = 0; i < 60; i = i+5)
        strip.setPixelColor(i, 0, g + plus, b);//выделяем 12 сегментов (они зеленоватые на фотке
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len,
2 - В порт модуль все выводит, вроде ништяк.
Логично предположить, что 60000 миллисекунд = 1 минута.
Но нифига, при значении в 60к за 20 минут реального времени
эта конструкция вместе со всей подноготной могла насчитать только
17 минут. Поэтому такое странное (причем еще и усредненное) значение.
Не знаю, куда 9 секунд девается.
Так в порт нормально сыпет минуты или нет??

Кроме того, он тебе дает 12 или 0 часов?
Тогда в первом условии "f (h == 0){ " надо учесть.
C++:
if (h == 0 || h == 12){
    strip.setPixelColor(59, 250 ,0 ,0 ); //вот это для корректного отображения 12 часов
    strip.setPixelColor(0, 250 ,0 ,0 );
    strip.setPixelColor(1, 250 ,0 ,0 );
}
 
Последнее редактирование:

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
Я не засекал расхождения между реальным временем и тем, что пишется в порт. Тупо включил, настроил и ушел. Пришел, увидел разницу, немного математики и все. Оставлял на сутки в среднем. Ровно в полночь замер расхождения и коррекция. Кстати, да, надо было оставлять открытый порт и зырить... Кстати, в порт писало от 60004 до 60012 мс
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len,

Что в этом куске ты хотел сделать?
C++:
if (millis() - pause > 200) {
pause = millis();
if (!digitalRead(keyHor)){
h++;
}
if (!digitalRead(keyMin)){
m++;
}
}
Вот так ?

C++:
    if (millis() - pause > 200) {
        pause = millis();
        if (!digitalRead(keyHor)){
            h++;
        }
        if (!digitalRead(keyMin)){
            m++;
        }
    }
Или так?
C++:
    if (millis() - pause > 200) {
        pause = millis();
    }
    if (!digitalRead(keyHor)){
        h++;
    }
    if (!digitalRead(keyMin)){
        m++;
    }
 
Последнее редактирование:

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
@feniragon, так вроде разница только в удобстве ориентирования в коде, а функционал вроде не меняется.... Согласен, с чистописанием проблемы)
Кнопки, часы подводить, больше ничего я тут не планировал реализовывать
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
@seve_len, Нет, разница огромная. В первом случае у тебя происходят изменения в h, m, pause если millis() - pause > 200
во втором случае h и m не зависят от этого условия. Скобки же. Я не даром написал про отступы. Наглядно видны уровни вложенности

Та же история что и с начальной заливкой цветом ленты
 

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
ааа, я второй вариант не узрел. пауза нужна, слишком быстро изменяются h и m без неё, потому и вкрутил
 

feniragon

✩✩✩✩✩✩✩
31 Июл 2018
87
4
Тогда смотри по пунктам мои комментарии и сравни с алгоритмом, все ли верно
C++:
#include <SPI.h>
#include "Adafruit_NeoPixel.h"
Adafruit_NeoPixel strip = Adafruit_NeoPixel(60, 12, NEO_GRB + NEO_KHZ800);

#define keyHor 5 //кнопки
#define keyMin 4
unsigned long timing; //для счетчика времени
unsigned long pause; //для обработки кнопок
int m = 0; //минуты
int h = 0; //часы
int r = 10; //сделано для упрощения подбора цветов и яркости
int g = 10;
int b = 10;
int plus = 50;
int i = 0;

void setup() {
    Serial.begin(9600);
    strip.begin(); // Функция begin() настроит порт Arduino и выставит значения по умолчанию.
    strip.show(); // Функция show() передаст команду на выключение всем пикселям.

    pinMode(keyHor, INPUT_PULLUP);
    pinMode(keyMin, INPUT_PULLUP);
    timing = millis();
    pause = millis();
}


void loop() {
    for (i = 0; i < 60; i++)
        strip.setPixelColor(i, r, g, b ); //заливаем контур (60 светодиодов)
    for (i = 0; i < 60; i = i+5)
        strip.seуtPixelColor(i, 0, g + plus, b);

if (m > 59){
   h++;
   m = 0;
}

if (h > 11){
   h = 0;
}

    if (h == 0){
        strip.setPixelColor(59, 250 ,0 ,0 ); //вот это для корректного отображения 12 часов
        strip.setPixelColor(0, 250 ,0 ,0 );
        strip.setPixelColor(1, 250 ,0 ,0 );
    } else {
        strip.setPixelColor(h*5-1, 250 ,0 ,0 ); //для всех остальных часов
        strip.setPixelColor(h*5 , 250 ,0 ,0 );
        strip.setPixelColor(h*5+1, 250 ,0 ,0 );
    }

    strip.setPixelColor(m, 250 ,0 ,250 ); //Рисуем "минуту"

    // обработка кнопок
    if (millis() - pause > 200) {
        pause = millis();
        if (!digitalRead(keyHor)){
            h++;
        }
        if (!digitalRead(keyMin)){
            m++;
        }
    }
}
PS. Я бы еще оптимизировал код, что бы не перезаписывать всю ленту а перезаписывать ТОЛЬКО измененные пиксели.. те h-2 и m-1,
А потом заливать часовые пиксели, минутную и один/два из зеленых
 
Последнее редактирование:

seve_len

✩✩✩✩✩✩✩
13 Сен 2018
69
4
36
@feniragon, Очень похоже. Счетчика минут/часов нету, а так да, посексуальней выглядит)