A couple weeks ago my Dad mentioned to me it would be cool if advent candles automatically lit themselves according to the date. (One candle is lit starting the 4th Sunday before Christmas with an additional candle being lit for each of following Sundays). I thought, hey, that sounds like an interesting project, so why not build it. I didn't want to bother with the complexity and danger of lighting real candles, so I started searching for suitable LED candles. I ordered these Advent Tealight Set Purple and Pink Battery Operated from Amazon:
I just had to remove a screw to pop the bottom off which revealed the tealight's simple construction. The coincell just slide in between the two battery terminals, and the switch closes the circuit:
The whole board came out with no resistance to reveal the LED on the other side. I was confused about the various pads on the PCB as they didn't seem to be used. It must have been used for some other product. The LED flickers pseudo-randomly, so I reckon there is a microcontroller embedded inside the LED lens:
The multiProductLinkCR2032 coincell battery that came with the candle initially measured 3.3V but quickly dropped below 3V after running for about 10 minutes. I removed the battery and hooked the terminals up to my benchtop power supply set at 3VDC. My power supply showed between 0.00 and 0.01 amps being drawn (it's not more accurate than that). I hooked my DMM in series to measure current and observed a maximum of about 11 mA. The reading fluctuated quickly due to the LED's flickering.
I thought the simplest approach would be to just control power to each of the LED candles in order to turn on and off as needed. This could have been implemented with a simple 8-bit microcontroller. However, I've been enjoying learning Python recently, so I decided to use a along with the . The RTC is needed to make sure the Pi has the correct date when powered up as it won't be connected to a network. I'd already built a Raspberry Pi time and temperature display earlier this year, so I was familiar with how to set the system clock during boot using the RTC.
I choose the to connect all the components to the Pi. The prototyping area on the Pi Plate is large enough to stick on the which makes it easy to experiment while developing a circuit:
I used the case as the top cover is removable which is perfect for use with the Pi Plate. To avoid being tethered to an AC outlet, I decided to power the Raspberry Pi with a battery-powered USB charger which I previously wrote about in my blog post: Portable Pi
I made this diagram with Fritzing to show how I connected the RTC, a pushbutton and the four LED candles:
I couldn't figure out how to place the tiny bread on top of the Pi Plate in Fritzing, so I just show the connections to the pushbutton and RTC as being soldered. The 4 LED candles are represented by the yellow LEDs in the diagram.
Real-Time Clock WARNING:
For the Adafruit RTC module, it's very important to make sure the 2.2k Ohm resistors are not installed. I had previously soldered them in, so I had to snip them off before using with the Pi. With the resistors removed, the 5V RTC can safely communicate with Pi's 3.3V logic level.
Originally, I had prototyped using a NPN transistor to turn on one of the LED candles. However, the Pi's GPIO pins can individually provide 16mA max and 51mA total. Each candle only drew a max of 11mA when testing which is within those limits. Avoiding transistor circuitry gave me the advantage of being able to wire the candles to the screw terminals on the Pi Plate.
I only had one set of candles so I was cautious of providing too much voltage or current to candles. Since the GPIO pins are 3.3V, I added a diode () in series to drop the voltage down to around 2.7V. I also added a 100 ohm resistor in series as well to limit current. I couldn't tell if there was a current limiting resistor integrated into the candle's LED or not. I wanted to play it safe in case the LED's design was depending on the coincell's internal resistance to limit current.
I measured a maximum current of 3.66mA with my DMM in this configuration (although it is always fluctuating as the LED flickers). This correlated approximately with the maximum voltage I measured across the resistor of 350 mV (350mV / 100Ohm = 3.5 mA). The maximum voltage drop across the LED was 2.5V. These readings indicate the configuration is safe for both the Pi's GPIO pins and the LEDs.
To wire up each candle, I soldered a red wire to the positive battery contact and a white wire to the negative battery contact. I hot glued the connections to make sure the two contacts wouldn't touch and short out. I routed the wires out the bottom and was still able to close the bottom cover almost flush. I then connected the red wire to the resistor and the resistor to the diode by twisting their leads together. I then soldered the twists:
Finally, I covered the exposed connections with heat shrink. The white wires from each candle were all connected together to a single white wire by twisting the ends together to form a single ground wire. The big twist was soldered and covered in heat shrink wrap. The four red wires and single white wire were then inserted into the Pi Plate screw terminals:
|Wire||Pi Plate terminal|
|Purple candle #1: Red wire||#17|
Purple candle #2: Red wire
|Pink candle: Red wire|
|Purple candle #3: Red wire||#22|
|Combine white wires||GND|
NOTE: #21 will be connected to GPIO 27 on a Rev 2.0 Pi. If you are using a Rev 2.0 Pi, then you'll need to modify autoadvent.py to use GPIO 27 instead of GPIO 21.
The Pi won't be connected to a screen or keyboard (e.g. "headless), so I wired up a push button which will cause Linux to shutdown when pressed. The one contact of the switch is wired to GPIO pin #23 and the other to ground. There is no pull-up resistor as the pin's internal pull-up is enabled via the RPi.GPIO Python module.
All the code for this project located in the repo called autoadvent in my GitHub account "pdp7":
You'll need git and the Python module RPi.GPIO installed on your Pi:
sudo apt-get update sudo apt-get install git-core python-setuptools sudo easy_install RPi.GPIO
To install my software for this project, you'll will need to clone (e.g. download) the repo via:
cd /home/pi git clone https://github.com/pdp7/autoadvent.git cd autoadvent
The software assumes that it will be located in /home/pi/autoadvent.
When the Pi boots up, the system time must be automatically set from the Adafruit DS1307 RTC, and the Python script to control the candles must be started. This process is started with a init script called autoadvent:
The init script calls this shell script which initializes the RTC, sets the system time from the RTC and then calls the autoadvent.py Python script:
(Note: if you have a Rev 2.0 Pi, then you'll need to change "i2c-0" in the above script to "i2c-1" as the I2C bus is on the GPIO header has changed between Rev 1 and 2)
Follow these steps to install the script:
sudo cp /home/pi/autoadvent/autoadvent /etc/init.d/autoadvent sudo update-rc.d autoadvent defaults
The existing startup scripts which set the system time need to be disabled so as not to conflict with my autoadvent startup script:
sudo update-rc.d -f hwclock remove sudo update-rc.d -f fake-hwclock remove
(In the future, I'd like to figure out how to make the system's existing hwclock init script utilize the DS1307 RTC rather than having to set time in my autoadvent init script)
Finally, the I2C kernel module is required to access the RTC, so the following line must be added (if not already present) to the file /etc/modules:
After the next reboot, the init script should automatically start and the candles should light according to the date as shown in this video clip:
autoadvent.py - Usage:
The Python script autoadvent.py contains the logic for lighting the candles according to the date:
The script can be run manually from the command line for testing a specific date with the "-t" switch (make sure to stop the autoadvent init script first to avoid having two instances running):
$ cd /home/pi/autoadvent $ ./autoadvent.py -v -t "Dec 13 2012" today: Dec 13 2012 self.today: 2012-12-13 2012-12-13 >= 2012-12-02 2012-12-13 >= 2012-12-09 candles: 2 Turning on pin: 17 Turning on pin: 18
Since Dec-13-2012 is in the 2nd week of Advent, then two candles will lights. The "-v" switch is for verbose. Without it, the script will not print any output.
If I run it without the "-t" switch, then it will use the current date:
$ cd /home/pi/autoadvent $ ./autoadvent.py -v today: None self.today: 2012-12-23 2012-12-23 >= 2012-12-02 2012-12-23 >= 2012-12-09 2012-12-23 >= 2012-12-16 2012-12-23 >= 2012-12-23 candles: 4 Turning on pin: 17 Turning on pin: 18 Turning on pin: 21 Turning on pin: 22
As today is Dec-23-2012, all 4 candles would be light as it is the 4th week of Advent. Here is a clip of the candles light when recorded during the third week of Advent:
autoadvent.py - GPIO Pin Configuration:
I built this project with a Rev 1.0 Pi. For a Rev 2.0 Pi, the line that defines "pins" in autoadvent.py needs to be changed as described in the comments below:
autoadvent.py - Execution & Shutdown:
autodavent.py will not adjust the number of candles if the date changes after it has started running. The intended use case was to have the Pi turned on for a short duration such as as during dinner. Once the GPIO pins for the candles are set, autoadvent.py just enters an infinite loop where it checks if the pushbutton has been pressed and sleeps 1 second. If the pushbutton is pressed, then it shutdown the Pi via "sudo halt":
Here is a video clip of the shutdown process:
My dad was quite excited to receive my autoadvent project and decided to make a more festive housing to contain the Pi. Here it is along with a "real" Advent wreath, a Velleman 3-D Xmas tree, and a PICMas tree:
Additional photos of the project and its construction can be found in this Picasa gallery:
(note: this is a not an entry for the Double Your Memory Challenge)
*Products and resources listed are listed to help members build their own Pi Projects. They are suggestions and listed for educational purposes. For substitutions of any parts, please post a question asking the original author.