Cloc 2.0: The Alarm Clock You've Always Wanted

By Yves Bourdon (France)

Clocks are probably one of the most popular topics in DIY electronics, together with radio receivers. I wouldn't be surprised if every reader of this article has built a clock at least once. I have built a lot of clocks in my life, and many had alarm functions. Because of this, I know what I want from an alarm clock. As my ideal alarm clock is not available commercially, I built it myself. Cloc 2.0, presented here, is the result.

I built my first clock in 1971 using Nixie tubes from an old IBM computer display that I had been given. The board used an impressive number of components, and the precision was about ten seconds per day. In the years that followed, I designed and built many clocks, including the most famous ones from Elektor.

My Nixie clock was also used as an alarm clock, and it's a feature I developed a lot over the years by simplifying the human-machine interface as much as possible. My last alarm clock was based on a PIC32 processor with two displays (Figure 1). It had an ESP8266 module to set the time automatically from an online time server over NTP. The PIC32 pressed buttons on a real remote control to turn on my favorite radio station or play music. A rotary encoder and two push-buttons allowed setting the alarm clock. This alarm clock was the basis of the project described below: Cloc 2.0.

Figure 1: Cloc 1.0, the predecessor of Cloc 2.0. Based on a PIC32, it used a real remote control as IR output.

Beautiful and Easy to Reproduce

I wanted to make an alarm clock that was easy to build, did not use SMD parts, and fit as easily as possible into a standard commercially available enclosure. I also wanted to keep the retro touch of the 7-segment displays, whose variable brightness makes the alarm clock very readable at night without being too disturbing when you like to sleep in the dark.

The Web Interface

Cloc connects to a Wi-Fi network, so it can access a time-server somewhere on the planet. It can connect using DHCP or with a fixed IP address. Once it is connected, you can access its web server to know the time, set the alarms and adjust the clock's parameters. The optimized graphical HTML interface works on most standard browsers and handheld devices. The interface consists of three panels: Main, Alarm and Settings.

Main Panel

The main panel (Figure 2) displays the current time and date, and the start and end time of the upcoming alarm. It also shows the SSID of the Wi-Fi network it is connected to with the signal strength RSSI. The color of the latter (green, orange, or red) depends on its value. The main panel is refreshed approximately every second.

Figure 2: The Main panel shows besides the current time and date an overview of the most important settings.

Alarm Panel

The alarm panel (Figure 3) is used to set the alarm times for each day of the week. Unchecking a weekday disables the alarm for that day. It is also possible to disable all alarms with a single click.

The duration of the alarm is configurable too. At the start of an alarm, the Media ON command is sent using the infrared LED; at the end of the alarm, the IR Media OFF command is sent. Additionally, the alarm can sound the buzzer (to be enabled in the Settings panel).

Each time an alarm parameter is changed, a short beep is emitted. If the value changed with respect to its previous value, it is saved in the EEPROM.

Figure 3: The Alarm panel lets you set the alarm time for every day of the week.

Settings Panel

The following parameters can be adjusted. See Figure 4.

Figure 4: All the user-configurable parameters are found in the Settings panel.

Push Buttons

Cloc has two push-buttons for interacting with the user: S1 (Disable) and S2 (Stop). In normal operation mode, pressing S1 enables or disables the alarm (the lower display switches on or off). You can also (de)activate the alarm through the web interface. If S1 is pressed down when switching on Cloc's power, the default values as defined in the program (and that you must adapt to your own needs before programming the clock!), are restored. This is the thing to do when you switch on the clock for the very first time.

Circuit Description

The schematic of Cloc 2.0 is shown in Figure 5. Almost two thirds of it are taken up by the two 7-segment displays and its driver, IC1. To drive the eight digits, four per display (time & alarm), I used the MAX7219. It has a 2-wire SPI bus (DIN is not used) and it is easy to program thanks to open-source libraries. Resistor R1 allows setting the maximum brightness of the display (the higher its value, the dimmer the displays). Note that high-brightness 7-segment digits are really bright, and maybe too bright for an alarm clock.

The ESP32 module chosen for Cloc is the ESP32-PICO-KIT, which offers many I/O ports, and which has the perfect dimensions for this project. Capacitor C7 is only needed when the ESP32 module stays in reset mode after power-up. Some (older?) ESP32 modules appear to suffer from this problem, but I have never noticed it. If you decide to mount it, mount it lying down and pointing away from R6 and R7.

The alarm buzzer BUZ1 (without integrated oscillator) is driven by a PWM signal on port IO27 of the ESP32.

