A compact smart clock built on the ESP32-C6 Super Mini — shows the time, weather, Google Calendar events, and lets you set an alarm. Everything configurable from a browser, no app needed.
📦 3D Model on MakerWorld: Mini ESP32 Clock & Media
Important
Hardware & Assembly Guide: For now, refer to esp32-clock-media for hardware requirements and step-by-step assembly photos. The enclosure is 100% compatible with this firmware.
| 🕐 Clock | Large font, 3 styles, date below |
| 🌤 Weather | Current conditions + next-day forecast via OpenWeatherMap |
| 📅 Calendar | Up to 5 upcoming events from Google Calendar, scrolling text |
| ⏰ Alarm | 4 ringtones, per-day scheduling |
| 🌙 Night Mode | Auto screen-off on schedule, wake with button press |
| ☀️ Auto Brightness | Up to 8 time-based brightness slots |
| 💤 Eco Mode | Full WiFi radio shutdown between syncs — minimal power draw |
| 🌐 Web UI | Full config from any browser, dark/light theme, live OLED preview |
| 💾 Backup/Restore | Export and import all settings as JSON |
| 🛜 Wi-Fi 6 | Native 802.11ax support via ESP32-C6 |
| 🌍 5 Languages | English, Italiano, Français, Español, Deutsch |
| Component | Detail |
|---|---|
| MCU | ESP32-C6 Super Mini |
| Display | SSD1306 128×64 OLED (I2C) |
| Button | BOOT button — GPIO 9 |
| Buzzer | Passive buzzer — GPIO 18 |
| SDA | GPIO 19 |
| SCL | GPIO 20 |
No buzzer? Set
#define ENABLE_BUZZER 0at the top ofcuboid.ino.
- Install ESP32 by Espressif in Arduino IDE (board manager URL below)
- Select
ESP32C6 Dev Moduleand your COM port - Open
cuboid/cuboid.inoand click Upload
https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
On first boot the device creates a WiFi hotspot called ESP32-Cuboid.
- Connect your phone or PC to it
- Open
http://192.168.4.1(orhttp://cuboid.local) - Enter your WiFi credentials, timezone, and optionally your API keys
- Save & Reboot — done
After connecting to your network the clock is reachable at http://cuboid.local or the IP shown on the display.
| Action | Result |
|---|---|
| Short press | Cycle modes: Clock → Calendar → Weather → Clock |
| Long press on Weather | Switch to Forecast view |
| Long press on Calendar (multiple events) | Next event |
| Short press during alarm | Dismiss |
| Short press during Night Mode | Wake screen temporarily |
| Hold 2 seconds | Open on-device Settings menu |
| Hold 10 seconds | Factory reset |
Open http://cuboid.local from any browser on your network.
- Enable/disable alarm, set time and active days
- Choose ringtone (Digital Beep, Nervous Cricket, Melodic Rise, Sci-Fi Siren)
- Timezone — 28 entries covering the full globe (UTC+12 → UTC−11) with city labels; unknown saved POSIX strings are preserved as a "Custom" option
- Clock font (Sans Bold / Sans / Serif Bold)
- Date format (5 styles including day/month names)
- Screen-off animation and speed
- Wake animation (mirror the screen-off effect on wake)
- Auto clock return timeout
- Auto-brightness — define up to 8 time/brightness slots; the display dims and brightens automatically throughout the day
- Off / Scheduled / Always on
- Set start and end times
- Wake duration when button is pressed at night
- OpenWeatherMap API key + city → Get a free key
- Google Apps Script URL for calendar (see setup below)
- Change network and password
- Change language
- Flash firmware from browser (
.binupload) - Set OTA username/password for Arduino IDE OTA
- Export/import all settings as
cuboid-settings.json - Live system info: chip, heap, temperature, uptime
- Live WiFi info: RSSI, channel, security, 802.11 flags
- Factory Reset — two-step confirmation wipes all settings and reboots into setup mode
The topbar on every page includes a 📺 button that opens a floating panel with a real-time 3× canvas replica of the display, updated every second. Three buttons — Tap, Med, and Hold — simulate physical button presses remotely, so you can navigate menus and change settings without touching the device.
Hold the button for 2 seconds to open the settings menu on the display. Navigate with short presses, confirm with a medium hold.
SETTINGS
├── Controls → Mute · Alarm on/off
├── WiFi → Network (force AP) · Eco Mode
├── Display → Screen · Brightness · Font · Night Mode · Date Format · Animation · Auto-return
└── System → Language · Restart
└── Info → CPU MHz · Temp · WiFi RSSI · Uptime (read-only)
Eco Mode cuts power consumption by shutting down the WiFi radio completely between syncs. Enable it from the on-device settings menu (WiFi → EcoMode).
When enabled:
- The radio is stopped (
esp_wifi_stop) after every sync cycle - Weather, calendar and NTP are refreshed every 2 hours; the radio powers up only for the duration of the sync
- Pre-alarm sync — the radio wakes automatically 1–10 minutes before the scheduled alarm, so the time is always accurate when it fires
- A small animated indicator (
~*/*~) appears in the top-right corner of the clock face while connecting - If the alarm fires mid-sync, the connection is aborted immediately so the buzzer is not delayed
Eco Mode is most useful on battery-powered builds or whenever the web UI is not needed during the day.
The clock fetches events via a Google Apps Script web app that you deploy once.
- Go to script.google.com and create a new project
- Paste this code:
function doGet() {
var cal = CalendarApp.getDefaultCalendar();
var now = new Date();
var end = new Date(now.getTime() + 48 * 60 * 60 * 1000);
var events = cal.getEvents(now, end);
if (events.length === 0) {
return ContentService.createTextOutput(
JSON.stringify({ hasEvent: false })
).setMimeType(ContentService.MimeType.JSON);
}
var result = [];
for (var i = 0; i < Math.min(events.length, 5); i++) {
var e = events[i];
var start = e.getStartTime();
var isToday = (start.toDateString() === now.toDateString());
var isTomorrow = (start.toDateString() === new Date(now.getTime() + 86400000).toDateString());
var prefix = isToday ? "Today " : (isTomorrow ? "Tomorrow " : "");
var timeStr = prefix + Utilities.formatDate(start, Session.getScriptTimeZone(), "HH:mm");
result.push({ event: e.getTitle(), time: timeStr });
}
return ContentService.createTextOutput(
JSON.stringify({ hasEvent: true, events: result })
).setMimeType(ContentService.MimeType.JSON);
}- Deploy → New deployment → Web App
- Set Execute as: Me and Who has access: Anyone
- Copy the URL and paste it in the Web UI under Google Script URL
#define OLED_SDA 19 // I2C pins
#define OLED_SCL 20
#define BOOT_BUTTON_PIN 9
#define BUZZER_PIN 18
#define ENABLE_BUZZER 1 // set to 0 to disable buzzer entirely
#define HOSTNAME "cuboid" // accessible as cuboid.localconst unsigned long DATA_REFRESH_INTERVAL = 7200000UL; // weather/calendar/NTP refresh interval (ms)
// also used as eco sync intervalInstall from Arduino Library Manager (Sketch → Include Library → Manage Libraries):
| Library | Author |
|---|---|
| Adafruit GFX Library | Adafruit |
| Adafruit SSD1306 | Adafruit |
| U8g2 | oliver |
| ArduinoJson | Benoit Blanchon |
| ArduinoOTA | built-in with ESP32 core |
cuboid/
└── cuboid.ino ← open this in Arduino IDE
README.md
CHANGELOG.md
LICENSE
⚠️ Arduino requires the sketch file to be inside a folder with the same name. Don't rename them independently.
Print files and assembly photos are in the older repo for now: 🔗 Assembly Photos & Hardware Guide
👉 MakerWorld — ready-to-print profiles
Quick print settings: PLA or PETG · 0.2 mm layers · 15–20% infill · supports where needed
- Auto Timezone via IP — detect timezone automatically on first boot
- Info Screen — live diagnostics (CPU · Temp · RSSI · Uptime) in the on-device settings menu
- Live OLED Preview — real-time display preview and button simulation in the web UI
- Better 3D Enclosure — maybe i'll build a new optimized case on MakerWorld
- Full Offline Mode — set time and date fully offline without WiFi
- Multi WiFi — store up to N networks and connect automatically
- Orientation — rotate the UI to support any mounting orientation
- Switch to C lang and ESP-IDF — we'll build native, scalable and separate .C files so you can change things better and update only the required files (this might be less user-friendly but it's better...).
-
- Switch to RTOS
-
- Add changing alarm sound and other related things inside the settings menù on the display
-
- Fix display wake up and sleep animations
PRs and issues are welcome. If you improve the enclosure or add features, feel free to open a PR or share your remix on MakerWorld.
If you find Cuboid useful and want to help keep it going, a small donation goes a long way — it helps cover components for testing new hardware revisions and keeps the motivation up for future features.
A GitHub star is just as appreciated! ⭐
MIT — see LICENSE. Free to use, modify and distribute, including the 3D enclosure.