Hack the ThinkGeek R/C Moon to display realtime phase changes
UPDATE: This project was featured on the ThinkGeek blog !
UPDATE #2: Microsoft asked me to do a custom writeup and video of the project for their own Coding4Fun blog!
I first saw this R/C Moon Phase light at ThinkGeek some time ago and decided it would be ripe for hacking. Essentially, the R/C Moon Phase light is a nightlight that comes bundled with an infrared remote control. The controller allows the user to change the moon’s current phase with the press of a button – or automatically cycle through the standard phases of the moon (ie. waning crescent, waxing crescent, full, etc…) which it accomplishes with six LED’s and an impressively designed outer shell.
I decided that it would be more interesting if the model moon actually reflected the current phase of the moon based on the current date. Using an arduino and a DS1307 realtime clock module from Sparkfun, I was able to make that it do just that. The DS1307 module contains a coin cell battery backup that enables the internal clock to maintain the proper time, even without power, for up to 17 years!
|Light sensitive operation||✓||✓|
|Light sensitivity adjustment||✓|
|Realtime lunar phase update||✓|
|Optional mains power supply||✓|
|Open source design||✓|
|Persistent battery backup||✓|
The project is really very simple. The most difficult part was simply trying to decide which features were important, and how they should be implemented. For instance, this project doesn’t require highly accurate timing, so you may be able to get by using the arduino’s software realtime clock library and save yourself a little scratch on the DS1307 module. Let’s look at how I decided to do it:
Getting the materials
Here is a list of the items that you’ll need if you plan to do this hack at home:
- ThinkGeek R/C Moon Phase light- $29.99
- Sparkfun DS1307 RTC module- $19.99
- Arduino Duemilanove- $34.95
- 0-100k Potentiometer - $0.95
- 9V DC power adapter (optional)*- $7.00
* required only if you plan to run the moon from mains power instead of battery.
* The lunarupdate software consists of a very simple C# application that simply sends the current system date/time to the arduino via serial. Please see the Usage Notes at the bottom of the page for limitations.
On a budget?
In these tough economic times, you may be thinking to yourself, “But I can’t afford to spend that much money on a toy!” If this is the case, and you’re looking for a challenge, you can try substituting the DS1307 Realtime clock module with the arduino’s software realtime clock library. Still not cheap enough? You can build an arduino yourself on the cheap for under $15 in parts.
Disassembling the R/C Moon is straightforward. There are a number of small screws holding the moon together on the back. The moon comes apart easily when the screws are removed. There are no plastic tabs or glue holding anything together. Once the moon’s face has been removed, you will find more screws on the front holding the inner faceplate to the back. Again, these come apart with no complications.
Once you have the three parts of the shell removed, you’ll have easy access to the internals.
A quick inspection of the ribbon cable leading to the LEDs and you will find 6 small resistors (not pictured) aligned neatly side-by side. I chose to use these resistors for my project, so I desoldered them from the board. Truthfully, these resistors are a bit small, as the original moon only provided the LEDs with 4V of potential, whereas the arduino will provide 5V.
I measured the voltage drop across the LEDs (3V) while the LED was lit, and then cut one of the ribbon wires leading to the PCB and inserted my ammeter into the circuit. The factory fresh moon provides 4V of potential to the LEDs through 50 ohm resistors and pushes 15mA of current through the light. The formula for LEDs (Vs-V)/I tells us that these numbers are fairly accurate. Your choice of resistor value will determine how bright the LEDs will shine. I found with 150 ohm resistors, the LEDs drew around 10mA of current, and the overall power consumption of the project was nearly identical to factory moon. (The arduino consumes more power than the original uC) Since I have no qualms about connecting my moon to mains power and leaving it run indefinitely, I opted to use the small 50 ohm resistors that came from the factory. Using these 50 ohm resistors with the arduino, the LEDs will draw around 25mA each. A real drain on standard AA batteries. Decide for yourself which is more important brightness or battery life, and choose a resistor value between 50-150 ohms.
From this point on, the build process is fairly straightforward.
1. Connect the colored ribbon to the arduino through your chosen resistors (50-150 ohm) as follows:
- Red – Digital pin 7
- Orange – Digital pin 8
- Yellow – Digital pin 9
- Green – Digital pin 10
- Blue – Digital pin 11
- Purple – Digital pin 12
- Brown – Arduino GND
2. Connect one lead of the supplied light-dependent resistor (on the top of the moon) to the 5V power of the arduino and the other lead of the LDR to one of the outside legs of your potentiometer. Run another wire from the same leg of the potentiometer to digital pin 2 of the arduino. Finally, connect the middle leg of the potentiometer directly to the arduino’s ground (GND). The third, unused, leg of the potentiometer can be snipped off with a pair of cutters. The arduino will use this rudimentary voltage divider to sense when the light levels of the room are too high to operate, put the arduino to sleep to conserve battery life. When the light levels dip below a determined level (defined by the potentiometer) an external interrupt will trigger the arduino to wake up. Use the potentiometer to adjust the sensitivity to light so that the moon activates in the lighting conditions of your choice. I mounted the potentiometer through an existing hole on the back of the moon using a couple drops of hot glue.
Doctronics has an excellent article on voltage dividers and LDRs in case you need further discussion on the concept of an LDR voltage divider.
3. The DS1307 RTC module uses a simple I2C interface to communicate with the arduino. Connect the power and ground pins to the arduino. Connect analog pin labeled SDA to arduino analog input 4, and SCL to arduino’s analog input 5. The remaining RTC pin, labeled SQW can be ignored. You can find more information on communicating over I2C using arduino in the arduino playground.
4. Next is the battery compartment. You will see a + and – symbol lightly engraved next to the battery terminals. The wire coming from the + terminal will go to one leg of the power switch on the side of the moon. Take the other wire extending from the other leg of the power switch and attach it to arduino VIN pin and connect the wire coming from the – battery terminal directly to arduino GND. This will provide a hard power switch for the project when not in use.
5. And that’s a wrap. Determine the best way to mount the components. Your implementation will vary based on the arduino model you used. For my moon, I decided to cut a hole large enough for the arduino to protrude slightly from the bottom. This allows easy access to the USB port for updating the internal clock (see below) and a barrel connector for external DC power supply. I used a few small drops of hot glue to hold the arduino in place. I used the glue sparingly so that I can remove the arduino for future projects if need be.
As an added bonus, I have included a small Windows application, written in VC# Express 2008, which allows the user to update the internal clock with a single click. Just install the FTDI USB to Serial drivers (also included with the arduino development environment) select the appropriate COM port (most likely the highest port listed in the combo box) and click the update button.
Lunar update v1.0
- By design, the arduino requires 2-7 seconds of “boot up” time. In additon, the arduino requires restarts whenever an application opens the serial port. To overcome this limitation, I had to include a 10 second delay in the C# application that allows the arduino time to boot. In addition, this short delay in booting can cause the modified moon to appear unresponsive to changes in ambient light for the first 10 seconds of operation. If this behavior concerns you, you may consider Limor Fried’s No-Wait bootloader hack that removes the boot delay.
- The included C# update software is very crude. It opens the serial port, waits 10 seconds, and then dumps the data out to the serial port, and then reports that it has completed. There is no Exception handling, and no progress bar to indicate that the software is running. The software will get the job done, but not cleanly. Feel free to expand on the software at your leisure.
- It would also be nice to design a protocol for sending the updated date, to ensure that the values are accurate.
- The C# application only checks for serial ports when the application is launched. You must plug in the moon via USB prior to launching the application or the serial port will not be listed in the combo box. This project was about modifying the moon, the software is just a means to an end for me.
If you have questions, comments, or concerns, as always email them to me.