The ESP32's ports IO34 and IO35 are wired to the push-buttons S1 and S2, and connector K1. In a typical build, S1 and S2 would be mounted on top of the clock instead of on the PCB, which is why K1 is there. Pull-up resistors of 10 k are used (R6 & R7) even though the ESP32 has built-in pull-ups. But as they have values of several hundreds of kilo-ohms, relying only on them makes a button wired this way a bit more sensitive to noise.

Three (debug) LEDs (LED1, LED2 & LED3) indicate the Wi-Fi network connection status (blue), web server interface connection (orange) and IR in- and outbound traffic (red).

Figure 5: The ESP32-PICO-KIT provides Internet connectivity and the time, while the MAX7219 controls eight 7-segment digits organized in two rows. Note the IR interface around IC2 (input) and LED4 (output).

IR Interface

C5 and C6 decouple infrared receiver IC2 to recover an IR signal as clean as possible. The infrared TX LED (LED4) is controlled by transistor T1. The current through it is limited by R5 to about 150 mA. The IR output is powerful enough to control any equipment in its vicinity in the same way as the equipment's original remote control would do.

Power Supply

The external 5 VDC power supply must be able to deliver at least 500 mA. Diode D1 protects the circuit against a polarity inversion. Two electrolytic capacitors (C1 & C4) provide buffering for current peaks. Small 100 nF capacitors in parallel (C2 & C3) are intended for attenuating higher frequency noise.

Component List

Resistors

Capacitors

Semiconductors

Miscellaneous

Extensions

Connector K2 allows extending the clock with, for instance, a real-time clock module (see below). Three I/O ports are available for this: IO4, IO26 and IO32.

Real-Time Clock (RTC) Option

