Güneş Doğuş Batış Hesabı (+-5dk Hata ile)

Başlatan YARGICH, 06 Mayıs 2009, 01:30:16

YARGICH

Merhaba,

   Bu aralar bir Güneş doğuş batış hesabı yapmam gerekiyordu. Forumda araştırdım ama açılan konu başlıklarından pek bir sonuç çıkmadığını fark ettim. Bu hesabı birçok örneği inceleyerek anlaşılır bir biçime getirdim. En azından kendi adıma, yapılmış bir çok örnekte hep bir soru işareti kalıyordu aklımda. Astronomik olarak konu hakkında fazla bir bilgim yok ama az birşeyler öğrendim. Bu hesabı önce Excel'de denedim. Kafamda soru işareti kalan yerleri orada giderdim ve sonuç benim açımdan yeterliydi. O yüzden bu hesaplamayı CCS yazdığım bir kod ile PIC'e aktardım. Yalnız ROM da çok yer kaplıyo bilginize! isteyene Excel de bu hesaplama için hazırladığım dosyayı verebilirim ama çok dağınık olduğu için koymak istemedim.



##############################################################################*/
//                                                                            //
//                 Güneşin Doğuşunu ve Batışını Hesaplar                      // 
//                                                                            //
//##############################################################################

#include <math.h>

//##############################################################################
//                         Radyan to Degree
//##############################################################################
float RadtoDeg(float anglerad) { // radyanı dereceye çevirir
return (180.0 * anglerad / PI);
}//RadtoDeg

//##############################################################################
//                         Degree to Radyan
//##############################################################################
float DegtoRad(float angledeg) { // dereceyi radyana çevirir
return (PI * angledeg / 180.0 );
}// DegtoRad

//##############################################################################
//                           Artık Yıl Mı?
//##############################################################################
Boolean Artik_Yil_Mi(int yil){
if (((yil % 4 == 0) && (yil % 100 != 0)) || (yil % 400 == 0)) return (True);
else return (False);
}//Artik_Yil_Mi

//##############################################################################
//                            Ayin Günü
//##############################################################################
int Ayin_Gunu(int ay, int yil){

   switch(ay){
      case 1:  return(31);
      case 2:  if (Artik_Yil_Mi(yil)==True) return(29); else return(28);
      case 3:  return(31);
      case 4:  return(30);
      case 5:  return(31);
      case 6:  return(30);
      case 7:  return(31);
      case 8:  return(31);
      case 9:  return(30);
      case 10: return(31);
      case 11: return(30);
      case 12: return(31);
   }
}// Ayin_Gunu

//##############################################################################
//                            Gun Sayısı
//##############################################################################
int Gun_Sayisi(int gun, int ay, int yil){
int i,gun_sayac=0;

   for (i=1;i<ay;i++){ gun_sayac = gun_sayac + Ayin_Gunu(i, yil); }
   gun_sayac = gun_sayac + Gun;

return(gun_sayac);
}// Gun_Sayisi

//##############################################################################
//                             int to float
//##############################################################################
float inttoFloat(int integer){
 integer=(integer+1.5)-1.5; // herhangi bir integer sayıyı, float sayı ile toplamak onu float yapmaktaki iyi bir yöntem. (denendi...) 1.5 öylesine bir sayı
return(integer);
}// inttoFloat

//##############################################################################
//                          Koordinat to Float
//##############################################################################
float Koordinat_to_Float(int derece, int dakika, int saniye){
float dakika_float, saniye_float, koordinat_float;

   dakika_float = inttoFloat(dakika) / 60;
   saniye_float = inttoFloat(saniye) / 3600;
   koordinat_float = inttoFloat(derece) + dakika_float + saniye_float;

return(koordinat_float);
}// Koordinat_to_Float

//##############################################################################
//                           Float to Saat
//##############################################################################
void Float_to_Saat(float saat_float, int &saat, int &dakika){
float dakika_float,saniye_float,saat_int, dakika_int;

   dakika_float = modf(saat_float,&saat_int);               // saat

   dakika_float = dakika_float * 60;

   saniye_float = modf(dakika_float,&dakika_int);           // dakika
   if (saniye_float > 0.5) { dakika_int = dakika_int + 1.0; } // 0.5*60=30sn olduğundan...
   
   saat   = (int)saat_int;
   dakika = (int)dakika_int;
   
}// Float_to_Saat

//##############################################################################
//                             Saat to Float
//##############################################################################
float Saat_to_Float(int saat, int dakika){
float dakika_float, saat_float;

   dakika_float = inttoFloat(dakika) / 60;
   saat_float   = inttoFloat(saat) + dakika_float;

return(saat_float);
}// saat_to_Float

//##############################################################################
//                           Declination Angle
//##############################################################################
float Declination_Angle(int gun, int ay, int yil){
float DeclinationAngle,GunSayisi;

   GunSayisi=Gun_Sayisi(gun, ay, yil);
   
   DeclinationAngle = 23.45 * sin(DegtoRad((0.986 * (GunSayisi-81)))); // (0.986=360/365)

return(DeclinationAngle);
}// Declination_Angle

