Giter Site home page Giter Site logo

rickp / sunset Goto Github PK

View Code? Open in Web Editor NEW

This project forked from buelowp/sunset

0.0 1.0 0.0 54 KB

Calculate Sunrise and Sunset and the phase of the moon accurately based on date and geographic position

License: GNU General Public License v2.0

C++ 95.02% CMake 4.98%

sunset's Introduction

Calculate Sunrise and Sunset based on time and latitude and longitude

This is a modification of the sunrise.c posted by Mike Chirico back in 2004. See the link below to find it. I needed an algorithm that could tell me when it was dark out for all intents and purposes. I found Mike’s code, and modified it a bit to be a library that can be used again and again.

License

This is governed by the GPL2 license. See the License terms in the LICENSE file. Use it as you want, make changes as you want, but please contribute back in accordance with the GPL.

Building

The builder requires CMake 3.0.0 or newer, which should be available in most Linux distributions.

mkdir build
cmake ..
make
make DESTDIR=<some path> install

Note that by default, the installer will attempt to install to /usr/local/include and /usr/local/lib or the equivalent for Windows.

Supported targets

This should work on any platform that supports C++ 14 and later. However, it is exceptionally math intensive, and as such, will be very slow on 8 bit microcontrollers.

I have created a released library for the Particle build system, which you can find if you search for the sunset library. It is also buildable as a Linux C++ library. Porting to other build systems is possible, but outside of my willingness to support.

Details

To use SunPosition, you need to a few bits of local information.

  1. Accurate time. If you’re running this with something that can get GPS time or use NTP, then results will always be very accurate. If you do not have a good clock source, then the results are going to be very accurate relative to your not so accurate clock. For best results, make sure your clock is accurate to within a second if possible.
  2. You need an accurate position, both latitude and longitude, which the library needs to provide accurate timing.
  3. To get accurate results for your location, you need both the Latitude and Longitude, AND a local timezone. Without the timezone, the calcuations done are relative to UTC which may not be useful. Note that UTC isn't sunrise in Greenwhich, it is the UTC time when sunrises in your location.
  4. Prior to calculating sunrise or sunset, you must update the current date for the library, including DST if applicable. The library doesn’t track the date, so calling it every day without changing the date means you will always get the calculation for the last accurate date you gave it. If you do not set the date, it defaults to midnight, January 1st of year 0
  5. You can calculate for both the local timezone offset and UTC with related function calls if you would like. Local time calculations will return the number of minutes past midnight relative to your provided timezone. The UTC calculation will return the UTC time at your location, not the time in Greenwich.
  6. The library returns a double that indicates how many minutes past midnight relative to the set date that sunrise or sunset will happen. If the sun will rise at 6am local to the set location and date, then you will get a return value of 360.0. Decimal points indicate fractions of a minute.

The example provides the how to below, it's pretty simple. Every time you need the calculation call for it. I wouldn't suggest caching the value unless you can handle changes in date so the calculation is correct relative to a date you need.

SunPosition is C++, no C implementation is provided.

Releases

  • 1.0.8: Fix installation path issue and update README to include installation instructions
  • 1.0.7: Allowes for use of positive or negative longitude values. Thank you to https://github.com/nliviu

Moon Phases

This library also allows you to calculate the moon phase for the current day to an integer value. This means it's not perfectly accurate, but it's pretty close. To use it, you call moonPhase() with an integer value that is the number of seconds from the January 1, 1970 epoch. It will do some simple math and return an integer value that represents the current phase of the moon, from 0 to 29. In this case, 0 is new, and 29 is new, 15 is full. The code handles times that may cause the calculation to return 30 to avoid some limits confustion (there aren't 30 days in the lunar cycle, but it's close enough that some time values will cause it to return 30 anyway).

Examples

This example is relative to an .ino file. Create a global object, and initialize it and use it in loop().

#include <time>
#include <SunSet.h>
#define TIMEZONE	-5
#define LATITUDE	40.0000
#define LONGITUDE	89.0000
// Note that LONGITUDE can be positive or negative, but the original code will fail if you use a negative value
// Using a negative longitude does not impact, as it's the same either way. The code compensates for a negative value

SunSet sun;

void setup()
{
    // Set your clock here to get accurate time and date
    // Next, tell SunRise where we are
    sun.setPosition(LATITUDE, LONGITUDE, TIMEZONE);
}

void loop()
{
    // You should always set the date to be accurate
    sun.setCurrentDate(year(), month(), day());
    // If you have daylight savings time, make sure you set the timezone appropriately as well
    sun.setTZOffset(TIMEZONE);
    double sunrise = sun.calcSunrise();
    double sunset = sun.calcSunset();
    double sunriseUTC = sun.calcSunriseUTC();
    double sunsetUTC = sun.calcSunsetUTC();
    int moonphase = sun.moonPhase(std::time(nullptr));
}

This example is for the Raspberry Pi using C++

#include <ctime>
#include <SunSet.h>

#define ONE_HOUR	(60 * 60)
#define TIMEZONE	-5
#define LATITUDE	40.0000
#define LONGITUDE	89.0000
// Note that LONGITUDE can be positive or negative, but the original code will fail if you use a negative value
// Using a negative longitude does not impact, as it's the same either way. The code compensates for a negative value

void main(int argc, char *argv)
{
    SunSet sun;
    
    auto rightnow = std::time(nullptr);
    struct tm *tad = std::localtime(&rightnow);
    
    m_sun.setPosition(lat, lon, tad->tm_gmtoff / ONE_HOUR);
    m_sun.setCurrentDate(tad->tm_year + 1900, tad->tm_mon + 1, tad->tm_mday);
    double sunrise = sun.calcSunrise();
    double sunset = sun.calcSunset();
    double sunriseUTC = sun.calcSunriseUTC();
    double sunsetUTC = sun.calcSunsetUTC();
    int moonphase = sun.moonPhase(rightnow);
}

Notes

  • This is a general purpose calculator, so you could calculate when Sunrise was on the day Shakespeare died. Hence some of the design decisions
  • Date values are absolute, are not zero based, and should not be abbreviated (e.g. don’t use 15 for 2015 or 0 for January)
  • This library may run well enough on a 16KHz Arduino, but it’s fairly math intensive and uses quite a bit of memory, so it won’t run fast. It works very well on the ARM M core chips like the Teensy and Photon though.
  • It is important to remember you MUST have accurate date and time to make this work well. You must use internet time synced enough to avoid more than a few seconds drift, or GPS time. Without that, eventually the reported values from the library won't match up to what your CPU thinks the time is, and your usage will be not accurate.
  • It can be used as a general purpose library on any Linux machine as well. You just need to compile it into your RPI or Beagle project using cmake 3.0 or later.
  • UTC is not the UTC sunrise time, it is the time in Greenwhich when the sun would rise at your location. It's werid, but allows for some flexibility when doing calcualations depending on how you keep track of time in your system.

Links

You can find the original math in c code at http://souptonuts.sourceforge.net/code/sunrise.c.html

I got the moon work from Ben Daglish at http://www.ben-daglish.net/moon.shtml

sunset's People

Contributors

buelowp avatar nliviu avatar

Watchers

James Cloos avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.