I am using esp8266 then looking for a code to set country code and get calculation for sunrise and sunset time
search term: Arduino Ephemeris library. Arduino sun moon library
You could make the ESP fetch time sunrise & sunset times from a website, instead of calculating them.
https://sunrise-sunset.org/api
For example try clicking this, changing the lat and long for your location:
https://api.sunrise-sunset.org/json?lat=36.7201600&lng=-4.4203400
The results are like this.
{
"results": {
"sunrise": "6:10:39 AM",
"sunset": "6:04:49 PM",
"solar_noon": "12:07:44 PM",
"day_length": "11:54:10",
"civil_twilight_begin": "5:46:11 AM",
"civil_twilight_end": "6:29:17 PM",
"nautical_twilight_begin": "5:16:11 AM",
"nautical_twilight_end": "6:59:17 PM",
"astronomical_twilight_begin": "4:45:57 AM",
"astronomical_twilight_end": "7:29:31 PM"
},
"status": "OK"
}
not sure exactly what you want to do but google maps offers some reverse geocoding from GPS coordinates
Sunrise/sunset libraries for Arduino expect GPS location coordinates.
How to get data from api?
is there simple code to test?
I had written this a while back based on on line formulas and systems
so credit goes there:
/* https://www.esrl.noaa.gov/gmd/grad/solcalc/
https://www.esrl.noaa.gov/gmd/grad/solcalc/azel.html
The calculations in the NOAA Sunrise/Sunset and Solar Position Calculators are based on equations from Astronomical Algorithms, by Jean Meeus.
The sunrise and sunset results are theoretically accurate to within a minute for locations between +/- 72° latitude,
and within 10 minutes outside of those latitudes.
However, due to variations in atmospheric composition, temperature, pressure, and conditions, observed values may vary from calculations
The approximations used in these programs are very good for years between 1800 and 2100.
Results should still be sufficiently accurate for the range from -1000 to 3000.
Outside of this range, results may be given, but the potential for error is higher.
*/
this code will print some calculated data based on your position (lat, long), day of the year and time of day and print that out. There is a loop performing the calculation from 6:15 to 22:00 and you can see the results vary a bit. This is partly due to the precision of the double on our small arduino and approximations in the formulas
click to see the code
/* https://www.esrl.noaa.gov/gmd/grad/solcalc/
https://www.esrl.noaa.gov/gmd/grad/solcalc/azel.html
The calculations in the NOAA Sunrise/Sunset and Solar Position Calculators are based on equations from Astronomical Algorithms, by Jean Meeus.
The sunrise and sunset results are theoretically accurate to within a minute for locations between +/- 72° latitude,
and within 10 minutes outside of those latitudes.
However, due to variations in atmospheric composition, temperature, pressure, and conditions, observed values may vary from calculations
The approximations used in these programs are very good for years between 1800 and 2100.
Results should still be sufficiently accurate for the range from -1000 to 3000.
Outside of this range, results may be given, but the potential for error is higher.
*/
/*
The solar altitude is the angle between the direction of the Sun and the horizontal plane.
It ranges from 0° above the horizon to 90° at the zenith.
The solar azimuth is the angle created between the vertical plane passing through both the Sun and the observer,
and the North-South vertical plane. This angle is 0° at North, 90° at East, 180° at South, and 270° at West.
*/
/* Formulas extracted from Excel files at https://www.esrl.noaa.gov/gmd/grad/solcalc/calcdetails.html */
/* Verification with https://www.suncalc.org/ - of course double on 4 bytes creates approximation issues on UNO */
// Decimal Degrees
double latitude = 48.85824; // PARIS EIFFEL TOWER
double longitude = 2.2945; // PARIS EIFFEL TOWER
// ***********************************************************************
// IDEALLY SET THE RTC TO UTC TIME AND SET deltaTimeZone TO 0
// This way, you don't need to change the program for daylight saving time.
// ***********************************************************************
int8_t deltaTimeZone = +2; // FRANCE UTC+1 during standard time and UTC+2 during daylight saving time
#include <RTClib.h>
RTC_DS1307 rtc;
const char* dayNames[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"};
void fatalError(const __FlashStringHelper *message)
{
Serial.print(F("ERROR: ")); Serial.println(message);
while (true); // We halt here
}
void printWithTwoDigits(uint32_t number)
{
if (number < 10) Serial.write('0');
Serial.print(number);
}
void printFractionalTimeOfDay(double t)
{
uint32_t secondsSinceMidnight = t * (3600ul * 24ul);
Serial.print(secondsSinceMidnight / 3600UL);
Serial.write(':');
printWithTwoDigits((secondsSinceMidnight % 3600UL) / 60);
}
void printMinuteDuration(double nbMinutes)
{
byte h = nbMinutes / 60;
byte m = (nbMinutes / 60 - h) * 60;
byte s = (((nbMinutes / 60 - h) * 60) - m) * 60;
Serial.print(h);
Serial.write(':');
printWithTwoDigits(m);
// the seconds but we are not that precise anyway
// Serial.write(':');
// printWithTwoDigits(s);
}
inline double RADIANS(double a)
{
return a * (M_PI / 180.0);
}
inline double DEGREES(double a)
{
return a * (180.0 / M_PI);
}
void calculateAstronomy(
double latitude, /* Latitude (+ to N) */
double longitude, /* Longitude (+ to E) */
int8_t deltaTimeZone, /* Time Zone (+ to E) */
uint32_t numberOfDays, /* Number of days since January 1, 1900 */
uint32_t secondsElapsed /* Number of seconds since midnight */
)
{
double localHour = ((double) secondsElapsed) / (24.0 * 3600.0); // Fraction of a day
double julianDay = 2415018.5 + (double) numberOfDays + (double) localHour - ((double) deltaTimeZone) / 24.0;
double julianCentury = (julianDay - 2451545L) / 36525L;
double meanSolarLongitude = fmod(280.46646 + julianCentury * (36000.76983 + julianCentury * 0.0003032), 360);
double meanSolarAnomaly = 357.52911 + julianCentury * (35999.05029 - 0.0001537 * julianCentury);
double eccentricityEarthOrbit = 0.016708634 - julianCentury * (0.000042037 + 0.0000001267 * julianCentury);
double sunEquationOfCenter = sin(RADIANS(meanSolarAnomaly)) * (1.914602 - julianCentury * (0.004817 + 0.000014 * julianCentury)) + sin(RADIANS(2 * meanSolarAnomaly)) * (0.019993 - 0.000101 * julianCentury) + sin(RADIANS(3 * meanSolarAnomaly)) * 0.000289;
double trueSolarLongitude = meanSolarLongitude + sunEquationOfCenter;
double apparentSolarLongitude = trueSolarLongitude - 0.00569 - 0.00478 * sin(RADIANS(125.04 - 1934.136 * julianCentury));
double meanObliquityEcliptic = 23 + (26 + ((21.448 - julianCentury * (46.815 + julianCentury * (0.00059 - julianCentury * 0.001813)))) / 60) / 60;
double obliquityCorrection = meanObliquityEcliptic + 0.00256 * cos(RADIANS(125.04 - 1934.136 * julianCentury));
double solarDeclination = DEGREES(asin(sin(RADIANS(obliquityCorrection)) * sin(RADIANS(apparentSolarLongitude))));
double varY = tan(RADIANS(obliquityCorrection / 2)) * tan(RADIANS(obliquityCorrection / 2));
double equationOfTime = 4 * DEGREES(varY * sin(2 * RADIANS(meanSolarLongitude)) - 2 * eccentricityEarthOrbit * sin(RADIANS(meanSolarAnomaly)) + 4 * eccentricityEarthOrbit * varY * sin(RADIANS(meanSolarAnomaly)) * cos(2 * RADIANS(meanSolarLongitude)) - 0.5 * varY * varY * sin(4 * RADIANS(meanSolarLongitude)) - 1.25 * eccentricityEarthOrbit * eccentricityEarthOrbit * sin(2 * RADIANS(meanSolarAnomaly)));
double trueSolarTime = fmod(localHour * 1440 + equationOfTime + 4 * longitude - 60 * deltaTimeZone, 1440);
double hourAngle = (trueSolarTime / 4 < 0) ? (trueSolarTime / 4 + 180) : (trueSolarTime / 4 - 180);
double solarZenithAngle = DEGREES(acos(sin(RADIANS(latitude)) * sin(RADIANS(solarDeclination)) + cos(RADIANS(latitude)) * cos(RADIANS(solarDeclination)) * cos(RADIANS(hourAngle))));
double solarElevationAngle = 90 - solarZenithAngle;
double approximateAtmosphericRefractionAngle ;
if (solarElevationAngle > 85) approximateAtmosphericRefractionAngle = 0;
else if (solarElevationAngle > 5)
approximateAtmosphericRefractionAngle = 58.1 / tan(RADIANS(solarElevationAngle)) - 0.07 / pow(tan(RADIANS(solarElevationAngle)), 3) + 0.000086 / pow(tan(RADIANS(solarElevationAngle)), 5);
else if (solarElevationAngle > -0.575) approximateAtmosphericRefractionAngle = 1735 + solarElevationAngle * (-518.2 + solarElevationAngle * (103.4 + solarElevationAngle * (-12.79 + solarElevationAngle * 0.711)));
else approximateAtmosphericRefractionAngle = -20.772 / tan(RADIANS(solarElevationAngle));
approximateAtmosphericRefractionAngle /= 3600.0;
double finalSolarElevation = solarElevationAngle + approximateAtmosphericRefractionAngle;
double finalAzimuthAngle = (hourAngle > 0) ?
fmod(DEGREES(acos(((sin(RADIANS(latitude)) * cos(RADIANS(solarZenithAngle))) - sin(RADIANS(solarDeclination))) / (cos(RADIANS(latitude)) * sin(RADIANS(solarZenithAngle))))) + 180, 360) :
fmod(540 - DEGREES(acos(((sin(RADIANS(latitude)) * cos(RADIANS(solarZenithAngle))) - sin(RADIANS(solarDeclination))) / (cos(RADIANS(latitude)) * sin(RADIANS(solarZenithAngle))))), 360);
double sunTrueAnomaly = meanSolarAnomaly + sunEquationOfCenter;
double sunRadiusVector = (1.000001018 * (1 - eccentricityEarthOrbit * eccentricityEarthOrbit)) / (1 + eccentricityEarthOrbit * cos(RADIANS(sunTrueAnomaly)));
double sunRightAscension = DEGREES(atan2(cos(RADIANS(apparentSolarLongitude)), cos(RADIANS(obliquityCorrection)) * sin(RADIANS(apparentSolarLongitude))));
double hourAngleSunrise = DEGREES(acos(cos(RADIANS(90.833)) / (cos(RADIANS(latitude)) * cos(RADIANS(solarDeclination))) - tan(RADIANS(latitude)) * tan(RADIANS(solarDeclination))));
double solarNoon = (720 - 4 * longitude - equationOfTime + deltaTimeZone * 60) / 1440;
double sunriseTime = solarNoon - hourAngleSunrise * 4 / 1440;
double sunsetTime = solarNoon + hourAngleSunrise * 4 / 1440;
double daylightDuration = 8 * hourAngleSunrise;
Serial.print(secondsElapsed / 3600UL);
Serial.write(':');
printWithTwoDigits((secondsElapsed % 3600UL) / 60);
Serial.write('\t');
Serial.print(finalAzimuthAngle, 1);
Serial.print("°\t");
Serial.print(finalSolarElevation, 1);
Serial.write('°\t');
printFractionalTimeOfDay(sunriseTime);
Serial.write('\t');
printFractionalTimeOfDay(sunsetTime);
Serial.write('\t');
printMinuteDuration(daylightDuration);
Serial.print("\n");
}
void setup() {
uint32_t numberOfDays; // Number of days since January 1, 1900
Serial.begin(115200);
if (! rtc.begin()) fatalError(F("RTC Clock not found"));
rtc.adjust(DateTime(F(__DATE__), F(__TIME__))); // Do this ONCE to set the RTC to the current time if your RTC is not already set, then comment it out.
// rtc.adjust(DateTime(2020, 1, 2, 10, 30, 0)); // Or use this to set a specific date and time, e.g., January 2nd at 10:30 AM
// rtc.adjust(DateTime(2020, 1, 3, 21, 45, 0)); // Or use this to set a specific date and time, e.g., January 3rd at 9:45 PM
DateTime now = rtc.now(); // Current time
DateTime firstJanuary2020(2020, 1, 1, 0, 0, 0); // Reference point: January 1, 2020, at 0:00 UTC
TimeSpan sinceJanuary2020 = now - firstJanuary2020 ; // Time difference between now and January 1, 1900
numberOfDays = 43829UL + sinceJanuary2020.days() ; // + 43829 days to count from January 1, 1900
Serial.println(F("\nSun information for : "));
Serial.print(dayNames[now.dayOfTheWeek()]);
Serial.write(' ');
Serial.print(now.day());
Serial.write('/');
Serial.print(now.month());
Serial.write('/');
Serial.print(now.year());
Serial.write('\t');
Serial.print(now.hour());
Serial.write(':');
printWithTwoDigits(now.minute());
Serial.write(':');
printWithTwoDigits(now.second());
Serial.write('\n');
Serial.print(F("Latitude : ")); Serial.println(latitude, 6);
Serial.print(F("Longitude : ")); Serial.println(longitude, 6);
Serial.println("\nTime\tAzim\tElev\tRise\tSet\tdaylightDuration");
for (uint32_t moment = 22500; moment <= 79200UL; moment += 900UL) { // from 6:15 AM to 10:00 PM
calculateAstronomy(latitude, longitude, deltaTimeZone, numberOfDays, moment); // every 15 minutes
}
}
void loop() {}
See post #5. Look at GitHub - jpb10/SolarCalculator: Arduino library to calculate the times of sunrise, sunset, solar noon, twilight, the solar position, and more..
Maybe, did you try to Google for it?
If you cannot find, I suggest starting with the standard Arduino ESP8266 web client example sketch.
Then maybe add the Arduino JSON library, or simply use string/String manipulation to extract the sunset time from the response.
This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.