Recently I added Sun Moon Library to my DIY Arduino Weather Station.
Given a location specified as Latitude / Longitude coordinates and a date / time this clever algorithm uses astronomical math routines to provide timing of sunrise, sunset and moon age.
In spite of Arduino ATMega328p chipset being only an 8 bit architecture and float data type being low precision ( 6 – 7 decimal digits ) timings output by sun moon are said to be accurate to second scale.
Comparing results with UK Met Office weather forecast during testing I found Arduino sunrise / sunset timings to be out, with a margin or error of around 15 minutes.
Being suspicious of data, one sunny afternoon I found a vantage point and watched sun disappear below horizon, timing the event.
Sure enough Arduino data was indeed inaccurate.
What could be the problem?
While my knowledge of maths is not sufficiently advanced to properly understand each line of Sun Moon library algorithm, to eliminate possibility of faulty code I decided to try another implementation, Dusk to Dawn.
After running a test for same location, result with new library continued to show an inaccuracy of 15 minutes.
Weather Station timing (date / time) is provided by a Real Time Clock (DS3132 module) which is synced from internet via Network Time Protocol (NTP). A quick check showed date and time to be correct, although manual correction for daylight savings time (DST) seemed sub-optimal.
This pointed to a coordinate error.
Google gives my location Bournemouth, UK as Longitude / Latitude 50.7192° N, 1.8808° W.
These coordinates are defined in Weather Station code as:
// Lat/Long: Bournemouth 50.7192° N, 1.8808° W #define LOC_latitude 50.7192 #define LOC_longtitude 1.8808
Here was the problem.
Checking cooordinates for another location, London, UK ( 51.5074° N, 0.1278° W ) Arduino gave sunrise / sunset with only a minor ( < 1 minute) difference in timing.
Bournemouth is West of Greenwich Meridian (zero line for Longitude) by approx 107 miles. Each degree of latitude is approximately 69 miles (111 kilometers) apart.
Google gives coordinates (50.7192° N, 1.8808° W) as decimal degrees and “N/S/E/W”, a human friendly representation.
Arduino code expects decimal degrees and Plus/minus symbol.
ISO 6709 International Standard defines Longitude as a number preceded by a sign character. A plus sign (+) denotes east longitude or the prime meridian, and a minus sign (-) denotes west longitude or 180° meridian (opposite of the prime meridian)
Similarly, according to Microsoft, “The latitude is preceded by a minus sign ( – ) if it is south of the equator (a positive number implies north)”.
Updating Weather Station to include latitude minus symbol, code now provided accurate timings –
// Lat/Long: Bournemouth 50.7192° N, 1.8808° W #define LOC_latitude 50.7192 #define LOC_longtitude -1.8808
In navigation, the 1 in 60 rule states that for each degree off (or displacement) over a distance of 60 nautical miles (NM), it will result in 1 NM off course
A trans Atlantic journey by boat from Southampton to New York ( 2974.5 nautical miles ), given a similar error in bearing of ~2 degrees might arrive in Boston or possibly Washington.
We were in agreement at last, today sunrise would occur at 06:25 and sunset at 19:46.
References:
https://github.com/steveio/arduino/blob/master/WeatherStation/WeatherStation.ino
https://en.wikipedia.org/wiki/ISO_6709#Longitude
https://docs.microsoft.com/en-us/previous-versions/mappoint/aa578799(v=msdn.10)?redirectedfrom=MSDN
https://stackoverflow.com/questions/51626412/getting-negative-values-of-latitude-and-longitude