mirror of https://github.com/lumapu/ahoy.git
8 changed files with 226 additions and 31 deletions
@ -0,0 +1,99 @@ |
|||
/*
|
|||
sun.cpp - Library for calculating sunrise and sunset times based on current local time and position on Earth. |
|||
Calculations are based on Sunrise equation: https://en.wikipedia.org/wiki/Sunrise_equation
|
|||
Input and output times are in Unix Timestamp format (seconds since Jan 1, 1970, 00:00:00). |
|||
|
|||
Copyright (C) 2017 Nejc Planinsek |
|||
|
|||
This program is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#include "sun.h" |
|||
|
|||
const float pi = 3.14159265; |
|||
|
|||
/*
|
|||
* Constructor. Latitude and longitude must be provided. |
|||
*/ |
|||
void sun::setLocalization(float lat, float lon) { |
|||
_lat = lat; |
|||
_lon = lon; |
|||
} |
|||
|
|||
bool sun::LocalizationIsSet() { |
|||
if (_lat && _lon) |
|||
return true; |
|||
else |
|||
return false; |
|||
} |
|||
|
|||
/*
|
|||
* Calculates sunrise and sunset times based on current time. All times are in Unix Timestamp format. |
|||
*/ |
|||
void sun::getRiseSet(uint32_t unixTime, uint32_t &sunrise, uint32_t &sunset) { |
|||
// Convert Julian day to Unix Timestamp
|
|||
uint32_t Jdate = unixTime / 86400 + 2440588; |
|||
// Number of days since Jan 1st, 2000 12:00
|
|||
float n = Jdate - 2451545.0 + 0.0008; |
|||
// Mean solar noon
|
|||
float Jstar = -_lon / 360 + n; |
|||
// Solar mean anomaly
|
|||
float M = fmod((357.5291 + 0.98560028 * Jstar), 360); |
|||
// Equation of the center
|
|||
float C = 1.9148 * sin(M / 360 * 2 * pi) + 0.02 * sin(2 * M / 360 * 2 * pi) + 0.0003 * sin(3 * M * 360 * 2 * pi); |
|||
// Ecliptic longitude
|
|||
float lambda = fmod((M + C + 180 + 102.9372), 360); |
|||
// Solar transit
|
|||
float Jtransit = Jstar + (0.0053 * sin(M / 360.0 * 2.0 * pi) - 0.0069 * sin(2.0 * (lambda / 360.0 * 2.0 * pi))); |
|||
// Declination of the sun
|
|||
float delta = asin(sin(lambda / 360 * 2 * pi) * sin(23.44 / 360 * 2 * pi)) / (2 * pi) * 360; |
|||
// Hour angle
|
|||
float omega0 = 360 / (2 * pi) * acos((sin(-0.83 / 360 * 2 * pi) - sin(_lat / 360 * 2 * pi) * sin(delta / 360 * 2 * pi)) / (cos(_lat / 360 * 2 * pi) * cos(delta / 360 * 2 * pi))); |
|||
// Julian day sunrise, sunset
|
|||
float Jset = Jtransit + omega0 / 360; |
|||
float Jrise = Jtransit - omega0 / 360; |
|||
// Convert to Unix Timestamp
|
|||
uint32_t unixRise = Jrise * 86400.0 + 946728000; // Convert days (incl. fraction) to seconds + offset 1/1/2000 12:00
|
|||
uint32_t unixSet = Jset * 86400.0 + 946728000; // Convert days (incl. fraction) to seconds + offset 1/1/2000 12:00
|
|||
sunrise = unixRise; |
|||
sunset = unixSet; |
|||
} |
|||
|
|||
uint32_t sun::getRise(uint32_t unixTime) { |
|||
uint32_t rise; |
|||
uint32_t set; |
|||
getRiseSet(unixTime, rise, set); |
|||
return rise; |
|||
} |
|||
|
|||
uint32_t sun::getSet(uint32_t unixTime) { |
|||
uint32_t rise; |
|||
uint32_t set; |
|||
getRiseSet(unixTime, rise, set); |
|||
return set; |
|||
} |
|||
|
|||
uint32_t sun::getDayLength(uint32_t unixTime) { |
|||
uint32_t rise; |
|||
uint32_t set; |
|||
getRiseSet(unixTime, rise, set); |
|||
return set - rise; |
|||
} |
|||
|
|||
uint32_t sun::getNightLength(uint32_t unixTime) { |
|||
uint32_t rise; |
|||
uint32_t set; |
|||
getRiseSet(unixTime, rise, set); |
|||
return 86400 - (set - rise); |
|||
} |
@ -0,0 +1,42 @@ |
|||
/*
|
|||
sun.h - Library for calculating sunrise and sunset times based on current local time and position on Earth. |
|||
Calculations are based on Sunrise equation: https://en.wikipedia.org/wiki/Sunrise_equation
|
|||
Input and output times are in Unix Timestamp format (seconds since Jan 1, 1970, 00:00:00). |
|||
|
|||
Copyright (C) 2017 Nejc Planinsek |
|||
|
|||
This program is free software: you can redistribute it and/or modify |
|||
it under the terms of the GNU General Public License as published by |
|||
the Free Software Foundation, either version 3 of the License, or |
|||
(at your option) any later version. |
|||
|
|||
This program is distributed in the hope that it will be useful, |
|||
but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
GNU General Public License for more details. |
|||
|
|||
You should have received a copy of the GNU General Public License |
|||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|||
*/ |
|||
|
|||
#ifndef __SUN_H__ |
|||
#define __SUN_H__ |
|||
|
|||
#include "Arduino.h" |
|||
|
|||
class sun |
|||
{ |
|||
public: |
|||
void setLocalization(float lat, float lon); |
|||
bool LocalizationIsSet(); |
|||
void getRiseSet(uint32_t unixTime, uint32_t &sunrise, uint32_t &sunset); |
|||
uint32_t getRise(uint32_t unixTime); |
|||
uint32_t getSet(uint32_t unixTime); |
|||
uint32_t getDayLength(uint32_t unixTime); |
|||
uint32_t getNightLength(uint32_t unixTime); |
|||
private: |
|||
float _lat = 0.0; |
|||
float _lon = 0.0; |
|||
}; |
|||
|
|||
#endif /*__SUN_H__*/ |
Loading…
Reference in new issue