Introduction: Oled Alarm Clock
There's a lot of arduino/ESP32 clocks going around, but do they use those nice and crisp OLEDs?
I've been experimenting with arduinos and ESP32's for a while now, but I never made it to a finished product. I've made an alarm clock with 4 1.3 inch monochrome OLEDs. The clock also features a dimmable bedside lamp and an USB charging port (no one has spare outlets next to his bed). The OLEDs are dimmable as well, this was added last minute after my project was threatened by my girlfriend. Should dim not be -in girlfriends voice- dim enough, I can also provide a version of the code where 3 displays are powered of between certain hours. The goal was to make an easy serviceable clock, with a look beyond "prototype". While making my clock I encountered some difficulties I had to solve, which is why I think this instructable is worth sharing. The clock can be made with little tools, I don't like the "and for the next step I used my 10.000€/$ CNC mill" tutorials.
Some things that will be explained in this instructable (in-structable-ception):
- How to use/wire an I2C OLED display with arduino/ESP32
- How to use multiple I2C objects with one arduino/ESP32
- How to make a "scroll-able" menu using a rotary encoder (+ how to use an encoder with an ESP32/arduino)
- How to design and order a custom PCB using fritzing.
- The clock also uses a RTC (real time clock), led driver, step down voltage module... I won't really get in to these because there's really a lot of information readily available for these modules.
I would like to note that I'm not a professional programmer. The goal of my instructable is to explain the points I mentioned above. How I put it all together for my final product is might not be the cleanest way. It's the way that allowed me to keep track of it all.
When shopping for supplies I always try to weigh for the importance of quality/documentation vs price. My supplies are a mix of A-brands and cheaper Chinese parts. Mouser is a great supplier if quality is important, I order from Banggood/Aliexpress for the cheaper parts.
- An ESP32 board, I used the Huzzah32 from adafruit, but there are lots of other (cheaper) options. I chose the Huzzah32 because it's very well documented.
- 4 1.3 inch I2C OLED displays (128x64, with the SH1106 driver), the 0.96" ones are more common but for this project I prefer the 1.3" ones
- Sparkfun femtobuck driver to drive the LED
- RTC clock, I used one with a lithium cell
- Arduino nano
- Female USB 2.0 port (I used: SS-52200-002 from Stewart Connector)
- Female DC jack (I used: L722A from Switchcraft)
- 12V 3A DC adapter (GST36E12-P1J from Mean Well)
- Custom PCB, optional but this makes the project a lot more compact and easily serviceable if a part dies + more reliability because less wires (jlcpcb.com)
- M3 screws & bolts
- M3 brass inserts
- 12V to 5V step down module from Pololu (DF24V22F5)
- 3 watts powerled with heatsink
- Jumper wires
- I2C multiplexer (TCA9548A from adafruit)
- 2 Rotary encoders (I've tried some, not all work with my code. The one from "DFrobot" works and so does the one from with the round PCB from "DIYmore". My code doesn't seem work for the pushbutton of the KY-040 type.My alarm clock uses the one from DIYmore because they are very easy to panel mount (no extra screws/holes needed).
- Assortment of female headers (optional)
- Wood for the frame: 18mmx18mmx2400mm
- Tracing paper
I used some tools (soldering iron, 3rd hand, saw...) as well, but nothing really exotic.
Step 1: Using an Oled
To use the OLEDs you have to install a library. I use the U8G2lib from Oli Kraus, it is very comprehensible and has a reference guide with clear examples. https://github.com/olikraus/u8g2/wiki
I've added some example code. The code works for both arduino and ESP32, but the ESP32 is less likely to run out of memory. All the oleds I've tried so far work with both 3.3v (ESP32) and 5V.
Step 2: Multiple OLEDs
This is where my project starts to differ from lot's of other alarm clocks. Most arduinos/ESPs have only one or two I2C pins. This kind of limits the use of I2C parts. What if I have 4 I2C sensors and want to display their readings on a I2C display? Enter the multiplexer. The muliplexer allows you to address 7 different I2C parts. This allows my ESP32 to use an I2C real time clock, and to display the time using again I2C over the 4 displays (or more, don't let me stop you).
I've added some example code for the ESP32, from here on I'm not sure the arduino can keep up. The example only uses displays, it can be other things like I2C sensors etc as well. The principle is always the same, you call the right channel with the "tcaselect(#);" function, then you execute whatever code necessary for you I2C object.
Step 3: Creating a Scrollable Menu With a Rotary Encoder
First things first, test your encoders. I've added some code to test your encoder modules. As stated in the supplies: I've only succesfully tested my code with the rotary encoder modules from DF robot and the module with the round PCB from DIYmore. See the pictures above for the right encoders.
The library I used is this one: https://github.com/MajicDesigns/MD_REncoder
The PDF I've added hopefully helps with the menu structure I've used for my clock.
Making the encoder work, was the most difficult part for me in this project. There's a lot of different encoders, and a lot of different libraries that are not always compatible with the ESP32. But I think a (working) rotary encoder is an elegant solution if you want to input something. Should I have used only buttons, I would have needed more than 1 and setting the time would take a lot of presses.
Step 4: Putting the Previous Code Togetther
The title kind of summarizes what I did. I tried part for part and then I put everything together. But because nothing's ever easy, I had to change some things. The serial communication is a slow process. This gets in the way of reading the encoder properly. To overcome this I added interrupts to the pins of the encoder. The code to read the encoder is then immediately called if you push or turn the encoder.
Once you understand how the menu's are built, you will find that it is very easy to add or remove features to your own liking. Perhaps you would like to fetch the current weather or time from the internet and display it?
I've left out many such ideas because I wanted above all a reliable time-peace. One that does nothing automatically. I work very odd hours in a daylight savings zone. Every time the hour is changed I'm nervous to oversleep. Will my phone automatically change the hour? Will my watch? Well, my clock won't, unless I change it myself. But perhaps you want to put your clock in the kitchen? Different scenario, add features till the memory is out!
Step 5: Custom PCB With Fritzing + Schematic
Point of attention: Adafruit points out that while you can power the huzzah32 via the USB pin, you must be careful to not simultaneously use the micro USB power inlet. My PCB is powered via the step down buck, which then powers the huzzah via the USB pin. So always unplug external power/remove the huzzah from the board when uploading.
I decided to solder female headers on the PCB because it makes it easier to swap out a part, or add for example an extra I2C sensor. This also allows me to easily remove the nano or the ESP32 to load the programs.
I've added the Frizting file, I can type a novel here, but I think the example speaks the best. I started of with the schematic of the whole setup. While Fritzing has a lot of parts in it's bins, not everything is there. Sometimes you can find the Fritzing part on the internet, sometimes you can't. The parts that I could not find, I simply replaced by a female header part. If you right click it, you can edit the header to the amount of pins you want, and assign a pinout to it. I did this with every part I couldn't find. As almost all modules use the same pitch of 0.1in (2.54mm) this will give you the correct spacing for the part.
Next you switch to the PCB view of the fritzing app. A PCB will be put in place, if you click it, you can set its size and choose a single or double layer PCB. Mine uses 2 layers. Fritzing will suggest the connections you have made in the schematic view. The program has a autoroute option, but I never use it. I like to manually organize my connections. In the PCB view the yellow connections are in the top layer, the orange are in the bottom layer. Again if you click on the connection you can choose its properties.
To make the actual PCB, you have to export it as a gerber file. Before you do this, under the tab "routing" you can check the design rules.If everything checks out you can click on "export for PCB". Most manufacturers will ask for gerber file, so select export to gerber.
I ordered my PCB from JLCPCB, I like that they immediately quote you a price. There are of course many other options.
About the schematic: there's 2 voltages that are used. The LED and femtobuck are directly powered by the 12V supply. The rest is powered via the step-down buck with 5 volts.
Step 6: Design + Lasercutter
For my first design I tried using solid oak (I'm following woodworking classes), but it fast became clear that this was not ideal. The wood is too thick, making it difficult to fit your parts. The 3mm birch multiplex allows for easier ways to fasten the encoders and displays.
I found an online lasercut service, snijlab.nl, available for hobbyists located in Rotterdam (they ship to Belgium, The Netherlands and Germany). On their website you can upload your drawings and they immediately quote your price. I used Autocad, which I have at work, but the software doesn't really matter. It just has to be a vector drawing (Vectr, Illustrator, Inkscape...). Most shops use colors to determine whether you want to cut or engrave.
Some things to keep in mind:
- Max. dimensions of the lasercutter (I drew a frame around my parts)
- Min. distance between cuts
- Make sure you don't draw any double lines, the laser will do an extra pass, costing you more.
- When plotting to PDF, make sure you plot 1:1. You don't want to scale down or fit to paper.
Step 7: Assembly
I built the clock around a wooden frame, the panels are kept in place with M3 screws and inserts in the frame. Should I ever build a version 2, I would use aluminum "L" profiles to attach the panels to. It was very difficult to precisely drill the holes for the brass inserts. It took me very long, for just an acceptable result. This would mean of course that the lasercut drawing has to be revised. I think with aluminum profiles and just nuts and bolts you'd get a better result.
To diffuse the light better, I've glued tracing paper on the inside of the perforations. This gives the light a nice glow to it.
Step 8: Don't Stop Here
The project centers around an ESP32, I've barely used it. My bedroom lights can currently be remote controlled using blynk. Controlling them with the clock is only a small step further. Perhaps you want some extra displays that show you the temperature around your house? Or some local sensors (there's still spare I2C connections on that multiplexer!). Maybe set the time/alarm via an app and bluetooth?
Let me know what you changed, what you would change, what I should change...
Participated in the