Sponsored By
A compact, open-source smartwatch powered by the ESP32-S3-WROOM with real-time clock, battery monitoring, and USB charging.
- Introduction
- Features
- Hardware Overview
- Sponsorship and Support
- Schematic & PCB Design
- Known issues & Fix
- Bill of Materials (BoM)
- Firmware & Software
- Assembly & Soldering Guide
- Usage Guide
- Power Management
- Downloads
- Firmware
- Visit Interactive BOM
- Contributing
- License
- Acknowledgments
The Schrödinger Watch is an ESP32-S3-based open-source smartwatch designed with a focus on compact PCB layout, low power consumption, and modular features. It integrates RTC, I2C display, battery monitoring, and a USB charging circuit, making it a versatile platform for wearable tech enthusiasts.
| Feature | Description |
|---|---|
| Microcontroller | ESP32-S3-WROOM (40-pin) |
| Display | I2C OLED |
| RTC Module | DS3231 (with alarm) |
| Buttons | 3 push buttons (pull-up) |
| Buzzer | Included for alarms and notifications |
| Battery | 3.7V Li-Po battery |
| Charging Circuit | TP4056 for Li-Po charging |
| Battery Monitoring | Voltage divider for ADC measurement |
| USB Communication | CP2102 USB programmer |
| Power Switching | *P-MOSFET for auto power control |
| Protection Circuit | Schottky diode for USB protection |
- *feature will be added on the next revision
The smartwatch is designed with SMD components for compactness. Below is the pin mapping:
| Component | ESP32 GPIO | Function |
|---|---|---|
| OLED SDA | GPIO 20 | I2C SDA |
| OLED SCL | GPIO 21 | I2C SCL |
| RTC SDA | GPIO 20 | I2C SDA |
| RTC SCL | GPIO 21 | I2C SCL |
| RTC Alarm | GPIO 11 | SQW/INT to ESP32 |
| Battery ADC | GPIO7 | Voltage divider to ESP32 Analog Pin |
| LED | GPIO 2 | Status Indication |
| LED | GPIO 3 | Status Indication |
| LED | GPIO 4 | Status Indication |
| Push Button 1 | GPIO 12 | User Input |
| Push Button 2 | GPIO 13 | User Input |
| Push Button 3 | GPIO 22 | User Input |
- refer circuit Schrödinger_Watch_schematics for more detailed pin out.and pin assignments
This project was proudly sponsored by PCBWay.
Their support in fabricating the custom PCB for the Schrödinger Watch has been invaluable. The quality, precision, and delivery speed were exceptional — and I’m extremely grateful for their contribution to the maker and open-source community.
If you're looking for reliable PCB prototyping, assembly, or 3D printing services, I highly recommend PCBWay.
The Schrödinger Watch PCB was designed using KiCad. The schematic consists of:
- ESP32-S3-WROOM microcontroller
- RTC DS3231 with backup battery support
- Power management with TP4056 and P-MOSFET
- I2C OLED display
- Battery voltage detection circuit
- USB programmer (CP2102)
PCB Highlights:
- 2-layer compact design
- Optimized power trace routing
- Thermal relief for heat dissipation
- Dedicated test points for debugging
Schrödinger Watch ⌚ – ESP32-S3 DIY Smartwatch
This is the Schrödinger Watch, a DIY smartwatch powered by the ESP32-S3-WROOM. It's a fully open-source hardware project, designed and assembled from scratch, with a focus on learning, hacking, and creativity.
⚠️ Note: This is Rev 1 of the hardware. While functional, it contains some known hardware issues listed below. A refined Rev 2 is under development and will be released by September 2025 with additional features and improved reliability.
These are hardware issues identified after assembly and testing:
-
Missing CE Connection on TP4056:
⚠️ The CE (Chip Enable) pin was left floating, causing the charging IC to remain disabled.- ✅ Fix: A patch wire has been added to tie CE to GND manually.
-
AMS1117 3.3V LDO Lacks Input/Output Capacitors:
⚠️ Without these caps, voltage regulation is unstable (outputting ~2.4V instead of 3.3V).- ✅ Fix: Patch capacitors (10µF input, 22µF output) have been manually added close to the LDO pins.
-
No Pull-Down Resistors for Pushbuttons:
⚠️ Causes GPIO pins to float, leading to erratic behavior.- ✅ Fix: External 10kΩ pull-down resistors were added to stabilize the inputs.
-
Soldering Considerations:
- The board is fully designed with SMD components for a compact layout.
- All components were hand-soldered using a soldering iron, without hot air or reflow equipment. Minor imperfections exist, but the board is fully functional.
Rev 2 will be a major update with all hardware issues addressed and new features, including:
- ✅ Proper power rail decoupling and CE management
- ✅ Integrated MPU6050 IMU for motion sensing
- ✅ Improved button input system
- ✅ Compact routing
- ✅ Better power management and battery indication
- ✅ Optional haptic feedback (planned)
- ✅ Additional user-customizable GPIOs
📌 Disclaimer
This is a learning-oriented DIY project and should not be considered a finished consumer product. Use with care and contribute to make it better!
| Component | Quantity | Specification |
|---|---|---|
| ESP32-S3-WROOM | 1 | 40-pin module |
| OLED Display | 1 | I2C, 128x64 |
| DS3231 RTC | 1 | Real-time clock module |
| Li-Po Battery | 1 | 3.7V, 500mAh |
| TP4056 Module | 1 | Battery charger |
| CP2102 | 1 | USB-to-serial |
| Buzzer | 1 | 3V piezo |
| Push Buttons | 3 | Momentary switch |
| Resistors & Capacitors | Various | SMD components |
The firmware is written in Arduino using the ESP32 library. It supports:
- RTC time synchronization
- OLED display updates
- Battery monitoring
- Button interactions
- Alarm system with buzzer
- Soldering iron with fine tip
- SMD soldering paste
- Hot air reflow station (optional)
- Multimeter for testing
- Solder the ESP32-S3-WROOM module first.
- Attach RTC DS3231 and connect alarm pin to ESP32.
- Solder resistors, capacitors, and power circuits.
- Mount OLED display and ensure I2C connectivity.
- Connect battery and charging module.
- Flash firmware and test.
Press and hold the power button. The watch will display the time, battery status, and active alarms.
Use the serial monitor to set the time in RTC using setTime().
Battery percentage is displayed on-screen and can be accessed through the serial monitor.
The RTC alarm triggers a buzzer sound at the set time.
- Automatic Power Switching: P-MOSFET allows seamless switching between USB and battery.
- USB Protection: Schottky diode prevents reverse current flow.
- Low Power Mode: ESP32 enters deep sleep when inactive to conserve power.
- Download KiCad files: Schrödinger_Watch.kicad_pcb
- Download Code: Schrödinger_Watch.ino
- Schematics: Schrödinger_Watch_schematics
🛠️ Libraries Used
Install via Arduino Library Manager or PlatformIO.
🚧 Known Hardware Issues (Rev 1)
- ❌ No CE connection to TP4056 (manually patched)
- ❌ No input/output capacitors on MIC39100/AMS1117 LDO (caused unstable voltage)
- ❌ No pull-down resistors for switches (using
INPUT_PULLDOWNin firmware)
The current version of the firmware is a minimal working build to demonstrate the core functionality of the Schrödinger Watch. Several features are not yet implemented:
- ❌ Push Buttons are read but not interfaced with any logic or user interaction yet.
- ❌ RTC Alarm Interrupt is connected (GPIO 11), but not yet used in the firmware.
- ❌ ESP32 Deep Sleep functionality is not implemented.
These features will be added in the next firmware updates as part of the development toward Rev 2 and in between the current development , revision 2 of this watch expected by September 2025.
#include <Wire.h>
#include <U8g2lib.h>
#include <RTClib.h>
// this code works but to be honest there is a lot of places to improve , like switch are just interfaced but not given any function , but can be done like to set time etc etc ......
// all issues will be fixed as a progress please bare with me , but if you have the knowledge then happy to recieve help
// I2C Pins
#define SDA_PIN 20
#define SCL_PIN 21
// GPIO Definitions
#define LED_PIN 2
#define BATTERY_ADC 7
#define RTC_ALARM_PIN 11
#define BUTTON1 12
#define BUTTON2 13
#define BUTTON3 14
U8G2_SSD1306_128X64_NONAME_F_HW_I2C u8g2(U8G2_R0, U8X8_PIN_NONE);
RTC_DS3231 rtc;
void setup() {
Serial.begin(115200);
Wire.begin(SDA_PIN, SCL_PIN);
u8g2.begin();
pinMode(LED_PIN, OUTPUT);
pinMode(RTC_ALARM_PIN, INPUT);
pinMode(BATTERY_ADC, INPUT);
pinMode(BUTTON1, INPUT_PULLDOWN);
pinMode(BUTTON2, INPUT_PULLDOWN);
pinMode(BUTTON3, INPUT_PULLDOWN);
if (!rtc.begin()) {
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_ncenB08_tr);
u8g2.drawStr(0, 20, "RTC Not Found");
u8g2.sendBuffer();
while (1);
}
if (rtc.lostPower()) {
rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
}
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_6x10_tr);
u8g2.drawStr(0, 10, "Schrodinger Watch");
u8g2.sendBuffer();
delay(1000);
}
void loop() {
DateTime now = rtc.now();
char timeStr[9];
sprintf(timeStr, "%02d:%02d:%02d", now.hour(), now.minute(), now.second());
float batteryVoltage = analogRead(BATTERY_ADC) * (3.3 / 4095.0) * 2; // Adjust based on divider
char voltStr[10];
dtostrf(batteryVoltage, 4, 2, voltStr);
u8g2.clearBuffer();
u8g2.setFont(u8g2_font_logisoso38_tr);
u8g2.drawStr(0, 50, timeStr);
u8g2.setFont(u8g2_font_6x10_tr);
u8g2.drawStr(0, 62, ("BAT: " + String(voltStr) + "V").c_str());
u8g2.sendBuffer();
digitalWrite(LED_PIN, !digitalRead(LED_PIN));
if (digitalRead(BUTTON1)) Serial.println("Button 1 Pressed");
if (digitalRead(BUTTON2)) Serial.println("Button 2 Pressed");
if (digitalRead(BUTTON3)) Serial.println("Button 3 Pressed");
delay(1000);
}We welcome contributions! If you’d like to improve the watch, please:
- Fork the repository.
- Create a new branch.
- Submit a Pull Request with details.
This project is licensed under the MIT License. Feel free to use, modify, and distribute it with proper attribution.
Special thanks to the open-source hardware community for inspiring this project!
