Introduction: On-demand Sync Clock (OSC)
On-Demand Sync Clock (OSC), a DIY smart table clock that calibrates itself with one touch of a button.
The distinctive feature of this clock is its effortless adjustment: Simply press the push-button while an open network (Wi-Fi without password) is available, for instance, a smartphone hotspot.
Timekeeping is handled by a DS3231SN Real-Time Clock (RTC) module, which features a temperature-compensated crystal oscillator. According to the datasheet, its accuracy is within ±2 ppm (approximately ±1 minute per year).
When the button is pressed, the clock synchronizes with NTP servers. If at least 14 days have passed since the previous sync, it also calculates the drift and automatically adjusts the DS3231SN’s internal aging factor to improve long-term accuracy.
This automatic calibration is particularly handy, as many DS3231 chips on the market (in all versions, SN included) are clones with lower precision.
I developed this clock as a gift for my mum and mother-in-law, who don’t have Wi-Fi at home. I can now update or recalibrate their clocks simply by pressing the button during a visit.
In short, the On-demand Sync Clock (OSC) is a DIY smart table clock that synchronizes with NTP servers on-demand via a button press, calibrates its RTC drift automatically, and runs for months on a battery.
This makes the OSC a practical option for any location without permanent internet access.
Key Features:
- On-demand synchronization:
- If the push-button is pressed within 14 days of the last sync, the clock updates its time from NTP servers.
- If it’s pressed after 14 days, the clock also computes the DS3231SN drift and fine-tunes the aging factor to minimize future deviation.
- The updated value is stored both in the DS3231SN’s RAM and in the ESP32’s NVS (Non-Volatile Storage).
- The push-button is recessed so it cannot be pressed unintentionally.
- DS3231SN RTC module:
- The genuine DS3231SN typically drifts less than ±2 ppm under ideal conditions, though inexpensive modules often use clone chips.
- Calibration is simple and fully automated.
- A CR2032 coin cell powers the RTC during the ESP32-S3 sleep, and can last several years.
- The module is powered from the main LiPo battery for a brief moment each minute to read date/time over I²C.
- It embeds thermometer, from which the temperature is retrieved every 30 minutes, and displayed on the e-paper display. The specified accuracy is <±3°C, so not really great, yet it can be adjusted (shift) via the config.py file.
- To protect the coin cell, its charging path must be disabled (instructions below).
- Smart Time Management:
- Automatically handles time zones and Daylight Saving Time (DST) using configurable regional rules (EU, US, Australia, etc.).
- Regional settings:
- 12-hour / 24-hour time format.
- DMY / MDY / YMD date format.
- Day of the week language (EN, ES, FR, DE, IT, PT, RU, ZH, HI, AR)
- High-Contrast 4.2" E-Paper Display:
- Features gigantic 110-point digits for excellent readability.
- It uses partial refreshes for efficiency and a full refresh every hour to prevent ghosting.
- The display updates immediately after the minute changes (when seconds are between 0 and 5).
- The display also shows useful status information:
- Battery level.
- Room temperature (°C/°F) indication, via the DS3231SN termometer.
- Status of the last WiFi connection
- Status of the last NTP synchronization
- Time of the last NTP sync
- Aging factor used (default is zero)
- Moderate Power Consumption (ca 1.15 mA average):
- Optimized light-sleep cycles with ultra-short wake-ups (ca 0.8 s active per minute).
- A fully charged LiPo battery lasts several months, roughly 3 months with 2500 mAh, or 2.5 months with 2200 mAh.
- WiFi Connectivity:
- The clock requires an open Wi-Fi network the first time it powers on or whenever you want to adjust the time / recalibrate the DS3231SN module.
- A smartphone hotspot works perfectly for this purpose.
- The Wi-Fi connection attempt is blocking only at the real first OSC start-up: In case of Wi-Fi or internet access failure, a warning is plot to the screen and the code stops, to solve the issue. Differently, the "on-demand" sync won't stop the code in case of Wi-Fi issues, and in that case proper warning will be plot to the screen.
How the OSC Calibration Works
When the push-button is pressed, the OSC captures a high-resolution timestamp (in milliseconds), based on in internal. This timestamp serves as a reference point to compensate for all subsequent code execution and communication delays, maximizing calibration accuracy.
The clock then gathers the current time from both the NTP server and the DS3231SN RTC. It calculates the elapsed period since the previous sync for both 'time sources', with all timings adjusted to account for network and I²C read latencies referenced against the initial timestamp.
If this period is longer than 14 days, the OSC calculates the DS3231SN's drift. The drift is the compensated difference in seconds between the two time sources, divided by the elapsed period (according to NTP), and then converted to ppm (parts-per-million).
The last stored aging factor value is then adjusted, via a simple addition, by this newly calculated ppm drift. Each unit of the aging factor accelerates or decelerates the DS3231SN by one ppm.
The new aging factor is sent via I²C to the DS3231SN chip (where it resides in RAM, retained by the coin cell) and is also saved to the ESP32-S3's non-volatile storage (NVS).
Visual Feedback: The e-paper display shows the timestamp of the latest NTP sync and whether calibration is enabled (i.e., if the 14-day threshold has been met). This clarifies whether pressing the button will result in a simple time sync or also trigger a new DS3231SN's calibration.
Why a 14-day minimum period? The DS3231SN's time resolution is 1 second (not milliseconds). A minimum period of 14 days is required to "dilute" this ±1 second resolution error down to a calibration granularity of approximately ±0.83 ppm (about ±26 seconds per year). Of course, if the calibration will be made after one month, the resolution error will be smaller than ±0.4 ppm.
How OSC compares to the SLC
This On-Demand Sync Clock (OSC) is derived from my earlier Self-Learning Clock (SLC) project (https://www.instructables.com/Self-Learning-Clock-SLC/).
While the OSC incorporates more hardware (the DS3231SN RTC and a push-button), its operational concept is simpler: it does not require continuous Wi-Fi coverage to function.
The SLC remains an excellent and conceptually intriguing choice for locations where a permanent Wi-Fi connection is available, as it learns and applies daily drift correction automatically.
The OSC, however, is the practical solution for places without internet, relying only on brief, on-demand access for synchronization and calibration.
How the OSC Compares to typical DS3231 tutorials
If you've searched for "DS3231 clock projects" online, you'll find many tutorials that follow a similar pattern:
- Manual Setting: The RTC time is set once via a connected microcontroller.
- Passive Use: The DS3231 then runs independently, with its inherent drift (often significant with clone chips) slowly accumulating error over weeks or months.
- Periodic Manual Correction: The only way to correct this drift is to manually connect the device to a computer and reprogram the time.
Some advanced projects attempt an initial calibration, measuring drift over a period and applying a one-time correction to the aging register. While a step forward, this approach has a critical flaw: it's not sustainable. Component characteristics change with age and temperature, meaning a calibration performed today may be ineffective in six months or a year
The On-Demand Sync Clock offers a complete, sustainable solution:
Intelligent & Repeatable Calibration: It doesn't just calibrate once; Each on-demand sync (if enough time has passed) recalculates the drift and updates the aging offset, automatically compensating for long-term component aging.
- On-Demand Operation: Synchronization requires no computer and no reprogramming. A simple button press on an open Wi-Fi network (like a smartphone hotspot) triggers a full NTP sync and automatic drift recalibration.
- Long-Term Autonomy: This creates a self-maintaining system. Once set up, it sustainably maintains high accuracy for years with only minimal, user-friendly interaction, making it truly practical for gift or offline use.
In short, most projects use the DS3231 as a dumb clock. The OSC uses it as a smart, self-calibrating sensor in an adaptive, long-term timekeeping system.
About This Instructable
This guide provides all the key information to understand how the On-Demand Sync Clock (OSC) works and to build one yourself.
Whether your primary interest is exploring the concepts and functionality or replicating the physical device, the following steps are structured to guide you through both aspects.
Here’s what you’ll find in the steps ahead:
- The Concept & Setup: How the clock maintains accuracy, how to install its software, and how to configure it for your location.
- Critical Hardware Modifications: Essential tweaks to the e-paper display and DS3231SN module for safety and ultra-low power operation.
- The Physical Build: From preparing custom wiring and 3D printing the enclosure to the final assembly.
- Operation & Maintenance: How to interpret the display, manage autostart, charge the battery, and perform long-term calibration.
The project is broken down into the following steps:
- Supplies
- Step 1: Flash the ESP32-S3
- Step 2: Copy the OSC Files
- Step 3: Adjust the Settings
- Step 4: Prepare the Connections Board
- Step 5: Set the EPD to 3V3
- Step 6: Modify the DS3231SN Module
- Step 7: DS3231SN Battery
- Step 8: Prepare the Signals Wiring
- Step 9: First Test
- Step 10: 3D Print the Enclosure
- Step 11: Calibrate the ADC input (Optional)
- Step 12: Power wiring
- Step 13: Assembly of the OSC
- Step 14: Display Fields Explained
- Step 15: Enabling and Disabling Autostart
- Step 16: Battery Charging
- Step 17: Conclusions
- Step 18: Credits
- Step 19: Provide Feedback
Supplies
- 1 x LiLyGO TTGO T8-S3 (v1.2) [https://tinyurl.com/3tyy9sea].
- 1 x WaveShare 4.2 inches Pico epaper display [https://www.waveshare.com/wiki/Pico-ePaper-4.2]
- 1x Lithium Polymer Battery 3.7V 2200mAh, size LP 773575 (77mm x 35.5mm x 8.5mm) [https://tinyurl.com/2d88ehw4].
- Alternative Lithium Polymer Battery, easier to source: 3.7V 2500mAh, size LP 785060 (50.5mm x 62.5mm x 8.1mm) available from Adafruit [https://www.adafruit.com/product/328] and other shops.
- 1x 4056 breakout board with protection circuit [https://tinyurl.com/m7vyyh32]
- 1 x USB C DIY socket [https://tinyurl.com/264trdkj]
- 1 x DS3231SN module [https://tinyurl.com/2h32uywm]. Check with the seller for the "SN" version !
- 1 x CR2032 coin battery (3V lithium battery, diameter 20mm and thickness 3.2mm).
- 1 x Push Button diameter 7mm [https://tinyurl.com/56t2e9dn].
- 1x Connections board to drastically reduce wiring, otherwise wires :-). The board can be made out of a perfoboard, otherwise the Gerber files are provided to order it at a PCB manufacturer.
- 2.54mm female and male headers.
- some screws: See Assembly for the types.
Rationale for some of the chosen components:
- ESP32-S3 Development Board: I couldn’t get this project to run with the standard RAM of a regular ESP32-S3 board (about 320 KB of DRAM). The chosen LilyGO TTGO T8 board offers several useful features: 8 MB of PSRAM (essential for this project's memory needs), a battery connector, and an IPEX connector as an alternative to the built-in antenna.
- Battery Protection: Although the T8 board includes charging circuitry for a LiPo battery, it lacks an integrated protection system. For this reason, I added a dedicated TP4056 breakout board with an over-charge/discharge protection circuit.
- E-Paper Display: The Waveshare 4.2″ Pico e-paper display is large and provides excellent readability. It also offers flexibility: it can be connected either via wires or directly through its header for a cleaner assembly. Not to mention, I was able to purchase the Pico version at a very reasonable price (about 24 € in 2025).
Step 1: Flash the ESP32-S3
To flash the ESP32-S3 follow the steps listed below.
An images-based guide (HowTo_install_MicroPython_and_OSC_files) is also attached, in case any of these steps require further clarification.
- Install esptool in your PC.
- [instructions at https://micropython.org/download/ESP32_GENERIC_S3/ and https://docs.espressif.com/projects/esptool/en/latest/esp32/]
- Download the Micropython firmware.
- Download the v1.26.1 binary image for the ESP32_GENERIC_S3 from the same page [https://micropython.org/download/ESP32_GENERIC_S3/]
- Prepare the firmware file
- Move the downloaded .bin file to the directory/folder where you plan to run the esptool commands.
- Connect the board.
- Connect your LilyGO T8 board to your PC using the USB-C port.
- Identify the COM port.
- Check which COM port the device is assigned to (e.g., using Device Manager on Windows)
- Erase the flash memory.
- Open a terminal/command prompt in your esptool directory and run the following command, replacing <COM> with your actual port (e.g., COM6):
- Flash MicroPython.
- Run the following command to flash the operating system. (Note: This board has 8MB of PSRAM).
Step 2: Copy the OSC Files to the ESP32-S3
The source code for the On-Demand Sync Clock is hosted on GitHub:
https://github.com/AndreaFavero71/on_demand_sync_clock
The project consists of 27 files organized into 4 folders. You will need to copy all these files, including the lib folder, to the root directory of your ESP32-S3 microcontroller. All necessary libraries are already included in the repository.
A visual, image-based guide (HowTo_install_MicroPython_and_OSC_files) is attached in Step 1 for additional reference.
How to Upload Files Using Thonny
The easiest method to transfer the files is using the Thonny IDE.
- Prepare the Files:
- Download or clone the OSC project from the GitHub repository to a known folder on your PC.
- Connect and Configure Thonny:
- Connect your LilyGO T8 board to your PC via USB-C.
- Launch the Thonny IDE (https://thonny.org/).
- In the bottom-right corner, check if your board is automatically detected.
- If not, click that area and manually select the device/COM port associated with your ESP32-S3.
- Establish Connection:
- Press the Stop button on the Thonny toolbar to establish a connection with the board.
- Enable the File Manager:
- Go to View → Files to enable the dual-pane file manager.
- Upload the Project:
- In the top-left panel ("Your computer"), navigate to the local folder containing the downloaded OSC files.
- In the bottom-left panel ("MicroPython device"), you will see the files on your ESP32-S3. It should initially be nearly empty.
- Select all files and folders from the local source pane. You can click the first file, hold Shift, and click the last file to select everything.
- Right-click on one of the selected items and choose “Upload to /”.
- If prompted, confirm the overwriting of any existing files (like boot.py).
Once the upload is complete, all OSC files and the lib folder will be copied to the root of your T8 board's filesystem.
Step 3: Adjust the Settings
The OSC software includes three configuration files:
- config.py --> Main system and regional settings.
- secrets.json --> Private Wi-Fi credentials.
- dst_rules.json --> Daylight Saving Time rules for different regions.
The content of these files is largely self-explanatory. However, the following sections provide additional guidance on key settings.
Regional and Time Settings
The clock operates internally on UTC (Universal Time Coordinated), so you must tell it your local time conventions via config.py.
Key settings to configure include:
- Time Zone: Your UTC offset (e.g., 1 for UTC+1).
- Time Format: 12-hour or 24-hour display.
- Date Format: Choose from DMY, MDY, or YMD.
- Day of the Week Language: Choose from available languages (EN, ES, FR, DE, IT, PT, RU, ZH, HI, AR).
- Daylight Saving Time (DST): Whether DST is observed in your region.
- DST Rule: If DST is used, select the applicable rule from dst_rules.json. Pre-defined rules for the EU, US, and Australia are included. Adding new regional rules is straightforward.
- Temperature Unit: Celsius (°C) or Fahrenheit (°F).
- NTP Servers: A list of time servers for synchronization.
Note on NTP Servers:
The default servers in config.py are:
The second and third servers are specific to my location (National and Continental pools).
You can, and conveniently should, replace these with servers closer to you for better performance. The first server, 'pool.ntp.org', is an international pool and is typically the fastest one the OSC can reach via my home Wi-Fi.
WiFi settings:
The OSC only requires a Wi-Fi connection during its first-ever boot (blocking) and for any subsequent on-demand sync or calibration (non-blocking).
- Enter your network SSID(s) and password(s) in the secrets.json file.
- If you define multiple networks, the clock will attempt to connect to them in the order listed, falling back to the next if one fails.
- Optional but recommended: If no configured networks are available, the clock can scan for open (password-free) networks. If found, it will automatically connect to the one with the strongest signal. This feature can be enabled in config.py (OPEN_NETWORKS).
System settings:
The config.py file also contains several system-level switches for advanced control:
- QUICK_CHECK --> Enable/disables a fast system test.
- OPEN_NETWORKS --> Enables/disables the use of open Wi-Fi networks as a fallback
- BATTERY --> Enables/disables the battery operation logic.
- WDT_ENABLED --> Enables/disables the hardware Watchdog Timer for system recovery
Step 4: Prepare the Connections Board
The circuit that interconnects all components can be assembled on a prototyping board. However, for a cleaner and more reliable build, it is highly recommended to have the dedicated PCB manufactured.
If you choose to order the PCB, the Gerber files are available in the project repository:
Gerber Files:https://github.com/AndreaFavero71/on_demand_sync_clock/board
Important Note:
- This PCB is the same one used for the previous SLC (Self-Learning Clock) project. The revision V1 is only improved on the printed information related to the H5 connector and the board's name.
- For the OSC, it must be fully populated, including the 6-pin header (H5) for the DS3231Sn and push button.
Attachments
Step 5: Modify the E-Paper Display for 3.3V Operation (Lower Power)
The connection board supplies two power rails to the e-paper display (EPD): 3.3V and VSYS (the direct battery voltage, ~3.5V-4.2V).
The default configuration:
- The Waveshare EPD includes a 0 Ω resistor at position J2, bridging the pads labeled "VCC" and "VSYS". This selects VSYS as the default power source.
- When powered from VSYS, the display's internal level-shifter circuit remains active at all times, drawing approximately 1.5 mA continuously,even when the display is in deep sleep.
The Modification (Low-Power Configuration):
To achieve the project's target power consumption, you must reconfigure the display to run on the 3.3V rail instead.
- Desolder the 0 Ω resistor from its current position bridging "VCC" and "VSYS".
- Resolder it to bridge the "VCC" and "3V3" pads at J2. Alternatively, you can remove the resistor entirely and apply a small droplet of solder directly between these two pads.
The Result:
With this simple hardware modification, the EPD's deep-sleep current drops to less than 10 µA. Since the display is in deep sleep for more than 99.1% of the time, this change is essential for long battery life.
The schematic for the Waveshare 4.2" Pico e-Paper display is attached for reference.
Attachments
Step 6: Modify the DS3231SN Module
⚠️ Safety First – Disable the Charging Circuit
The charging circuitry on common DS3231SN modules is poorly designed and can pose a safety risk (overcharging, heating) with both rechargeable and non-rechargeable batteries. This is a well-documented issue in online forums.
Furthermore, in this clock, the module is only powered for a fraction of a second each minute, making effective charging impossible. Therefore, disabling the charging circuit is mandatory.
Refer to the attached module diagram from Proto Supplies (https://protosupplies.com/product/ds3231-rtc-with-eeprom-module/), who themselves remove these components when supplying it with a CR2032 coin cell.
Required Modifications:
- Disable the Battery Charging Path:
- Locate and desolder the small resistor (typically 100Ω) located next to the diode on the module. This resistor is part of the charging path to the battery holder.
- Optional but recommended: After removing the resistor, carefully flatten the solder pads with a soldering iron. This will ensure the module sits flush against the 3D-printed frame.
- Reduce Power Consumption:
- Desolder the Power LED from the module. This removes a small but unnecessary current drain.
These modifications prepare the module for safe, long-term operation with a CR2032 coin cell.
Step 7: DS3231SN RTC Battery
Battery Selection
Recommended to use a standard non-rechargeable CR2032 coin cell.
- It has a significantly larger capacity than rechargeable equivalents.
- According to the DS3231SN datasheet, a CR2032 should power the RTC for several years in this application.
Alternative (Use with Caution): If you prefer a rechargeable battery (e.g., an LIR2032), you must charge it externally from the OSC, by using a dedicated charger.
- As explained in Step 6, the module's onboard charging circuit must be disabled for safety and is ineffective due to the clock's very brief power cycles.
Replacing the Battery
Important Note: The DS3231SN loses its timekeeping function when the backup battery is removed.
Procedure:
- Remove the old battery from the module's holder.
- Insert the new CR2032 (observing correct polarity).
- Perform a full reboot of the clock:
- Slide the power switch on the LilyGO T8 board to OFF.
- Wait a moment, then slide it back to ON.
What happens during reboot: The clock will restart. The most recently calculated aging factor is preserved, as it is stored in the ESP32's non-volatile storage (NVS). Upon booting, this value is automatically copied back to the DS3231SN's RAM, restoring its calibrated accuracy.
Step 8: Prepare the Signals Wiring
Due to the limited space inside the clock, a custom, compact wiring harness is strongly recommended.
It ensures a clean assembly, prevents tangled wires, and makes the final fit into the enclosure much easier.
This harness connects the DS3231SN module and the push-button to the main connections_board using two small protoboard adapters with female headers.
For complete, step-by-step visual instructions, including all necessary wire lengths, soldering details, and assembly sequence—please follow the attached OCS_signals_wiring.pdf guide.
Attachments
Step 9: First Test
Before proceeding with the 3D printing and final assembly, it's important to verify that all software, core hardware and wirings are functioning correctly.
Testing Procedure:
- Power: Connect the LilyGO T8 board to your PC using the USB-C port. This will power the entire system.
- Connect: Open Thonny (or your preferred MicroPython IDE) and establish a connection to the board's serial port.
- Run: In the IDE, open and run the main application file: osc.py.
- Observe: After approximately 20 seconds, the e-paper display should update and show the OSC logo.
- If you have configured Wi-Fi credentials in secrets.json, the clock should continue its normal startup sequence and showing the date & time to the display.
- If Wi-Fi is not configured, the display will likely show a connection error message; This is normal and confirms the software is attempting the expected process.
Next Steps:
- A successful test confirms that the microcontroller, display, RTC, core firmware, and wiring are all working together; You can now proceed to 3D print the case and begin the final physical assembly.
Step 10: 3D Print the Parts
The clock enclosure consists of six parts:
- Back (choose version for your battery size)
- Clip (holds the LiPo battery in place)
- Panel (separates the LiPo battery compartment from the thermally sentivite components)
- Frame
- Button Support (btn_support)
- Front
3D printing orientation: The attached images show the suggested orientation for printing each part.
3D Printing Settings:
- Supports: Enable supports only for the "Frame". All other parts should be printed without supports.
- Infill: Use at least 30% infill for the Frame and Back parts, as they have screw pillars and require extra strength. Standard infill (15–25%) is fine for the remaining parts.
Battery Compatibility:
Two versions of the Back part are provided:
- Back_LP_773575 --> for batteries measuring 77mm x 35.5mm x 8.5mm.
- Back_LP_785060 --> for batteries measuring 50.5mm x 62.5mm x 8.1mm.
Choose and print the version that matches your LiPo battery.
Source Files:
If you wish to modify the design, STEP files are available in the project repository:
https://github.com/AndreaFavero71/on_demand_sync_clock/tree/main/3d_model/step
Step 11: Calibrate the ADC Input (Optional)
In this clock (like for the SLC one) the GPIO 4 is used as ADC (analog to digital converter) to read the battery voltage, and decide which battery level icon to display.
The ESP32's ADC inputs aren't very precise; Calibrating an ADC channel is not difficult and, if you haven't done before, I'd recommend you to do it as it turns out to be an interesting process.
To run this process you need a dc power supply that can be regolated in between 3.2V and 4.2V, and a trustable voltmeter.
The process looks like:
- Connect the LiLyGO T8-S3 board to the PC, via the USB-C cable.
- Opend the boot.py file, uncomment row 29 and keep commented all the other rows. Save the file.
- Power off the LiLyGO T8-S3 board: move the slider to the left (OFF).
- Detach the LiLyGO T8-S3 board from the PC.
- Detach the LiLyGO T8-S3 board from the Connections_board.
- Connect the LiLyGO T8-S3 power suply cable to its connector, on the back of the board (the connector is polarized, but is's very small, so make sure the red wire is pointing the + mark on the board).
- Connect the LiLyGO T8-S3 board to the Connections_board.
- Connect the power supply voltage regulator to the LiLyGO T8-S3 power suply cable, by making sure the voltage is in the range 3.2V to max 4.2V.
- The OSC display will show the battery voltage, just wait some little time for the internal averaging to deliver a stable value.
- Annotate on a spreadsheet the provided voltage (voltmeter) and the voltage interpreted by the ADC channel already filtered.
- Vary the supply voltage on 0.2V steps, until 4.2V.
- If you'd the interpreted voltage differs more than 0.05V you might want to proceed with a calibration:
- Detach the power supply.
- At rows 55 and 56 of utility/adc_battery_pin_calib.py there are two tweeking parameters:
- CORRECTION (default = 1.0) affects the slope; CORRETION should be > 1.0 if the interpreted voltage is smaller than the supply voltage.
- SHIFT (default = 0.0) shifts the full response.
- On the spread sheet calculate the needed CORRECTION to adjust the slope and the SHIFT to get the interpreted value overlapping the supplied voltage.
- To decide the CORRECTION and the SHIFT, make your own calculation on the spreadsheet.
- Adjust these parameters and save the file.
- Repeat steps from 5, until you're sattisfied with the result.
- If you have altered the CORRECTION and/or the SHIFT parameter, these new settings must be applied to the lib/battery_manager.py (rows 40 and 41) to be effectively used by the OSC in its normal operation.
Step 12: Power Wiring
Before starting the complete assembly, it's convenient to prepare the wiring for the power supply.
Once the USB-C socket is inserted and fixed to the clock enclosure, the wiring can be completed by soldering the last two wires to it.
For complete, step-by-step visual instructions, including all necessary wire lengths, soldering details, and assembly sequence, please follow the attached Power_wiring.pdf guide.
Attachments
Step 13: Assembly of the OSC
Please follow the attached pictures, which are arranged in the suggested assembly sequence.
Screw list:
Use the following screws to secure the components. In some location an alternative screw's lengths works too.
- 1× M3×8 mm (or M3×10 mm) → Clip holding the battery and TP4056 breakout board
- 3× M3×8 mm (or M3×10 mm) → Panel and Back cover
- 1× M3x8 mm (or M3×10 mm) → Btn_ support and Frame
- 4× M2.5×10 mm → Frame to EPD (e-paper display)
- 2× M2.5×8 mm (or M2.5×10 mm) → DS3231SN module and Frame
- 4× M3×18 mm → Back cover to Frame
Assembly notes and tips:
- Power Wiring Safety: When preparing the LiPo battery wiring, cut and strip one wire at a time to prevent accidental short circuits.
- Front Panel: The Front piece attaches to the Frame via snap hooks. It can be installed as the final step after all internal components are secured.
- Tight Screw Holes: If a screw hole feels too tight or produces excessive friction:
- Clean the hole with a drill bit of the same diameter (by hand, not powered).
- Alternatively, rub the screw threads against a wax candle; the wax will act as a lubricant and reduce friction during assembly.
Step 14: Display Fields Explained
Step 15: Enabling and Disabling Autostart
Edit the file boot.py (for example, using Thonny) and uncomment the commands from lines 9 to 17.
Save the file.
From now on, when the board boots, the OSC will start automatically.
To reboot the board, simply switch it OFF and then ON using the small slider switch.
Important Notes – Stopping the Code After Auto-Start
When the OSC is running, it spends over 99% of the time in light-sleep mode.
While the ESP32-S3 microcontroller is in light sleep, it cannot handle serial communication, so your PC will not recognize it as a connected USB device.
If you need to modify a setting or re-edit the code, follow these steps:
- Open Thonny on your PC.
- Connect the T8 board to your PC.
- Press and release the small push button located behind the slider switch — this is the one soldered on the back side of the board, facing upward.
- Press the STOP button in Thonny.
- In the bottom-right corner, select the board/COM port corresponding to your ESP32.
- Left-click to the Shell area of Thonny.
- Press Ctrl + C to interrupt the SLC code running in the background.
- Double-click boot.py in the lower-left file list.
- Select all the code with Ctrl + A.
- Comment out all lines with Alt + 3.
- Save the file with Ctrl + S.
- Press the STOP button again.
- From step 3 onward, you have about 20 seconds to prevent the code from restarting automatically.
After commenting out boot.py, the OSC will no longer start automatically, allowing you to modify or upload new files.
Step 16: Battery Charging
Battery charging:
To charge the battery, connect a 5V phone charger (with a USB-C cable) to the USB-C socket.
The TP4056 module lights a red LED while the battery is charging, and it turns blue when the battery is fully charged (see attached picture). The LED is visible from the back side of the SLC.
A full charge takes about 2.5 hours, as the TP4056 normally limits the charging current to 1 A.
The battery level icon does not update quickly enough to reflect the actual charging progress: When the blue LED turns on, the battery icon may still show around 80%. It is recommended to stop charging at that point. The battery icon will reach 100% within about an hour.
Warning:
Although the suggested battery and the suggested TP4056 module include protection circuits, charging LiPo batteries is inherently dangerous. Do not leave the charger connected and unattended.
If you build and use this clock based on this information, you accept that it is at your own risk.
Weird display?
Occasionally, when connecting the charger to the clock, the display may turn “weird”, showing a salt-and-pepper pattern over the previous time. If this happens:
- The display may appear unresponsive, although the clock keeps running.
- Do not worry, the display will automatically recover within about one hour, thanks to the hourly full refresh of the e-paper display.
- The issue resolves itself whether the charger is kept connected until the battery is fully charged or disconnected while the display issue is still present.
Attached are a couple of images showing this temporary display effect and its self-correction.
Step 17: Conclusions
I made this clock as a gift for my mum and mother-in-law, who don’t have Wi-Fi at home.
The idea was to make a reliable clock that adjusts automatically for daylight saving time and stays accurate between my visits, when I can sync it by just pressing a button.
It’s a simple design that aims to balance low power use, long-term accuracy, and easy maintenance, a practical clock that quietly keeps the right time.
I'm pretty sattisfied with the overal result.
Step 18: Credits
Credits to:
- Hackaday One Hertz Contest → [https://hackaday.io/contest/203248-one-hertz-challenge] for hosting so many inspiring projects. I particularly liked the one based on a tuning fork:[https://hackaday.io/project/202971-a-more-precise-tuning-fork-clock].
- Instructables Clock contest [https://www.instructables.com/contest/clocks25] for organizing and collecting so many interesting projects.
- Volodymyr Shymanskyy → for his excellent lightweight asynchronous DNS client for MicroPython:[https://github.com/vshymanskyy/aiodns/tree/main]
- Mike Causer, Willem Peterse, and Conrad Storz for their work on the DS3231 driver.
- Kevin, for the suggested improvements, like the 12-hour format time
- All makers who provided feeback to my first clock project (SLC), triggering some thinking for this clock.
Step 19: Provide Feedback
If you've enjoyed the project and/or you've suggestions, please feedback













