Project: Anniversary
A few weeks back my girlfriend and I decided to buy an XBox 360 for ourselves for our upcoming anniversary (May 28). It was that time that I realized I still had a month if I wanted to do something else for her. Something more personal and special.
I remember seeing an Instructable involving a jewelry box with an LCD screen inside of it. When you opened the box, the LCD would display a random message such as “I love you”. I thought this was a good idea but I wanted to do something more original. I also remembered a project where someone created two small “stones”. Each person would keep a stone in their pocket and when they were thinking of their significant other, they would squeeze the stone. The other person’s stone would then warm up. I really liked that idea, but again I wanted to be more original and I also had no idea how to accomplish something like that. Also, the wireless communication aspect of that just seemed impossible for anything more than 100 feet.
One night, I couldn’t fall asleep and an idea hit me. A lamp. A heart shaped lamp. This lamp would be hooked up to the Internet. I could send the lamp a text message from my cell phone whenever I was thinking about my girlfriend and the lamp would them “throb”. I kept brainstorming. Maybe it could blink different colors for different meanings. Or maybe it can blink at different speeds. What if I added an LCD screen so I can have it display messages? The reason this is a good idea is because there are many times that my girlfriend is at home (like for lunch) and I am either at school or work. Usually we just text each other but I thought this was a more interesting way to show I was thinking about her.
I started this project with a BS2 since it was all I had and also all that I knew how to use. The first problem I ran into was communicating with the BS2 via the serial port on my computer. It worked fine using the BS2 programmer’s debug window but I could NOT make it work with anything else. Not Hyperterminal. Not Perl. Not C. Not Java. I was so fed up at this point. I had spent days trying to get serial communications working and I just could NOT. I had all of the settings set correctly but it just didn’t want to work. As a last ditch effort I thought I’d try Python. I had heard good things about Python but I had no experience with it. 4 lines of code later, serial communications worked perfectly. I love Python.
Next I had to find a way to communication with GMail using Python. I was able to find a Python module that did just that using an encrypted POP3 connection. It was very similar to the Perl module I had used. This didn’t take long at all.
I was able to get a basic version of the lamp up and running but I quickly ran into limitations. The main limiting factor: throbbing LEDs. The only way to control the brightness of an LED is to limit the current flowing through it. This is done using a technique called pulse-width modulation (PWM). The BS2 has PWM functions built in but they are not fast. In fact, it is impossible to do it on more than one pin at a time. Even without interrupting the PWM function you can still notice the LED flickering. This was not good enough. I didn’t want the lamp to just blink on and off like some kind of warning light. I wanted it to glow.
Five days and $115 later, I had everything I needed to start learning the SX chip from Parallax. I bought their starter kit and a few extra SX28 modules in case I blew one up. After all, I had never used one before and they are a bit more complex than the BS2. I went through a bit of the books that came with the kit and ran a sample program or two to get a feel for the SX. It was a bit confusing at first but I got the hang of it. The next thing I wanted to do was to just get a throbbing LED on this thing.
After some searching around I found this forum post on the Parallax SX forums. It seems that someone already created all the code necessary for a dedicated PWM chip using an SX28 module. This was absolutely perfect. This code allows one SX chip to control the brightness of 16 LEDs simultaneously. It uses an interrupt routine to accomplish this task. I tried loading his code onto an SX. I also loaded up his sample BS2 code onto my BS2 to see if everything would work. It did. It was so awesome.
Next, I had to port my code from the BS2 over to the SX. It took some fiddling but in the end, it worked. My next problem was that this worked only for one light of one color. Not good enough. I want multiple colors. Many colors. Rather than just having 10 LEDs I decided that one RGB LED would be perfect. I can get hundreds of colors out of one LED that way. Unfortunately I didn’t have any RGB LEDs and neither did anyone I knew. I didn’t want to wait for them to come in since our anniversary was rapidly approaching. I checked my local Radio Shack and Fry’s but they didn’t have any either. I ended up buying a few different colors and messing with those. A week or so later I was back at my local Radio Shack looking for some other parts when I noticed that they had two RGB LEDs. It turns out that the guy there ordered some specifically because I had asked for them. I thought that was amazing. Nice guy.
I picked those up and went home to start modifying my code. It turns out that these RGB LEDs are actually common anode, not common cathode as I expected. This presented a problem. The PWM code I downloaded from the Parallax forums was meant to work with a common anode LED. It didn’t work correctly on this one. I had to switch a few things around in the PWM code to get it to function, but it ended up being much simpler than I thought it would. After I modified the code, everything was working.
Next I wanted to find a way to make an almost unlimited amount of colors. This created another problem. In order to get an obscure color, you have to do PWM on all three LED pins. That’s no problem. However I needed to control the brightness of that one color. The way you control brightness is by using PWM on the LED. I was already doing that. How could I do PWM over PWM? It didn’t make sense. One thing I tried was to set the common anode pin on another PWM pin, instead of hooking it straight to +5V. This sort of worked. Lets say that I had Blue lit up to 50% and Red lit up to 100%. When I throbbed the common pin, the red would start to light up first, then the blue would come it. The problem is, you could very distinctively make out that one light turned on later. The only option I could think of was to use some sort of ratio to make the LEDs brighter together. This seemed too complicated. I decided that having just seven colors should be plenty.
Once I had the main code working, I had to build the casing. I ended up using poster board and wax paper. I cut two heart shapes out of the poster board for the main lamp. One of them was cut into a picture frame style. I then hot-glued two sheets of wax paper on either side of that and cut them to the heart shape. The wax paper is used to diffuse the light from the LED. I used small poster board chucks to space the heart pieces apart and attach them together.
Then I made a small box shape out of poster board for the PCB. I cut a small hole in the side that attaches to the heart piece and used a plug for the LED. The LED leads stick out of the back of the heart piece and plug straight into the box. I then used a piece of tape to better attach the heart piece to the box. The serial and power cable just comes out of the back of the box. The box also works as a stand.
All in all, it works pretty well. This was a very educational project for me. I learned a three new programming languages, serial communication, a new microcontroller, and more. My girlfriend really likes this gift. I wish I had taken more photos during the build process but I was trying to keep it a total secret until it was done.