This project uses a NULA Mini ESP32-C6 and a 0.96" 128x64 SSD1306 OLED display to build a simple DIY smart watch–style interface.
The device provides four main screens:
- HOME – Animated wallpapers (MSB-first 1bpp bitmaps, 128×64)
- CLOCK – NTP-synced digital clock with date and subtle pixel drift to reduce OLED burn-in
- WEATHER – Current temperature and a simple icon using data from Open-Meteo
- TIMER – Simple MM:SS countdown-style timer with start/pause/reset logic
Interaction is done using a single button:
- Short press → switch screen:
HOME → CLOCK → WEATHER → TIMER → HOME → ... - Long press → context action:
- HOME: switch to next wallpaper
- CLOCK: force NTP time sync
- WEATHER: force weather refresh
- TIMER: start / pause / reset (depending on current state)
This makes for a nice demo of Wi-Fi, NTP, HTTP API, and OLED UI on the NULA Mini ESP32-C6.
- NULA Mini ESP32-C6
- 0.96" SSD1306 OLED Display (I²C, Qwiic/easyC)
- Momentary push button (for UI input)
- USB-C cable (for power & programming)
- Optional:
- Qwiic/easyC cable for the OLED
- 3D-printed watch enclosure / strap
- Small LiPo battery + charger (if you want it wearable and not just on USB)
- Arduino IDE
- ESP32 core for Arduino (with ESP32-C6 support) by Espressif Systems
- Libraries:
- Built-in ESP32 libraries:
WiFi.htime.hHTTPClient.hWire.h
- Fonts:
FreeSansBold24pt7b(included with Adafruit GFX, used for big clock & timer)
No extra JSON or weather libraries are required — the project uses a lightweight manual JSON parser for Open-Meteo responses.
-
Install Arduino IDE if you haven’t already.
-
Install the ESP32 core via Boards Manager (search for ESP32 by Espressif Systems and install).
-
Install the required libraries via Library Manager:
Adafruit SSD1306Adafruit GFX Library
-
Clone or download this repository and extract it.
-
Open the sketch:
diy-smart-watch/diy-smart-watch.ino -
Under Tools → Board, select the appropriate ESP32-C6 board profile (e.g. NULA Mini ESP32-C6 or closest equivalent from Soldered’s board package).
-
Select the correct Port for your board.
-
Open the sketch and adjust the Wi-Fi configuration at the top:
const char* WIFI_SSID = "YourWiFiName"; const char* WIFI_PASS = "YourWiFiPassword";
Optionally adjust:
TZ_INFO– timezone stringWX_LAT/WX_LON– latitude/longitude for your locationBUTTON_PIN– if you wire the button to a different GPIO
-
Wire the components as in the Wiring section below.
-
Click Upload and open Serial Monitor at
115200 baudto see debug logs (Wi-Fi, NTP, weather fetch status).
Once Wi-Fi is configured and the device is powered, it will automatically:
- Connect to your Wi-Fi
- Sync time from NTP
- Fetch weather data from Open-Meteo
- Show the CLOCK screen by default
- The OLED is initialized and cleared.
- The board attempts to connect to the configured Wi-Fi network.
- If Wi-Fi connects:
- It syncs time from NTP servers (
pool.ntp.org,time.google.com,hr.pool.ntp.org). - It fetches current weather data for the configured location (default: Osijek, Croatia).
- It syncs time from NTP servers (
- The default screen is CLOCK.
With the button wired and BUTTON_PIN set (default: GPIO 5):
-
Short press:
- Cycles through screens in this order:
HOME → CLOCK → WEATHER → TIMER → HOME → ...
- Cycles through screens in this order:
-
Long press:
- On HOME: change to the next wallpaper
- On CLOCK: trigger an immediate NTP resync
- On WEATHER: trigger an immediate weather refresh (ignoring the normal refresh interval)
- On TIMER:
- If timer is stopped at
00:00: start counting - If timer is running: pause and hold the current value
- If paused at a non-zero value: reset to
00:00
- If timer is stopped at
- Shows one of several 128×64 MSB-first 1bpp bitmaps:
hypnocatscancloudsover
- A long press cycles through these wallpapers.
BITMAP_INVERTcan be set totrue/falsein the sketch if your display’s colors appear inverted.
- Displays the current time in HH:MM (24h format) using
FreeSansBold24pt7b. - Date is shown below in
DD.MM.YYYY. - The entire layout slowly drifts a few pixels in X and Y over time to reduce potential OLED burn-in.
- A small minimalist Wi-Fi icon shows connection status and signal “bars”.
- If time is not yet synced, it shows "Syncing..." instead of the time.
- Uses the Open-Meteo API to fetch:
- Current temperature (°C)
- Weather code
- A small icon is drawn representing:
- Clear sky, partly cloudy, overcast, rain, snow, or thunderstorm (simplified).
- The temperature is shown as a large integer value (e.g.,
23) with a stable°Clabel next to it. - If Wi-Fi is not available, it shows "No WiFi".
- If a request fails, it shows "Error / fetching...".
- Weather is refreshed:
- Automatically every
WX_REFRESH_MINminutes, and - Immediately when long-pressing the button on the WEATHER screen.
- Automatically every
- Shows a large MM:SS display, up to 99:59.
- Behavior:
- Long press (when at
00:00): start timer - Long press (while running): pause timer
- Long press (paused at non-zero): reset to
00:00
- Long press (when at
- A hint line at the bottom shows the current action:
Long press = STARTLong press = PAUSELong press = RESET
If you use the Qwiic/easyC connector, the OLED connects with a single cable (power + I²C).
You only need to wire an external button to one GPIO.
| Component | Pin on NULA Mini ESP32-C6 | Notes |
|---|---|---|
| OLED VCC | 3V3 / Qwiic VCC | Power |
| OLED GND | GND / Qwiic GND | Common ground |
| OLED SCL | Qwiic SCL (default I²C) | I²C clock |
| OLED SDA | Qwiic SDA (default I²C) | I²C data |
| Button one side | GPIO 5 (default BUTTON_PIN) |
UI input (short/long press) |
| Button other side | GND | Used with INPUT_PULLUP |
| USB-C | USB port on NULA Mini | Power & programming |
If you change the button pin, update:
#define BUTTON_PIN <your-pin-number>in the sketch.
At the top of diy-smart-watch.ino, you can tweak:
// Wi-Fi
const char* WIFI_SSID = "YourWiFiName";
const char* WIFI_PASS = "YourWiFiPassword";
// Timezone (Osijek / Central Europe by default)
const char* TZ_INFO = "CET-1CEST,M3.5.0,M10.5.0/3";
// OLED size + address
#define OLED_WIDTH 128
#define OLED_HEIGHT 64
#define OLED_ADDR 0x3C
// Button
#define BUTTON_PIN 5
// Weather (default: Osijek, Croatia)
#define WX_LAT 45.5549
#define WX_LON 18.6955
#define WX_REFRESH_MIN 30Change latitude/longitude and timezone if you want your watch to show local time and local weather.
At Soldered, we design and manufacture a wide selection of electronic products to help you turn your ideas into acts and bring you one step closer to your final project. Our products are intended for makers and crafted in-house by our experienced team in Osijek, Croatia. We believe that sharing is a crucial element for improvement and innovation, and we work hard to stay connected with all our makers regardless of their skill or experience level. Therefore, all our products are open-source. Finally, we always have your back. If you face any problem concerning either your shopping experience or your electronics project, our team will help you deal with it, offering efficient customer service and cost-free technical support anytime. Some of those might be useful for you:
Soldered invests vast amounts of time into hardware & software for these products, which are all open-source. Please support future development by buying one of our products.
This repository is under the MIT license. Long story short: use these open-source files for any purpose you want, as long as you apply the same open-source licence to it and disclose the original source.
No warranty — all designs in this repository are distributed in the hope that they will be useful, but they are provided “AS IS” without warranty of any kind.
The entire quality and performance of what you do with the contents of this repository are your responsibility.
And thank you from your fellow makers at Soldered Electronics.
