Астротаймер, есть ли смысл в математике?

std
Offline
Зарегистрирован: 05.01.2012

Чтобы стало понятнее, сабж - устройство, включающее (выключающее) нагрузку, с наступлением гражданских, навигационных или астрономических сумерек, т. е. к моменту когда солнце скроется на угол 6, 12 или 18 градусов от горизонта. Короче думаю вещь популярная.

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

Вопрос такой. Устраивает точность в пределах 10 минут, а таблица на другой год не такая же, то есть есть определённый люфт в единицы минут. Оно там за 15 лет не уйдёт далеко? Вроде как эта разница всегда отличается на несколько минут, но мало ли чо, вдруг если много времени пройдёт то ошибка увеличится? не?

Или забить и каждые три года таблицу перепрошивать?

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

Gippopotam
Gippopotam аватар
Offline
Зарегистрирован: 12.09.2014

Я был уверен, что там все линейно (в крайнем случае с одним коэффициентом) от равноденствия к равноденствию. А с погрешностью в 10 минут можно в уме посчитать...

Я заблуждался?

std
Offline
Зарегистрирован: 05.01.2012

В таком случае, можно считать это чудище готовым :)

<html><?php
// date_sunset(time(), SUNFUNCS_RET_STRING, Lat, Long, Zenith, TZ);
/* Lat: + N, - S
   Long: + E, - W
   Zenith: 90 sunset, 96 civil, 102 naut., 108 astro. twilight
   TZ: 0 = GMT  */
if(isset($_GET['y'])){
 $year=(int)$_GET['y'];
 if($year==0) $year=date("Y",time());
 echo '<title>'.$year.'</title><body>';
 $date=strtotime("1-1-".$year);
 for($i=1;$i<=12;$i++){
  $stopflag=false;
  for($j=1;$j<=31;$j++){
   $number = cal_days_in_month(CAL_GREGORIAN, date("n",$date), $year);
   $offtime=date_sunset($date, SUNFUNCS_RET_STRING, 50.27961, 127.5405, 96, 9);
   if(isset($_GET['f']) && !$stopflag) echo date("d/m/Y",$date).' - '.$offtime.'<br>';
   $offhr[$i][$j]=substr($offtime,0,2);
   $offmn[$i][$j]=substr($offtime,3,2);
   if($number==date("d",$date)){
    $stopflag=true;
    $date+=24*60*60;
   }
   if(!$stopflag) $date+=24*60*60;
  }
 }
 if(isset($_GET['f'])) echo '<br><a href='.$_SERVER['PHP_SELF'].'>Reset</a>';
 if(!isset($_GET['f'])){
  echo 'const uint8_t twhr[12][31] PROGMEM={<br>';
  for($i=1;$i<=12;$i++){
   echo '&nbsp; {';
   for($j=1;$j<=31;$j++){
    if(!isset($_GET['x'])){
     if(substr($offhr[$i][$j],0,1)=='0') echo ' '.substr($offhr[$i][$j],1,1);
     else echo $offhr[$i][$j];
    }else echo '0x'.str_pad(strtoupper(dechex((int)$offhr[$i][$j])),2,'0',STR_PAD_LEFT);
    if($j<31) echo ',';
   }
   echo '}';
   if($i<12) echo ',';
   echo '<br>';
  }
  echo '};<br>const uint8_t twmn[12][31] PROGMEM={<br>';
  for($i=1;$i<=12;$i++){
   echo '&nbsp; {';
   for($j=1;$j<=31;$j++){
    if(!isset($_GET['x'])){
     if(substr($offmn[$i][$j],0,1)=='0') echo ' '.substr($offmn[$i][$j],1,1);
     else echo $offmn[$i][$j];
    }else echo '0x'.str_pad(strtoupper(dechex((int)$offmn[$i][$j])),2,'0',STR_PAD_LEFT);
    if($j<31) echo ',';
   }
   echo '}';
   if($i<12) echo ',';
   echo '<br>';
  }
  echo '};<br><br><a href='.$_SERVER['PHP_SELF'].'?y='.$year.'&f>Show full calendar</a> ';
  if(!isset($_GET['x'])) echo '<a href='.$_SERVER['PHP_SELF'].'?y='.$year.'&x>HEX</a>';
   else echo '<a href='.$_SERVER['PHP_SELF'].'?y='.$year.'>DEC</a>';
  echo ' <a href='.$_SERVER['PHP_SELF'].'>Reset</a>';
 }
}else{
 echo '<title>Twilight data calculator</title><body><form action='.$_SERVER['PHP_SELF'].' method=get>Year:
 <input type=text size=5 name=y value='.date("Y").'>
 <input type=submit value=">>>"></form>';
}
?></body></html>
<!---
Header:
 #include <avr/pgmspace.h>

Read:
 byte x=pgm_read_byte(&(twhr[i][j]));
---->

Координаты (строка 16) в десятичном виде. В первом массиве будут часы, во втором минуты. Адресация вида массив[месяц][день].