07 February 2012

A high-tech night light

Often I find myself working on small projects that might be categorized as silly and/or impractical. However, my aim is usually to learn something new and to have a little fun in the process. So here is an example of such a project that I've been tinkering with recently.

Worlds highest-tech night light?  The two AA cells are underneath and connect via the connector on the upper left.

This project is a night light that just consists of a common 5mm LED for the light, an ATmega328P microcontroller, two AA cells, and a minimum of other parts. The twist is that the LED turns on at sunset and off at sunrise, adjusting its on and off times automatically day by day throughout the year, including adjustment for daylight saving time. I also added a piezo transducer to make some noise at sunrise and sunset. This was mostly a debugging aid to make it easier to check whether it was turning on and off at the right times. This project has several features of interest:
  1. Timer/Counter2 is clocked from a 32.768kHz crystal and configured to generate an interrupt every 8 seconds.
  2. The interrupt service routine (ISR) that handles these interrupts comprises a software real-time clock (RTC) that tracks hour, minute, second, day, month, and year (and adjusts for leap year).
  3. A friend found a function on the web that calculates sunrise and sunset times given day of the year, latitude, and longitude. (I tweaked it a bit, I think that I improved it some.) Combining this with the RTC makes it quite straightforward to turn the LED on and off at the appropriate times. (But I definitely do not get all of this astronomical right ascension and declination stuff!)
  4. I had previously written code to automatically adjust for daylight saving time, so it was easy enough to include (feature creep!) The rules which determine when DST starts and ends are stored in EEPROM. There is a small separate sketch to store the DST rules.
  5. Since the project runs on batteries, we want to conserve power. So in between interrupts, the MCU puts itself into Power Save mode, which keeps Timer2 running so that the RTC continues to keep accurate time, but powers off most of the other systems. An interesting point here is that the MCU can sleep regardless of whether the LED is on or off. Once the pin driving the LED is set, it retains its state while the MCU sleeps. While sleeping, with the LED off, the project draws right around one microampere. The Timer2 interrupt every 8 seconds serves to wake the MCU, update the RTC, and switch the LED on or off if appropriate. I haven't kept track of how long the battery will last, but I'm guessing at least a few weeks.
When not sleeping, the MCU is clocked from the internal RC oscillator, running at 1MHz. Because of this, the sketch needs to be uploaded from the Arduino IDE using an ICSP programmer (I use Adafruit's USBtinyISP).

I added the following entry to the Arduino boards.txt file, which is used for this project. Note the fuse byte settings. The extended fuse byte sets the brown-out detector level to 1.8V (to keep the MCU in reset if the battery gets too low), and the low fuse byte is the same as the factory default setting to give the 1MHz system clock.

 uno1.name=Arduino Uno ICSP @ 1MHz

Even though the project works well, it's not what I'd call a practical project that will ever get past the breadboard stage. It ended up with a fair amount of code, which seems like definite overkill for a crummy night light (wouldn't a photocell be more straightforward?) But I figure why not, if I learned some things and had a good time with it. I hope you enjoy it too!

The code and schematic for this project are available on github.

1 comment:

  1. I hope to see more of your work. This is wonderful overkill :-) (Not sure my first comment posted)