Coder Social home page Coder Social logo

jpb10 / solarcalculator Goto Github PK

View Code? Open in Web Editor NEW
43.0 2.0 10.0 41 KB

Arduino library to calculate the times of sunrise, sunset, solar noon, twilight, the solar position, and more.

Home Page: https://www.arduino.cc/reference/en/libraries/solarcalculator/

License: MIT License

C++ 100.00%
arduino astronomy sunrise sunset solar astronomical-algorithms meeus

solarcalculator's Introduction

SolarCalculator Library for Arduino

SolarCalculator is inspired by the NOAA Solar Calculator.

This library provides functions to calculate the times of sunrise, sunset, solar noon, twilight (dawn and dusk), Sun's apparent position in the sky, equation of time, etc.

Most formulae are taken from Astronomical Algorithms by Jean Meeus and optimized for 8-bit AVR platform.

Installation

Download and copy SolarCalculator to your local Arduino/libraries directory.

Time

Date and time inputs are assumed to be in Universal Coordinated Time (UTC).

Although not required, it is recommended to use SolarCalculator along with the Time library or similar.

Usage

Include SolarCalculator.h in your sketch:

#include <SolarCalculator.h>

Calculate the times of sunrise, transit (solar noon), and sunset, in hours:

double latitude = 45.55;     // Observer's latitude 
double longitude = -73.633;  // Observer's longitude
int time_zone = -5;          // UTC offset
int year = 2022;             // Calendar year (1901-2099)
int month = 1;               // Calendar month (1-12)
int day = 1;                 // Calendar day (1-31)

double transit, sunrise, sunset;
calcSunriseSunset(year, month, day, latitude, longitude, transit, sunrise, sunset);

Or, using the Time library (Unix time):

time_t utc = now();
calcSunriseSunset(utc, latitude, longitude, transit, sunrise, sunset);

Convert to local standard time:

double sunrise_local = sunrise + time_zone;
  • Refer to the example sketches for more on rounding and printing the results.

Similarly, calculate the times of dawn and dusk, in hours:

calcCivilDawnDusk(utc, latitude, longitude, transit, c_dawn, c_dusk);
calcNauticalDawnDusk(utc, latitude, longitude, transit, n_dawn, n_dusk);
calcAstronomicalDawnDusk(utc, latitude, longitude, transit, a_dawn, a_dusk);

Sun's equatorial coordinates, in degrees and AUs:

calcEquatorialCoordinates(utc, rt_ascension, declination, radius_vector);

Sun's horizontal coordinates, corrected for atmospheric refraction, in degrees:

calcHorizontalCoordinates(utc, latitude, longitude, azimuth, elevation);

Equation of time, in minutes of time:

calcEquationOfTime(utc, eq);

where the results are passed by reference.

Examples

The following example sketches are included in this library:

  • SunriseSunset: Calculate the times of sunrise, solar noon, and sunset for a given date and location.

  • SunriseSunsetAltitude: Calculate the rise and set times at a height above the level of the horizon.

  • SolarCalculatorTimeLib: Calculate the rise and set times, equation of time, and current solar coordinates.

  • SolarTrackingTimeLib: Monitor the Sun's position in the sky for any location on Earth.

  • EquationOfTime: Plot the equation of time for a given year.

Notes

Accuracy

Various things to consider:

  • The amount of atmospheric refraction changes with air temperature, pressure, and the elevation of the observer. Therefore, sunrise and sunset times can only be accurate to the nearest minute (Meeus, 1998).

  • Assuming a purely elliptical motion of the Earth, solar coordinates have a "low accuracy" of 0.01° (Meeus, 1998). To this precision, we ignore nutation, delta T, and higher-order terms in the relevant expressions.

  • Arduino's single precision floating numbers have the equivalent of 23 * log10(2) ≈ 6.92 significant digits. Although this is generally not sufficient for mathematical astronomy (Meeus, 1998), it is good enough for our purposes.

Sunrise and sunset

The algorithm for finding the times of sunrise and sunset implemented in this library is valid for all latitudes between the Arctic and Antarctic circles (about ± 66.5°). Outside this range, a more general algorithm should be used but is not provided at this time.

References

ESRL Global Monitoring Laboratory (n.d.). NOAA Solar Calculator. https://gml.noaa.gov/grad/solcalc/

Meeus, J. (1998). Astronomical algorithms (2nd ed.). Willmann-Bell.

solarcalculator's People

Contributors

jpb10 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar

solarcalculator's Issues

Civil, Nautical, Astronomical Twilight wonky?

I am getting incorrect values for Astronomical dawn, and for both Civil and Nautical dusk. The following values are for location 33.386854212167975, -111.64819464040542 on date 3/9/2023.