//##############################################################################
//                           Equation of Time
//##############################################################################
float Equation_of_Time(int gun, int ay, int yil){
float EqT,GunSayisi,c,x,y,z;

   GunSayisi=Gun_Sayisi(gun, ay, yil);
   
   c = 0.986 * inttoFloat((GunSayisi - 81));
   x = 9.87  * sin(DegtoRad(2.0 * c));
   y = 7.53  * cos(DegtoRad(c));
   z = 1.5   * sin(DegtoRad(c));
   
   EqT = x - y - z;

return(EqT);
}// Equation_of_Time

//##############################################################################
//                         Mid_Day (Dhuhr Zamanı)
//##############################################################################
float Mid_Day(int time_zone, int Long_deg, int Long_dk, int Long_sn, int gun, int ay, int yil){
float MidDay,EqT,Longitude_Float;

   Longitude_Float = Koordinat_to_Float(Long_deg, Long_dk, Long_sn);

   EqT = Equation_of_Time(gun, ay, yil);

   MidDay = 12.0 + time_zone - (Longitude_Float/15.0) - (EqT/60.0);

return(MidDay);
}// Mid_Day

//##############################################################################
//                            T(a) => (a=0.83333) 
//##############################################################################
float Ta(int time_zone, int Lat_deg, int Lat_dk, int Lat_sn, int gun, int ay, int yil){
float x,y,DecofSun,Latitude_Float,Ta_Float;

   Latitude_Float = Koordinat_to_Float(Lat_deg, Lat_dk, Lat_sn);

   DecofSun = Declination_Angle(gun, ay, yil);
                                                      
   x = - 0.015 - ( sin(DegtoRad(Latitude_Float)) * sin(DegtoRad(DecofSun)) ); // 0.015 = sin(DegtoRad(0.83333))
   y = cos(DegtoRad(Latitude_Float)) * cos(DegtoRad(DecofSun));
   
   Ta_Float = RadtoDeg( acos(x / y) ) / 15.0;
   
return(Ta_Float);
}// Ta

//##############################################################################
//                         Gunes Saati Hesapla
//##############################################################################
void Gunes_Saati_Hesapla(int gun,int ay,int yil,int time_zone,int Lat_deg,int Lat_dk,int Lat_sn,int Long_deg,int Long_dk,int Long_sn,float &SunRise_Float,float &SunSet_Float){
float Mid_Day_Zamani, Ta_Zamani;

   Mid_Day_Zamani = Mid_Day(time_zone, Long_deg, Long_dk, Long_sn, gun, ay, yil);

   Ta_Zamani = Ta(time_zone, Lat_deg, Lat_dk, Lat_sn, gun, ay, yil);

   SunRise_Float = Mid_Day_Zamani - Ta_Zamani;
   
   SunSet_Float  = Mid_Day_Zamani + Ta_Zamani;
  


}// Gunes_Saati_Hesapla

//##############################################################################
//                           Gunes Saati Oku
//##############################################################################
void Gunes_Saati_Oku(int gun,int ay,int yil,int time_zone,int Lat_deg,int Lat_dk,int Lat_sn,int Long_deg,int Long_dk,int Long_sn){
int i,Ortalama_Sayisi=10;
float SunRise_Float,SunSet_Float,SunRise_Float_Top=0.0,SunSet_Float_Top=0.0;

//   for (i=0;i<Ortalama_Sayisi;i++)
//      {
         Gunes_Saati_Hesapla(gun,ay,yil,time_zone,Lat_deg,Lat_dk,Lat_sn,Long_deg,Long_dk,Long_sn,SunRise_Float,SunSet_Float);
         SunRise_Float_Top = SunRise_Float_Top + SunRise_Float;
         SunSet_Float_Top  = SunSet_Float_Top  + SunSet_Float;
//      }

//   SunRise_Float_Top = SunRise_Float_Top / inttoFloat(Ortalama_Sayisi);
//   SunSet_Float_Top  = SunSet_Float_Top  / inttoFloat(Ortalama_Sayisi);

   Float_to_Saat(SunRise_Float_Top, Gunes_SunRise_Saat, Gunes_SunRise_Dakika);
   Float_to_Saat(SunSet_Float_Top,  Gunes_SunSet_Saat,  Gunes_SunSet_Dakika);

}// Gunes_Saati_Oku


İyi Çalışmalar...
Uçurtmalar, rüzgarın kuvvetiyle değil, rüzgara karşı koydukları direnç ile yükselirler.

YARGICH

