Страница 1 из 1
Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Ср ноя 20, 2019 12:06:56
X-HUNTER
Привет.
Сделал часы с автоматической коррекцией времени. Часы имеют обычный двенадцати часовой циферблат со стрелками. Соответственно время можно переводить либо вперед, либо назад.
Эталонное время получаю из интернета или RTC в формате HH:MM:SS .
Пока придумал такой алгоритм:
Вычисляю разницу в секундах, ели число положительное, значит, часы отстают и стрелки нужно перевести вперед, если разница отрицательная – то назад. Так как циферблат двенадцати часовой, нужно привести время к соответствующему формату.
Код: Выделить всё
/*
s – текущее время, секунды
m – текущее время, минуты
h – текущее время, часы
ss – эталонное время, секунды
mm – эталонное время, минуты
hh – эталонное время, часы
*/
if (h > 12) h = h - 12; // привести к 12 часовому виду
if (hh > 12) hh= hh - 12;
long sec = (ss - s) +
(mm - m) * 60L +
(hh - h) * 3600L;
long rev = 43200L - sec ; // направление + по часовой - против
if (rev < sec ) sec =-rev; // куда ближе крутить стрелки
Вроде все работает. (уже неделю =))
Может, есть другие алгоритмы или идеи?
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Чт ноя 21, 2019 21:58:12
NStorm
Допустим, на часах 11:55. А фактическое время 12:10. По вашему алгоритму они будут крутиться против часовой 11 часов 45 минут.
Ну или я на ночь глядя неправильно что-то понял. )
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Пт ноя 22, 2019 11:19:40
X-HUNTER
Приветствую. Да, есть проблемы с выбором направления вращения в некоторых случаях. Но по вашему примеру должно быть правильно.
[uquote="NStorm",url="/forum/viewtopic.php?p=3741158#p3741158"]Допустим, на часах 11:55. А фактическое время 12:10...
Ну или я на ночь глядя неправильно что-то понял. )[/uquote]
Результат в переменной sec = 900 (сколько секунд)
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Пт ноя 22, 2019 12:49:31
NStorm
Да, на ночь глядя внимание фиговое. Вчера мне показалось что if из hh вычтет 12 и сделает его равным 0.
Ну хорошо, а если на часах 11:55. А фактическое время 13:10.
ss = s = 0
m = 55; mm = 10
h = 11; hh = 13
После if'ов: h = 11; hh = 1
sec = (10 - 55) * 60 + (1 - 11) * 3600 = -38700
rev = 81900
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Пт ноя 22, 2019 12:58:08
akl
Может считать все в секундах, типа
12:10=43'800
11:55=42'900
Значит нужно перевести стрелки на 900 секунд вперед.
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Пт ноя 22, 2019 14:42:58
NStorm
akl, так он и считает в секундах, только в 12-часовом формате. И 13:00:00 становятся 01:00:00 при расчетах перемотки.
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Пт ноя 22, 2019 19:58:37
X-HUNTER
Если проверку времени делать на линейном участке циферблата, то первый мой вариант вроде работает не плохо. Если между 12-час и 1-час тут непонятно что получится.
На собранных часах (сделал 3 шт.) проверяю время раз в сутки в 21 час. Разница несколько секунд успешно корректируется. Все три экземпляра идут почти секунда в секунду уже больше недели.
Вот написал другой код, должен работать лучше, хотя х.з.
Код: Выделить всё
/*
s – текущее время, секунды
m – текущее время, минуты
h – текущее время, часы
ss – эталонное время, секунды
mm – эталонное время, минуты
hh – эталонное время, часы
*/
uint8_t h = 12,
m = 55,
s = 33;
for (uint8_t i=0; i<23;i++)
{
uint8_t hh = i,
mm = 10,
ss = 33;
Serial.print ("Time: ");
Serial.print (h);
Serial.print (":");
Serial.print (m);
Serial.print (":");
Serial.print (s);
Serial.print (" >>> ");
Serial.print (hh);
Serial.print (":");
Serial.print (mm);
Serial.print (":");
Serial.println (ss);
if (h > 12) h = h - 12; // привести к 12 часовому виду
if (hh > 12) hh= hh - 12;
// Первый результат. Смещение в секундах.
// Положительное число вращение вправо (по часовой стрелке),
// Отрицательное - влево (против часовой стрелки).
long sec = (ss - s) +
(mm - m) * 60L +
(hh - h) * 3600L;
// Если применить абсолютные значения можно узнать оба (влево, вправо) смещения.
// Но при этом потеряем направление вращения.
long var1 = abs(sec); // Прямое направление
long var2 = 43200L - var1; // Противоположное направление (43200 = 12 часов * 3600 секунд)
Serial.print ("Variant 1: ");
Serial.println (var1);
Serial.print ("Variant 2: ");
Serial.println (var2);
// Получаем направление вращения, но тут я не уверен…
// Выбираем наименьшее значение смещения.
// Если первоначальное направление в право, меняем на противоположное.
if (var2 < var1 )
{
if (sec > 0) sec=-var2; else sec=var2; // Волшебство =)
}
Serial.print ("Select: ");
Serial.print(sec);
Serial.print (" >>> ");
sec = abs(sec);
hh = sec / 3600;
mm = (sec - hh * 3600) / 60;
ss = sec - hh * 3600 - mm * 60;
Serial.print (hh);
Serial.print (":");
Serial.print (mm);
Serial.print (":");
Serial.println (ss);
Serial.println("----------------------------------------------");
}
delay(5000);
Вывод терминала
Спойлер
Код: Выделить всё
Time: 12:55:33 >>> 0:10:33
Variant 1: 45900
Variant 2: -2700
Select: -2700 >>> 0:45:0
----------------------------------------------
Time: 12:55:33 >>> 1:10:33
Variant 1: 42300
Variant 2: 900
Select: 900 >>> 0:15:0
----------------------------------------------
Time: 12:55:33 >>> 2:10:33
Variant 1: 38700
Variant 2: 4500
Select: 4500 >>> 1:15:0
----------------------------------------------
Time: 12:55:33 >>> 3:10:33
Variant 1: 35100
Variant 2: 8100
Select: 8100 >>> 2:15:0
----------------------------------------------
Time: 12:55:33 >>> 4:10:33
Variant 1: 31500
Variant 2: 11700
Select: 11700 >>> 3:15:0
----------------------------------------------
Time: 12:55:33 >>> 5:10:33
Variant 1: 27900
Variant 2: 15300
Select: 15300 >>> 4:15:0
----------------------------------------------
Time: 12:55:33 >>> 6:10:33
Variant 1: 24300
Variant 2: 18900
Select: 18900 >>> 5:15:0
----------------------------------------------
Time: 12:55:33 >>> 7:10:33
Variant 1: 20700
Variant 2: 22500
Select: -20700 >>> 5:45:0
----------------------------------------------
Time: 12:55:33 >>> 8:10:33
Variant 1: 17100
Variant 2: 26100
Select: -17100 >>> 4:45:0
----------------------------------------------
Time: 12:55:33 >>> 9:10:33
Variant 1: 13500
Variant 2: 29700
Select: -13500 >>> 3:45:0
----------------------------------------------
Time: 12:55:33 >>> 10:10:33
Variant 1: 9900
Variant 2: 33300
Select: -9900 >>> 2:45:0
----------------------------------------------
Time: 12:55:33 >>> 11:10:33
Variant 1: 6300
Variant 2: 36900
Select: -6300 >>> 1:45:0
----------------------------------------------
Time: 12:55:33 >>> 12:10:33
Variant 1: 2700
Variant 2: 40500
Select: -2700 >>> 0:45:0
----------------------------------------------
Time: 12:55:33 >>> 13:10:33
Variant 1: 42300
Variant 2: 900
Select: 900 >>> 0:15:0
----------------------------------------------
Time: 12:55:33 >>> 14:10:33
Variant 1: 38700
Variant 2: 4500
Select: 4500 >>> 1:15:0
----------------------------------------------
Time: 12:55:33 >>> 15:10:33
Variant 1: 35100
Variant 2: 8100
Select: 8100 >>> 2:15:0
----------------------------------------------
Time: 12:55:33 >>> 16:10:33
Variant 1: 31500
Variant 2: 11700
Select: 11700 >>> 3:15:0
----------------------------------------------
Time: 12:55:33 >>> 17:10:33
Variant 1: 27900
Variant 2: 15300
Select: 15300 >>> 4:15:0
----------------------------------------------
Time: 12:55:33 >>> 18:10:33
Variant 1: 24300
Variant 2: 18900
Select: 18900 >>> 5:15:0
----------------------------------------------
Time: 12:55:33 >>> 19:10:33
Variant 1: 20700
Variant 2: 22500
Select: -20700 >>> 5:45:0
----------------------------------------------
Time: 12:55:33 >>> 20:10:33
Variant 1: 17100
Variant 2: 26100
Select: -17100 >>> 4:45:0
----------------------------------------------
Time: 12:55:33 >>> 21:10:33
Variant 1: 13500
Variant 2: 29700
Select: -13500 >>> 3:45:0
----------------------------------------------
Time: 12:55:33 >>> 22:10:33
Variant 1: 9900
Variant 2: 33300
Select: -9900 >>> 2:45:0
----------------------------------------------
Жаль, что видимо никто этим не озадачивался, хотелось бы получить минимальный, лаконичный алгоритм, про код, я уже молчу.
Добавлено after 2 minutes 51 second:
P.S.
За Ардуину не ругайте, это только для отладки =)
Добавлено after 46 minutes 28 seconds:
[uquote="NStorm",url="/forum/viewtopic.php?p=3741407#p3741407"]Да, на ночь глядя внимание фиговое. Вчера мне показалось что if из hh вычтет 12 и сделает его равным 0.
Ну хорошо, а если на часах 11:55. А фактическое время 13:10.
ss = s = 0
m = 55; mm = 10
h = 11; hh = 13
После if'ов: h = 11; hh = 1
sec = (10 - 55) * 60 + (1 - 11) * 3600 = -38700
rev = 81900[/uquote]
Сейчас проверил.
Первый алгоритм (в принципе верно, но направление вращения не верное):
Код: Выделить всё
Текущее время: 11:55:33 >> 1:10:33
Выбрано: 10:45:00 ( -38700 )
Второй алгоритм (тут лучше):
Код: Выделить всё
Текущее время: 11:55:33 >> 1:10:33
Вариант 1: 10:45:00 ( 38700 )
Вариант 2: 01:15:00 ( 4500 )
Выбрано: 01:15:00 ( 4500 )
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Сб ноя 23, 2019 12:49:41
Starichok51
а если возьмем наоборот - эталонное 11:55, а текущее 1:10.
в какую сторону и на сколько у тебя будет крутить?
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Сб ноя 23, 2019 23:28:30
X-HUNTER
Если ни у кого нет идей а только вопросы “Куда оно будет крутить ?”
Вот сделал эмулятор, этого алгоритма.
Эээ...мулятор
Если, что, писал на коленке, да и засыпаю уже, пойду чай пить и спать…

Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вс ноя 24, 2019 13:18:43
Starichok51
а мне вот непонятно, зачем из 24-часового формата переводить в 12-часовой?
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вс ноя 24, 2019 13:38:06
NStorm
Потому что сегментов на циферблате 12.
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вс ноя 24, 2019 20:35:06
Starichok51
ну и что?
зачем из 13 часов вычитать 12, а потом ломать голову, как из 1 часа скорректировать к 11 часам?
если сразу можно вычислить, сколько секунд будет в 13:10 и сразу пересчитать к 11:55.
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вс ноя 24, 2019 20:44:11
musor
шаговые моторы во 2часах НЕРЕВЕРСИВНЫЕ питаются 1ф разнополяркой --П---U---П----U---
пауза +30в пауза 2минута =-пауза 3мин +30в пауза4 мин-пауза и ТД
так что про перевод протиф часовой сразу забудте!!!
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Пн ноя 25, 2019 22:51:25
X-HUNTER
[uquote="Starichok51",url="/forum/viewtopic.php?p=3742818#p3742818"]ну и что?
зачем из 13 часов вычитать 12, а потом ломать голову, как из 1 часа скорректировать к 11 часам?
если сразу можно вычислить, сколько секунд будет в 13:10 и сразу пересчитать к 11:55.[/uquote]
Чем меньше числа, тем меньше переменные, тем меньше и быстрее программа. Попробуйте впихнуть код в attiny13 и познаете дзен.
А вообще, в 12 часовом циферблате, при переводе времени используется только +6 или -6 часов, остальное излишне =) Если стрелки можно крутить в обе стороны.
Добавлено after 5 minutes 42 seconds:
[uquote="musor",url="/forum/viewtopic.php?p=3742829#p3742829"]шаговые моторы во 2часах НЕРЕВЕРСИВНЫЕ питаются 1ф разнополяркой --П---U---П----U---
пауза +30в пауза 2минута =-пауза 3мин +30в пауза4 мин-пауза и ТД
так что про перевод протиф часовой сразу забудте!!![/uquote]
Что мешает поставить шаговик который крутится в обе стороны? Если нет возможности вращать стрелки против часовой, можно подождать (пропустить некоторое количество секунд), для точной настройки времени, если часы пропустят минуту , этого ни кто и не заметит. Тут много вариантов.
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вт ноя 26, 2019 07:20:45
Starichok51
чтобы легко впихнуть код в attiny13, нужно писать на ассемблере.
а на Си тот же самый код (по функционалу) получится в несколько раз длиннее, и не впихнется.
код на ассемблере, соответственно, и работать будет намного быстрее.
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вт ноя 26, 2019 08:48:01
OKF
Да ладно. На 10..20% всего. И всё зависит от умения готовить как с одной, так и с другой стороны.)
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вт ноя 26, 2019 12:00:16
Ivanoff-iv
только часы: Y=(((X2-X1)+18)%12)-6
или в секундах
signed int dT= ((unsigned long int)(((((H2-H1)*60+M2-M1)*60)+C2-C1)+(18*60*60-1))%(12*60*60))-(6*60*60-1);
-1 это для того, чтобы при ровно 6 часах разницы часы пошли вперед, а не назад...
Добавлено after 2 hours 34 minutes 7 seconds:
или, чтобы с большими числами не работать, можно подводить по частям...
signed int dT=( (unsigned char)(H2-H1+30)%12)-6; //поддерживается 12 и 24 часовой формат в любом сочетании
dT*=60;
dT+=((unsigned char)(M2-M1+90)%60)-30;
dT*=60;
dT+=((unsigned char)(C2-C1+90)%60)-30;
вроде тоже должно нормально заработать...
Добавлено немного погодя:
Вот бы ещё мозги у часов могли бы определять реальное положение стрелок... в шестернях стрелок просверлить по дырочке, чтобы эти дырочки сходились в полночь и оптопару...
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вт ноя 26, 2019 17:53:30
X-HUNTER
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3743814#p3743814"]
signed int dT= ((unsigned long int)(((((H2-H1)*60+M2-M1)*60)+C2-C1)+(18*60*60-1))%(12*60*60))-(6*60*60-1);[/uquote]
Огромное спасибо за формулу, даже не думал что кто-то поможет с кодом.
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3743814#p3743814"]
signed int dT=( (unsigned char)(H2-H1+30)%12)-6; //поддерживается 12 и 24 часовой формат в любом сочетании
dT*=60;
dT+=((unsigned char)(M2-M1+90)%60)-30;
dT*=60;
dT+=((unsigned char)(C2-C1+90)%60)-30;
вроде тоже должно нормально заработать...[/uquote]
То что поддерживается 24 часовой формат, понятно ведь %12 как раз и приводит к такому формату…
Вот с остальным не совсем понятно откуда 90 и 30
Если возможно, напиши код для часов и минут. Ну, или алгоритм расчета. Заранее благодарю.
[uquote="Ivanoff-iv",url="/forum/viewtopic.php?p=3743814#p3743814"]Вот бы ещё мозги у часов могли бы определять реальное положение стрелок... в шестернях стрелок просверлить по дырочке, чтобы эти дырочки сходились в полночь и оптопару.[/uquote]
Делал когда-то нечто подобное, только оптопара была под часовой стрелкой, на циферблате.
Удалось даже обойтись одним датчиком, так как, часовая стрелка загораживает его дольше, чем минутная.
Если у часов автономное питание, смысла в этом нет. Время выставляется только при включении, потом можно просто запоминать положение стрелок даже перед выключением.
Добавлено after 8 minutes 4 seconds:
[uquote="Starichok51",url="/forum/viewtopic.php?p=3743762#p3743762"]чтобы легко впихнуть код в attiny13, нужно писать на ассемблере.[/uquote]
Пробовал, не понравилось
Делал опрос термодатчика, разница получилась около 100 байт… На эмуляторе работало на ура, по факту ассемблерный код на схеме не заработал. Самая большая проблема в ассемблере, для меня, по крайней мере, сделать аналог _delay_ms(); _delay_us();
Re: Перевод времени в аналоговых часах. (Код или алгоритм).
Добавлено: Вт ноя 26, 2019 19:10:54
Ivanoff-iv
мне вообще функция остатка от деления нравится,
например какой нибудь двунаправленый кольцевой счетчик: 0<=i<n
i=i±x
i=(i mn)%n
где m - целое число (mn не дают остатка)
n - длина счетчика
x - какоето число, изменяющее счётчик, x<mn
диапазон можно сдвинуть: k<=i<(n+k)
i=((i-k+mn)%n)+k;
важно только проследить, чтобы не было переполнения по вместимости переменной...
вот и в том примере длина = сутки, смещение = -полсуток...
а потом тоже, но по частям, сначала часы (длина 12, смещение -6), потом переведя в минуты - минуты (длина 60, смещение -30), и наконец секунды...
правда код я не проверял, но, думаю, он заработает