A DS3231 RTC module can be connected to extension bus K2. The RTC takes over if the NTP server is inaccessible for some reason (e.g., Wi-Fi is down, or a problem at the internet provider's end). The RTC module is detected and configured automatically by the software and updated once a day (at 12:00). The DS3231 is a very capable chip featuring crystal drift compensation thanks to an integrated temperature sensor.

The DS3231 RTC module sports an I²C interface and connecting it to K2 requires only four wires: GND, 3.3 V, SDA and SCL. If an RTC module is detected, port IO26 becomes the SDA signal while port IO32 takes care of the SCL signal of the I²C bus.

Figure 6: If the (optional) DS3231 real-time clock (RTC) module is used with a non-rechargeable CR2032 button cell, remove the resistor or the diode (or both) in the red circle to avoid damaging the battery.

Danger!

Be careful, these RTC modules can be dangerous! Indeed, the module features a battery charging circuit, but it often comes with a non-rechargeable CR2032 battery installed that might eventually explode. There are two solutions to this problem. The easy but more expensive one is to replace the battery by a rechargeable LIR2032 battery. The second solution is to remove the diode or the 200 Ω resistor (or both) near the SCL pin of the 4-pin connector, see Figure 6.

Mechanical Details

A good enclosure for Cloc is the 1591CTDR from Hammond, which measures 120 mm by 63 mm by 38 mm. It is translucent (IR) red and perfect for the time-of-day and alarm time 7-segment displays (red and/ or orange). The transmission and reception of IR signals also benefit from such an optical filter. Note that light with little or no red content (like the blue LED) is hardly visible due to this filtering.

And while we're on the subject of LEDs, the ESP32-PICO-KIT has a (way too) bright red power LED that you probably want to hide or remove.

The printed circuit board (PCB) was designed with this enclosure in mind. The KiCad6 project can be downloaded from [1]. The board, mounted on four 16 mm studs, fits perfectly inside the enclosure, as shown in Figure 7. Only four 3.2 mm holes need to be drilled in the

Figure 7: The assembled board fits nicely inside the enclosure. Note that you can also mount it on the cover instead to hide the enclosure's screws. The power supply connector can be mounted on either side of the board.

bottom to fix the board, one 8 mm hole is needed on the side for the power connector, and two 12 mm holes on top allow inserting two nice push buttons.

The optional RTC module can be connected under the main PCB to K2 with its component side up using the 4-pin non-populated header (you may want to remove the 6-pin angled header to prevent short circuits). You can also stick it to the main PCB with double-sided adhesive tape (as I did).

The Software Development Environment

I used the Arduino IDE to develop the software for Cloc 2.0 with the ESP32 boards package added to it. To avoid compilation or memory management errors, you must select the board ESP32 PICO-D4 with a 240 MHz CPU frequency. For the Partition Scheme choose Default (i.e., 4 MB with SPIFFS). If you select the right serial port, then compiling and uploading the program should go smoothly!

The following external libraries must be installed in the IDE before compiling the program. I have indicated in the source code where to get them. Most can also be obtained using the IDE's Library Manager.

Important: LedControl.h must be modified. Line 30 (#include <avr/pgmspace.h>) must be commented out. Also see the comment in the source code.

The download [1] contains a folder named libraries which includes all the libraries used, including the pre-modified LedControl.h. Copy these libraries into libraries subfolder of the Arduino sketchbook folder (you can see where it is by going to the IDE's Preferences window).

Refer to [2] to learn how to add the ESP32 Sketch Data Upload option to the IDE. You'll need it to load the clock's web interface into the ESP32 module's data memory. Don't forget to upload this data; otherwise the web server will not work.

Over-the-Air (OTA)

To remotely update the firmware of the alarm clock, point a browser to IP_of_cloc/update where IP_of_cloc represents the IP address of the clock. You can now pick an executable on your computer and upload it to the clock. A detailed explanation of the OTA interface is available at [3].

Program Internals

The program is quite well documented (unfortunately often in French), and after reading the following, you should find your way around easily. You might want to monitor the serial port of the ESP32 because a lot of debug information is sent on it.

After including the libraries, the default values are defined that are used either on the first boot, by holding down the alarm disable key (S1), or from the Settings page after clicking the Defaults button. The order of the constants follows the order of the parameters in the Settings panel (lines 40 to 65 of Alarm_Clock.ino). Check in particular the fixed IP address and gateway, as well as Wi-Fi credentials. For the Alarm panel (lines 67 to 84) things are organized the same way.

At power up, the function setup is executed first. It is easy to follow the initialization order of the Cloc hardware. The function initRTC checks if a DS3231 RTC module is connected. If button S1 is being held down at this time, the default values will be loaded.

If this is the clock's first boot or if the button Stop (S2) is pressed during power up, the clock will enter Access Point (AP) mode. In this case, you can connect with a browser to its web interface at 192.168.4.1, as indicated by the clock.

After retrieving the IP address (DHCP or fixed) and connecting to the Wi-Fi network, we look for the NTP time. If it is found and an RTC is present, they will be synchronized. The clock's IP address is shown briefly before switching to time display. If the display starts flashing 'HH:HH' on the time display and 'AA:AA' on the alarm display, the NTP server could not be reached, and you must reboot the device (if no RTC is present; otherwise it displays the RTC Time).

Initialization ends by starting the web server and the AsyncOTA service, which allows doing a remote update of the firmware and SPIFFS.

The function loop executes the rest of the program in an endless loop. If the RTC is present (flagRTC=1), it reads the RTC time. Without RTC, it tries the NTP time (NTPflag=1). Once the clock is connected, the program reads the RTC time, while strTime contains the NTP time as "hh:mm:ss" if it is valid or as '0' otherwise.

Then the state of the buttons is checked (checkButtons) and it checks if the clock must beep and if an IR code was received. Since the server is asynchronous, we must use flags to signal parameter changes and alarm triggers to the main program.

The screen is refreshed every second (dispTime) and the alarms are checked (checkAlarm). Also, the program checks if it is in the high-brightness period or not (checkBrightness) and if it must synchronize the RTC with the NTP time (checkSyncRTC). This happens once a day at 12:00 (syncRTC=12*60). The function checkTimer checks if an alarm must be activated. For this, the time-of-day and the alarm time are converted to minutes (computeMinutes) before comparing them (testRange).

As mentioned before, the server is asynchronous. Each time the Settings or Alarm panel is refreshed, the data to be displayed (ParametresProcessor and TimerProcessor) is returned. For this, the %value% tags contained in the HTML page must be replaced by the real values.

For the main panel, it's a bit different because we must display almost in real time the time of day, the date, and the alarm start and stop times. A function written in JavaScript queries approx. every second the main program to retrieve the values to display (onDataUpdate). At each query, LED2 flashes briefly to indicate that the server is being accessed (flashRqstBeacon). To check that the page is indeed displaying the values in real time, press S1 (Alarm Disable). The alarm time is displayed or turned off simultaneously on both the 7-segment display and on the HTML page.

Specifications

Regarding the IRremote Library

The IRremote library works perfectly fine, but requires some integration rules. Do not move the initialization sequences unless you know what you are doing.

To wake up to music instead of a beep, I use a Bose radio. Therefore, I limited the reception and decoding to Bose remote controls (see line 125 of Alarm_Clock.ino). You can remove this line to decode other remotes. However, I recommend limiting infrared reception to the brand of your radio or hi-fi system. Refer to [4] for possible options.

Similarly, IR transmission is limited to the Bose format. Therefore, it is quite likely that you must adapt the code to the brand of the Hi-Fi equipment you use. Replace the line IrSender.sendBoseWave in the functions startMedia and stopMedia in Alarm_Clock.ino by a function that corresponds to your brand (again, refer to [4]).

To find out which IR codes to use for your (audio) system, connect the USB port of the ESP32 module to a computer running a serial monitor, for instance the Serial Monitor built in the Arduino IDE. Point your remote control to the clock's IR receiver and press a key to display the corresponding code in hexadecimal on the computer. Enter the codes in hexadecimal in the Media ON and Media OFF fields of the Settings panel.

IR activity is indicated by LED3 flashing briefly. As a result, this LED also flashes when an alarm is active.

A DIY Solution

I've been using this new version of Cloc 2.0 for several months now, and I've never overslept due to it malfunctioning. The ability to set alarm times for each day of the week is very convenient.

I highly recommend adding the RTC option because if the NTP server does not respond (for instance because your modem got offline for some reason), the alarm clock will lose time at the next NTP time resynchronization moment. You will then have to stop and restart the alarm clock when the NTP time is available again. For even more reliability, I built a small NTP server which receives the time from a GPS [5]. So, even if the Internet connection is cut, my alarm clock can set itself automatically.

I hope that many of you will make this clock. Please don't hesitate to contact me on my private email (yb.electronique@orange.fr) if you encounter any difficulties or if you make any improvements to my favorite alarm clock! K

Questions or Comments?

Do you have technical questions or comments about this article? Email the author at yb.electronique@orange.fr or contact Elektor at editor@elektor.com.

Related Products

Web Links

PDF preview unavailable. Download the PDF instead.

G7CPaAoZHrq2zoIMGOibrTKSA9EEV2Wk Adobe InDesign 18.2 (Macintosh) Adobe PDF Library 17.0

Related Documents

Preview Elektor ESP32 Energy Meter FAQ: Programming, Connectivity, and Usage Guide
Comprehensive Frequently Asked Questions (FAQ) for the Elektor ESP32 Energy Meter. Get answers on initial programming, adding ports, display compatibility, Home Assistant integration, data logging, power supply, accuracy, and troubleshooting.
Preview Raspberry Pi Pico Experimenting Kit: Programming and Projects Guide
A comprehensive guide to the Raspberry Pi Pico Experimenting Kit, covering hardware, programming environments, and 42 diverse projects using MicroPython. Learn to master the RP2040 microcontroller with hands-on examples for electronics enthusiasts.
Preview Elektor Circular Christmas Tree Kit Construction Manual
Detailed construction manual for the Elektor Circular Christmas Tree Kit, guiding users through assembly, soldering, and control of the LED Christmas tree. Includes bill of materials, specifications, and optional module integration.
Preview Arduino Uno Experimenting Kit: Programming and Projects Guide
Explore the Arduino Uno Experimenting Kit with this comprehensive guide covering programming fundamentals and practical projects. Learn hardware and software skills through over 60 engaging projects involving LEDs, displays, sensors, motors, and more.
Preview ESP32 Robot Car Control: A Comprehensive Guide
This guide explores building and controlling a robot car using the ESP32 microcontroller. It covers open-source code with Arduino IDE and PlatformIO, autonomous driving features (GPS, accelerometer, gyroscope), and PS3 controller integration, authored by Udo Brandes and published by Elektor.
Preview Reference Manual for 4-Bit IN-12 Nixie Clock Production
A comprehensive guide detailing the production process, component selection, circuit diagrams, and assembly instructions for a 4-bit IN-12 Nixie clock kit.
Preview Raspberry Pi Pico W: Program, Build, and Master 60+ Projects
A comprehensive guide to programming, building, and mastering over 60 projects using the Raspberry Pi Pico W and its RP2040 microcontroller. Covers hardware, programming with MicroPython, and various applications including LED projects, displays, sensors, PWM, Bluetooth, Wi-Fi, and RFID.
Preview Elektor Quasi Analog Clockwork Kit Construction Manual
The Elektor Quasi Analog Clockwork Kit Construction Manual provides comprehensive instructions for assembling a unique LED clock. This guide covers tools, component placement, soldering techniques, and circuit specifications, making it ideal for electronics enthusiasts and DIY builders.