Перевод времени в аналоговых часах. (Код или алгоритм).

Обсуждаем контроллеры компании Atmel.
Ответить
X-HUNTER
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср янв 23, 2019 20:18:44

Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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;   // куда ближе крутить стрелки



Вроде все работает. (уже неделю =))
Может, есть другие алгоритмы или идеи?
Реклама
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение NStorm »

Допустим, на часах 11:55. А фактическое время 12:10. По вашему алгоритму они будут крутиться против часовой 11 часов 45 минут.
Ну или я на ночь глядя неправильно что-то понял. )
Реклама
X-HUNTER
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср янв 23, 2019 20:18:44

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение X-HUNTER »

Приветствую. Да, есть проблемы с выбором направления вращения в некоторых случаях. Но по вашему примеру должно быть правильно.

[uquote="NStorm",url="/forum/viewtopic.php?p=3741158#p3741158"]Допустим, на часах 11:55. А фактическое время 12:10...
Ну или я на ночь глядя неправильно что-то понял. )[/uquote]

Результат в переменной sec = 900 (сколько секунд)
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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
Последний раз редактировалось NStorm Пт ноя 22, 2019 14:41:17, всего редактировалось 1 раз.
Реклама
Эиком - электронные компоненты и радиодетали
akl
Друг Кота
Сообщения: 4445
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение akl »

Может считать все в секундах, типа
12:10=43'800
11:55=42'900
Значит нужно перевести стрелки на 900 секунд вперед.
Реклама
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение NStorm »

akl, так он и считает в секундах, только в 12-часовом формате. И 13:00:00 становятся 01:00:00 при расчетах перемотки.
Реклама
X-HUNTER
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср янв 23, 2019 20:18:44

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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 ) 
Аватара пользователя
Starichok51
Модератор
Сообщения: 19054
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение Starichok51 »

а если возьмем наоборот - эталонное 11:55, а текущее 1:10.
в какую сторону и на сколько у тебя будет крутить?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
X-HUNTER
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср янв 23, 2019 20:18:44

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение X-HUNTER »

Если ни у кого нет идей а только вопросы “Куда оно будет крутить ?”
Вот сделал эмулятор, этого алгоритма.

Эээ...мулятор

Если, что, писал на коленке, да и засыпаю уже, пойду чай пить и спать… :)
Аватара пользователя
Starichok51
Модератор
Сообщения: 19054
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение Starichok51 »

а мне вот непонятно, зачем из 24-часового формата переводить в 12-часовой?
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
NStorm
Поставщик валерьянки для Кота
Сообщения: 1978
Зарегистрирован: Ср июл 17, 2013 13:55:57

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение NStorm »

Потому что сегментов на циферблате 12.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19054
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение Starichok51 »

ну и что?
зачем из 13 часов вычитать 12, а потом ломать голову, как из 1 часа скорректировать к 11 часам?
если сразу можно вычислить, сколько секунд будет в 13:10 и сразу пересчитать к 11:55.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
Аватара пользователя
musor
Друг Кота
Сообщения: 39197
Зарегистрирован: Сб сен 13, 2014 16:27:32
Откуда: СпиртоГонск созвездия Омега

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение musor »

шаговые моторы во 2часах НЕРЕВЕРСИВНЫЕ питаются 1ф разнополяркой --П---U---П----U---
пауза +30в пауза 2минута =-пауза 3мин +30в пауза4 мин-пауза и ТД
так что про перевод протиф часовой сразу забудте!!!
ZМудрость(Опыт и выдержка) приходит с годами.
Все Ваши беды и проблемы, от недостатка знаний.
Умный и у дурака научится, а дураку и ..
Алберт Ейнштейн не поможет и ВВП не спасет.и МЧС опаздает
X-HUNTER
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср янв 23, 2019 20:18:44

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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]
Что мешает поставить шаговик который крутится в обе стороны? Если нет возможности вращать стрелки против часовой, можно подождать (пропустить некоторое количество секунд), для точной настройки времени, если часы пропустят минуту , этого ни кто и не заметит. Тут много вариантов.
Аватара пользователя
Starichok51
Модератор
Сообщения: 19054
Зарегистрирован: Сб авг 14, 2010 15:05:51
Откуда: г. Озерск, Челябинская обл.

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение Starichok51 »

чтобы легко впихнуть код в attiny13, нужно писать на ассемблере.
а на Си тот же самый код (по функционалу) получится в несколько раз длиннее, и не впихнется.
код на ассемблере, соответственно, и работать будет намного быстрее.
Мудрость приходит вместе с импотенцией...
Когда на русском форуме переходят на Вы, в реальной жизни начинают бить морду.
OKF
Это не хвост, это антенна
Сообщения: 1401
Зарегистрирован: Вт июн 07, 2011 08:03:18

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение OKF »

Да ладно. На 10..20% всего. И всё зависит от умения готовить как с одной, так и с другой стороны.)
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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;

вроде тоже должно нормально заработать...

Добавлено немного погодя:
Вот бы ещё мозги у часов могли бы определять реальное положение стрелок... в шестернях стрелок просверлить по дырочке, чтобы эти дырочки сходились в полночь и оптопару...
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
X-HUNTER
Первый раз сказал Мяу!
Сообщения: 24
Зарегистрирован: Ср янв 23, 2019 20:18:44

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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();
Аватара пользователя
Ivanoff-iv
Друг Кота
Сообщения: 7077
Зарегистрирован: Пт ноя 11, 2016 05:48:09
Откуда: Сердце Пармы

Re: Перевод времени в аналоговых часах. (Код или алгоритм).

Сообщение 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), и наконец секунды...
правда код я не проверял, но, думаю, он заработает
Для тех, кто не учил магию мир полон физики :)
Безграмотно вопрошающим про силовую или высоковольтную электронику я не отвечаю, а то ещё посадят за участие в (само)убиении оболтуса...
Ответить

Вернуться в «AVR»