Astr 5:51 (should start about 5:23, and notice it's the same as Naut)
Naut 5:51
Civil 6:20

Sunrise 6:44
Transit 12:37
Sunset 18:29

Civil 18:54 (should start about 18:30, obviously)
Naut 19:23 (should start 18:55, and notice it's the same as Astr)
Astr 19:23

Everything else above is within round-off allowance. So, very good!

The code can be viewed/run here:
https://wokwi.com/projects/358710780536496129

Wildly wrong numbers

Could you please run your example code SunriseSunset.ino with the following numbers and see why it is giving such odd numbers?

// Date
int year = 2022;
int month = 1;
int day = 15;

// Location
double latitude  = 18.19;
double longitude = 120.55;
int time_zone    = -8;

With those figures, I get:

Date: 2022-1-15
Latitude: 18.190 Longitude: 120.550
UTC offset: -8
--
Sunrise: 0-9:0-28
Transit: 0-3:0-53
Sunset:  01:42
Civil dawn: 0-9:0-51
Civil dusk: 02:05

ESP32. Arduino IDE. Nothing changed in the library or example code except the lat/long and date values at the top.

not getting same elevation and azimuth as NOAA

Hi, I've made some simple ports of this to Linux which are mostly printf instead of Serial.print and adding <math.h> and <stdio.h> but what I'm getting is off from what NOAA states for San Diego CA. https://gml.noaa.gov/grad/solcalc/

NOAA would say my solar elevation is 43.61 but the library calculation gives me 19.7
NOAA would say my solar azimuth is 236.3 but the library calculation gives me 100.6

The calculated sunrise and sunset are off by 2 minutes and 3 minutes compared to NOAA so pretty close.

I'm using Lat long in the library as obtained from the NOAA web page when the marker is placed at the airport on the road to Harbor Island Dr:
double latitude = 32.727219;
double longitude = -117.19665;

Any ideas on what could be causing this elevation and azimuth discrepancy?

Different sun angle values at 90°S (and north, so at the poles?)

The accuracy of the azimuth value is fine, but it isn't for the altitude, and this problem seems to only occur at the poles or so.

Location is 90°S and 0°E.
Time is 23:53:46 UTC on March 22, 2023 (1679529226)

#include <iostream>

#include "SolarCalculator.h"

int main() {
    double az, el;

    time_t time = 1679529226;
    calcHorizontalCoordinates(time, -90.0, 0.0, az, el);
    std::cout << "Azimuth: " << az << "\nElevation: " << el << '\n';

    return 0;
}

Program output
image

timeanddate.com (https://www.timeanddate.com/astronomy/night/@-90,0) (displayed time is UTC+13)
image

Not Upgrade PlatformIO

hello
platformIO tells me that the upgrade is not compatible with version 2.0.0
I am on mega 2560 V3, there is an incompatibility?
my version 1.03 works perfectly thanks to you.

[Suggestion] Option to show in radians

Looking at the source code, it does appear to show the values being converted from radians to degrees. The suggestion is to define an optional bool parameter to return the values in radians instead of degrees (not sure if this feature is necessary, but I wonder about losing decimal places for rad -> deg -> rad, like converting the returned double values back into radians, due to floating-point problems).

Solar midnight.

Hello!

I analyzed the code and found that this line:

m[0] = jd.m + wrapTo180(ra - longitude - GMST) / 360;

Is used to calculate the transit [solar noon]. I tried adjusting it to return solar midnight , but without succes. I would add m[4] for solar midnight, but my astronomy know how is too limited for this.

Could you please tell me how to get it to return the solar midnight?

Thank you .

Best regards, Marius.

[Suggestion] More UTC timestamps

For example, could the function calcSunriseSunset(...), and some others, make the values in UTC timestamps instead of hours of the day?

Incorrect rise/set times for Fiji, Nadi and other locations.

Hello!

I have found a systematic issue:

double lat = -17.803; // fiji, nadi
double lon = 177.416;// fiji, nadi
int y = 2022;
int m = 9;
int d = 27;
calcSunriseSunset(y, m, d, lat, lon, transit, sunrise, sunset, SUNRISESET_STD_ALTITUDE, 2);

The function returns sunrise = -6.062. This is correct. However , if we set m = 10, the next month, the sunrise value jumps to 17.560. If I feed it UTC time, the date differs when the «jump» to a sunrise at 17h occurs. I tried the function with different iteration levels: 1, 5, 10... Nothing helped.

I found a similar thing happens for other locations in Fiji, and in Funafuti [Tuvalu], Apia [Samoa], Nuku'alofa [Tonga] and others. But, at different dates.

Please let me know if you can confirm the bug. Thank you .

Best regards, Marius.

Sunset (and probably sunrise) calculations for next day

In this program, the UTC day is Nov 11, 2022, but my local date is Nov 10, 2022. When the program calculates the sunset time using the unix epoch (using my utc_now variable), it calculates the sunset at my location for the next day, not for the current date.

unsigned long utc_now = 1668127050;
calcSunriseSunset(utc_now, LATITUDE, LONGITUDE, transit, sunrise, sunset);

// Printed as seconds after midnight.
std::cout << utc_now % 86400 << '\n';
std::cout << sunset * 3600 - 86400 << '\n';

// My correction
if (sunset > 24) {
    utc_now -= 86400;
    calcSunriseSunset(utc_now, LATITUDE, LONGITUDE, transit, sunrise, sunset);

    // Printed as seconds after midnight.
    std::cout << utc_now % 86400 << '\n';
    std::cout << sunset * 3600 - 86400 << '\n';
}

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.