Have you ever wanted to try one of those fancy alarm clocks that mimics the sunrise to wake you up? Do you want to add some colored lights to your room? Do you want to control it all from any device with an internet browser? Then check out this alarm clock I made using what I learned building my automatic fish feeder.
The Light Alarm's main purpose is to make sure there is light in my room when I wake up, especially in the winter time when it's usually still dark out. The light fades in for a predetermined length of time that ends in full brightness at the set alarm time. But that's just the first mode, there are 7 other lighting modes to play around with!
The Light Alarm is controlled via an HTML page that is hosted on the ESP-8266-12e board. It can be accessed from your home network or be configured to be accessed from anywhere on the internet with port forwarding.
Step 1: Materials:
- ESP-8266-12e (NodeMCU) board
- Latest Arduino IDE
- Libraries needed for the code installed
- Notepad++ (for editing the HTML if you want)
- Browser (I used chrome, but any should work, especially if it lets you see the html code working)
- 3D printer with at least 150mm x 150mm build area
- White or clear plastic filament (for the shade, the mount can be any color you have)
- 4 digit 7-segment display with TM1637 chip, I used one of these
- 1 meter addressable RGBW LED strip, sk6812. My strip has 60LEDs/meter, but is no longer sold. The arduino code is set up for the RGBW, so you'll have to rewrite it if you want to use an RGB strip. I would recommend a strip with at least 60LEDs.
- IF the strip doesn't have an adhesive backing: scotch tape and super glue
- Protoboard to mount the board
- 24AWG wire (I recommend multiple colors)
- At least 6ft of wire for power. I recommend using whatever your local hardware store sells for table top lamps.
- 5V power supply, I used this one
- Don't forget adapters for the power supply
- Soldering Iron
- USB cable to program the board
- hot glue
- Header pins (Male and Female)
Step 2: Programming the Board
The Board will have two sets of code on it, the regular arduino code that runs and the HTML code that it sends to your browser. You upload the arduino code as you would with any other board. The HTML, however, requires a plug-in to upload to the SPIFFs memory on the board.
For a tutorial on how to use SPIFFs, see https://tttapa.github.io/ESP8266/Chap11%20-%20SPIF...
For how to upload the HTML code, see https://www.esp8266.com/viewtopic.php?f=32&t=10081, you will need to install a plugin to arduino in order to do this.
The HTML needs to be saved to a folder in the arduino project folder simply called 'data'.
Uploading the HTML takes a couple of minutes, I was able to play an online race or two in Mario Kart 8 while I waited. Because of this, if you are making changes to the HTML, use notepad++ to edit and drop the file into a browser like chrome to test it.
Step 3: How the Code Works
The code in this project is separated into two files: The code run by the board, and the HTML stored in the board's memory that it sends to the browser when you navigate to the web page.
When you connect the board to power, the board's code starts, like any arduino. It connects to your home WiFi and then contacts a NIST server to get the current time to set the internal clock. After the clock is set, the web server starts and you can connect via your favorite browser.
You have to connect by the IP address of the board, so be sure to reserve a static IP on your router. I changed the port on my lamp as well, so to connect I navigate to 192.168.0.170:301/ . If you want to connect to your lamp from anywhere in the world, you will have to set up port forwarding on your router. You will then have to connect to the IP address you see when you connect to http://www.whatsmyip.org/ and the port you set up the lamp's local IP to be on.
Once you connect, the board sends the HTML file to your browser, which decodes it and displays page. The changes you make do not affect the board until you hit one of the buttons. on the web page. When you hit a button, your browser sends an html form to the board with the current settings and the board adopts those settings and sets the displays.
The settings are fairly straight forward. The page scales to the width of your browser and does look a bit better on mobile. To change the appearance of the settings page you will have to edit the HTML, and there are plenty of other tutorials online for that. Since this was my first time using HTML, I learned mostly using https://www.w3schools.com/HTML/html_intro.ASP.
When the page loads you will see four buttons, a slider, and a drop down menu. The top button is the main "enter" or "engage" button. The next two buttons toggle the digital time display and whether it displays time in 12 hr or 24 hr format. The slider controls the brightness of the digital clock, and that is updated whenever you toggle the display mode or turn the clock on. The last button is supposed to turn off all lights, but for some reason that isn't functioning with this version of the code. Instead, pressing the "Engage" button with no settings selected will turn the lights off.
The drop-down menu contains 7 system modes, selecting one will display the necessary settings below.
- Mode 1: Alarm. Enter the time you want the light to reach full brightness and how long you want the fade in to be in integer minutes. Default is 6:00:00AM and 15 minutes. The light will stay at full brightness for the same amount of time it fades in before automatically turning off. Default can be changed in HTML code.
- Mode 2: Analog Clock. Choose three colors to represent the hour, minute, and second hands on an analog clock. A slider above the three color pickers will automatically put in preset cool or warm colors if set left or right, respectively. If the slider is set left or right, then returned to the center, then the color pickers are all set to black (0,0,0,0) [R,G,B,W]. When an all-zero color is sent to the board, it is randomized. *This may cause lights to flash excessively.* If you want a light to remain off, setting any value to 1 will result in 'black' (all values default to 1 (01,01,01,01) when the color pickers are initialized). The color picker and RGB sliders are linked, while the W slider is independent.
- Mode 3: Color. Choose one color to set the lights to. This will remain until it is changed by the user.
- Mode 4: Color Cycle. Choose three colors to cycle through and enter the time to hold on each color. The same methods apply to picking the colors as in Mode 2. Random colors work best with this mode.
- Mode 5: Color Cylinder. Choose three colors (same as previous) and the RPM of the cylinder. The lights will display as a pattern of stripes that rotate around the axis. at the RPM you chose. The default RPM is 60, or 1 rev/sec. Random colors may result in flashing lights!
- Mode 6: Color Vortex. Set three colors and the RPM. This mode is not perfect, but the idea is that the lights swirl around the clock. There is built in randomness so it's best to just use the temperature slider to pick whether the vortex starts out warm or cool.
- Mode 7: Rainbow. Set the Cycle speed, the RPM is fairly useless here. This was a pre-made example from the Neopixel Library with some edits to allow the board to still respond to user inputs.
Once the settings are chosen, pressing any button will send an HTML form to the board, which uses the values in the form to change the display settings. The "Engage" button sends all the settings, while the two clock buttons send only the clock brightness. The "off" button is supposed to just turn off the LED strip, however there is a bug that is preventing that from working. Pressing "Engage" without changing any settings seems to work instead. Once the board has parsed the settings, it redirects your browser to the initial HTML page.
Note: Setting the alarm time changes the system mode to 1, which will stop any mode that was running before and reset all settings. However, starting a different mode after setting the alarm time does not change the time that you set, so you can set your alarm and then start a new mode. If the new mode is not turned off before the alarm starts fading in the white light, this can cause flashing. To prevent this, the board is hard-coded to turn off all lights and set the system mode to 1 (alarm) at 2am without changing the set alarm time. This hard cutoff time can be changed in the arduino code.
Step 4: Setting Up Your Network and Connecting
This step is a bit vague since every router is different. Google your particular router model to find the settings you need to change.
You need to log into your router and probably turn on advanced mode. On my router, I have to go to DHCP Server to reserve an IP address. Find your ESP8266's MAC address; it'll be the one on the DHCP client list (or your router's equivalent) that goes away whenever you unplug the ESP.
Use the MAC address to reserve the lamp's IP address. Make sure the entry is enabled if your router has that setting.
If you want to connect from outside your personal network, you'll have to google your router to find out how to set up port forwarding.
Step 5: 3D-Printed Parts
The printed parts should fit on most printers. There are two parts: The mount and the shade.
The mount is what the LED strip is wrapped around, in a spiral pattern, and it's diameter is such that a 60-LED, 1-meter strip should wrap around 3 times and all the LEDs should align axially. If you are using a strip where the LEDs are spaced differently and don't align on the mount like they should, change the diameter with the models provided. The diameter is C/pi, where C is the circumference and is 1/3 the length of the strip. The semicircular openings at the wall-side of the mount allow for the power cable and airflow to pass through. The cross-braces provide rigidity and a surface to apply command-strips to for mounting.
The shade has a friction fit with the mount, and there is a notch to align the shade with the mount. The notch should be at the 12- or 6-o'clock position when mounted on the wall, and the 7-segment clock display should be aligned with the notch. The shade acts as a diffuser for the lights and is very thin as a result. I printed it with a .5mm nozzle, and most commercial printers come with .4mm nozzles so there should be few issues, but be sure to check your slicer to make sure the shade will print properly. Also be sure to use a white or otherwise translucent plastic for the shade. Other colors will distort the colors of the lights or block too much light.
Be sure to check that the digital clock display you are using fits in the shade. It is designed to friction-fit in place with enough clearance for the clock's wires. Use the models to change the clock mount. When changing the shade's model, be sure to keep the thickness of the front face under 1mm, so that the clock is visible through it with little diffusion.
Step 6: Wiring and Board Assembly
The board and wiring is far less complicated than my fish feeder. Simply solder a couple of rows of female header pins to a protoboard for the ESP-8266-12e to sit in, as well as two rows of male head pins to attach power. I soldered the two clock data wires and the LED strip data wire to their respective pins on the protoboard, and all power and ground wires were soldered to the respective power rails I made on the back of the board.
The other side of these wires should be female headers for the clock and the LED strip connector for the LED strip. You may need to solder male pins to the clock and I recommend angled pins for it. The LED strip wires and power wires should be routed to the wall side of the board (the side with the ESP) and the clock wires should be routed to the front side (where all the solder joints are).
For a power line, I used 6ft of 16-26 stranded copper wire. It was a bit thick so I split each wire between three female pins to connect to the power and ground rails. The other side should be whatever connector you got for your power supply.
Hot glue all the exposed solder joints (especially on the power cable, and ESPECIALLY if there is exposed copper like mine) to insulate everything from accidental shorts. You can also hot glue the clock to the board (back of clock to solder side of board), but I found that this was a weak joint and wasn't all that necessary once everything was mounted.
Coil the LED strip around the outside of the mount. BE SURE to test the strip in mode 2 to check that the analog clock is going in the right direction. Be sure to leave a ~5 mm gap from the front edge for the shade. The first LED of the strip (the LED the seconds color appears on at the top of each minute, at one end of the strip) goes at the 12 o'clock position. when the lamp is mounted to the wall. When you have LED strip in place, use its adhesive backing (if it has one) or glue to stick it to the mount. Super glue will work best if the strip doesn't have an adhesive backing. Use scotch tape to hold the strip in place while testing and while glue dries.
Thread the LED wires through the semicircular holes into the mount to connect to the board. The power cable is also threaded through here, be sure to pick a hole that the cable won't pull on due to gravity or accidental pulls.
Step 7: Mounting
To mount to the wall, simply use 3-4 3M command strips, or as many as you like. Use the notch in the mount to check that it is level. After the mount is mounted, connect the power cable and LED wires to the board, and insert the clock into the shade. Then, simply pop the shade onto the mount and plug the power cable into the power supply!