Arkadaşlar,

  Yukarıda verdiğim kod örneğinde ve hesaplamalarda hata olduğunu düşünen varsa lütfen burda tartışalım.

  Bu kodu kullanmak için, bunu .h dosyası olarak kaydedin ve sadece en sondaki fonksiyonu gerekli parametreleri ile birlikte çağırmanız yetecektir.

  Hesabı internetde web sayfası üzerinden sorgulama yapabildiğiniz bir çok sitede denedim. Yakın sonuçlar veriyor. Zaten siteler arasında da farklı sonuçlar var hep. Bundan dolayı biraz hata payını göz ardı edeceğiz galiba.

   Bu arada eklemeyi unuttum, bu hesabı her yaptırdığınızda PIC her seferinde aynı sonucu üretmiyor. Yani hesaplama için her seferinde aynı parametreleri göndermenize rağmen her seferinde aynı sonuç gelmiyor. Bu hatalı sonuç üretimi, yıl içerisindeki günün belli aralıklarda artmasıyla artıp azalıyor. Bu hatalı sonuç üretimini önce PIC'den sonra CCS'den olduğunu düşünmeye başladım. Eğer bu tarz hesaplamalarda, özellikle floating point ve trigonometrik hesaplamalarda böyle bir durumda kalan arkadaşlar var ise yardımlarını bekliyorum.

  isteyen olursa Julian Day hesabınıda ekleyebilirim. Bu hesaplamayı yapan bir çok örnekte Julian Day hesabınıda yapıyorlar ama hesap içinde yıl içindeki günü kullandıkları için ekleme gereği duymadım.

İyi Çalışmalar.
Uçurtmalar, rüzgarın kuvvetiyle değil, rüzgara karşı koydukları direnç ile yükselirler.

lightt

Selam,

bir aralar benimde merak ettiğim bir konuydu, lakin ben bunu pic boyutuna taşımamıştım. Kodu inceledim ve aklıma bazı sorular geldi, yanlış anlaşılmasın hata olarak değil sadece geliştirme amaçlı.

Örneğin yaz kış saati uygulamasında kodun davranışının değişmesi gerekmez mi? Bu nasıl sağlanabilir?

Sanırım tarih bilgisi RTC den alınıyor,bu durumda ayın günü hesabı gereksiz kalmıyor mu (yanlışım varsa düzeltin RTC ler genelde ayın günü bilgisini veriyor diye biliyorum, hatta artık yıl bilgisinide veriyordu), peki koordinat bilgisi nasıl alınıyor GPS falan tarzı bir yaklaşımmı yoksa yok keypad ile mi giriliyor?

gallavi

Bu tarz hesaplardan çıkan sonuç GMT saatine göre ve yaz kış saati uygulamasına göre türkiye GMT+2 ve GMT+3 olarak buna ekleme yapmak gerekir
DemirHan=gallavi;

YARGICH

@lightt

   Yaz saati uygulaması yılın belli tarihleri arasında saat farkının, @gallavi nin de bahsetmek istediği gibi, +- 1 saat oyanatılması ile alakalı bir durum. Yani bu hesaplamayı programınıza eklediğinizde gerekli fonksiyonu çağırırken göndereceğiniz tarih bilgisi kısmında ayarlanabilir olacağını düşünmüştüm.

   Ben kullandığım RTC de yılın gününün verip vermediğine hiç bakmadım, daha önce kullandığım RTC lerde hiç fark etmdiğim ve hesabın kolay olması nedeniyle hiç bakmadım. Tabi eğer var ise kolaylık olabilir.

   Bu programın ne tür bir cihazda kullanılacağı size kaldığından dolayı istediğiniz şekilde koordinat bilgisi yine aynı fonksiyonu çağırırken gönderebilirsiniz. Genel bir yapıda olsun istedim. Ayrıca Time_Zone girerken, cihazın bulunduğu yerin saat farkı girilmesi gerekiyor.

iyi çalışmalar.
Uçurtmalar, rüzgarın kuvvetiyle değil, rüzgara karşı koydukları direnç ile yükselirler.

lightt

Selamlar,

Aslında burda benim sorularda da bir hata olmuş ben pic ile donanımsal olarak alakalı zannedip sazan gibi atladım,  halbuki konu software kısmında açılmış. Neyse yinede cevaplar için teşekkürler. Yaz kış saati için bir algoritma vardı basit bişey bulabilirsem ekleyeceğim.


Gökhan BEKEN

merhaba
vakit matik lerde bu formüller geçerli midir?
imsak güneş öğlen ikindi akşam yatsı
vakitlerini hesaplamak için bir formül kullanabilir miyiz?
Yoksa tek tek kayıt mı etmek gerekir?
TEŞEKKÜRLER
Özel mesaj okumuyorum, lütfen göndermeyin.

ata911467

iyi günler arkadaşlar,
                Astronomik zaman rolesinin keil da yazılımını yapmam gerekiyor.Coğrafi kordinat bilgilerini girerek otomotik gün doğuşu ve batışını hesaplayacak bir yazılım olması gerekir.Bunun için sizce nasıl bir algorithm oluşturmalıyım?