Calculating Sunrise/Sunset

sunset

So, now that we have most of the components of this project posted (including this post), I can finally give you the details of what we’re trying to accomplish. My house is situated in a smallish town without a lot of street lighting and the nearest light is too far away to effectively illuminate the house. Even worse than that, I have a driveway that slopes back towards the house creating a small, dark area just in front of the garage door. The problem with this arrangement is that it’s very easy for someone to spend a lot of time trying to steal gas from the one car I have that doesn’t fit in the garage. (funny tip: If you’re trying to steal gas, don’t go after a 4 cylinder, 35 MPG car like the guy in my neighborhood did. There is, on average, less than 4 gallons of fuel in the tank!) To help with this problem, I do have a pair of recessed lights on the house over the garage, but I don’t have a way to effectively turn them on and off at the right time of day. Currently, I have to leave the lights on all the time due to an unpredictable personal schedule of work, family, and friends which isn’t very efficient.

What about a light sensor? I did think of that solution, but that has its own set of problems. Being in the northeast, we get a fair bit of snow in the winter time. That snow can reflect a lot of light and cause the sensor to turn the lights off at the wrong time. Taking it a step further, if someone’s willing to resort to minor criminal activity, nothing would stop them from figuring out some way to fool the sensor since it would have to be mounted on the outside of the house where it would be accessible and visible.

My solution is to use a combination of a RTC, the WWVB time signal, and the TimeLord library to accurately compute sunrise and sunset. The resulting circuit would automatically turn the lights on at sunset and turn them off at sunrise. Not only would this be an energy savings over the course of each day, but with advancements in LED technology, I could reduce my energy use to just pennies per month and get the benefit of having a properly lighted driveway. Furthermore, an addition of some wireless communications could allow me to plot the energy usage over the course of the year. That last feature isn’t planned for this version but it wouldn’t be difficult to do.

So, how do you compute sunrise and sunset? Not being afraid of a little math, I started looking online at the equations necessary to accomplish this. I found this page that had all of the calculations and put together some proof of concept code to see how accurate it would be on the arduino. Being spoiled from working on PC’s I was a little surprised to find that the answers didn’t make much sense. In particular, the trig functions in the avr-libc package tended to give me the most inaccurate values. Furthermore, the calculation of the number of days since the last epoch was giving me a number that was too large to be represented on the microcontroller.

My next thought was to add a floating point processor to the circuit, but the problem with that is 1) added chips take up space, making the project bulky …and… 2) added chips drive up the overall cost of the project. Sometimes the best path forward is the simplest, so I did a search online to see if anyone else had already solved the problem. As it turns out, the TimeLord library does exactly what I needed it to do and it’s very easy to use. My only suggestion for the authors of this library would be to improve the documentation. Sometimes it’s hard to tell if values should be passed as local time or UTC. Beyond that, I would also add functions so that the user can pass either local or UTC without having to do the conversion. However, it did solve my problem without needing any extra circuitry.

I will be posting the full code to this project at a later date. For the time being, though, I’m posting the pieces in the same way I developed the final code which is to say that I put together several small and easy to debug code modules and then later integrated all of them into one large project. The benefit of doing it this way is that it’s much easier and faster to debug small modules than it is to try and put the whole project together in one attempt. Here is the proof of concept code for this week:

#include <TimeLord.h>

// current date - BTW - don't do this if you can avoid it.  Globals are evil.
int curYear = 2010;
int curMonth = 11;
int curDay = 12;

// west longitude and north lattitude - approximate - 
//      I'm not giving you my address in an online code example anyway... :-)
double Lw = -78;
double Ln = 43;

void setup() 
{
  // put your setup code here, to run once:
  Serial.begin(9600);
  
  TimeLord tardis;
  tardis.TimeZone(-5 * 60);
  byte day[] = { 0, 0, 12, curDay, curMonth, curYear }; // noon
  tardis.Position(Ln, Lw);
  if (tardis.SunRise(day))
  {
    Serial.print("Sunrise: ");
    Serial.print((int) day[tl_hour]);
    Serial.print(":");
    Serial.println((int) day[tl_minute]);
  }
  
  if (tardis.SunSet(day))
  {
    Serial.print("Sunset: ");
    Serial.print((int) day[tl_hour]);
    Serial.print(":");
    Serial.println((int) day[tl_minute]);
  }
}

void loop() {}

The next post in this series will have the fully integrated and tested code. I still have some modifications to make to the electrical in my garage to enable this to work, so it may be a while before I can post pictures of the final project. My goal is to have this done and installed sometime before the end of April.

Leave a comment