SSD1306 + DS3231 Desk Clock
A standalone 24-hour desk clock using the SSD1306 OLED driver and a DS3231 RTC — no Wi-Fi, no internet, just the textbook display + timekeeping pair.
Difficulty: Breadboard. Estimated build time: about 45 minutes. Estimated parts cost: about US$9.50. 4-line bill of materials. Compare supplier offers when available. A through-hole clock that keeps accurate time even when you unplug it.
Wire the shared I²C bus
Place both modules on the breadboard. Connect Arduino A5 (SCL) to BOTH the DS3231's SCL pin AND the SSD1306's SCL pin. Connect Arduino A4 (SDA) the same way to both SDA pins. Wire VCC on both modules to Arduino 5 V (the DS3231 module has a level-shifting LDO; the SSD1306 module accepts 3.3–5 V on VCC). Tie all the GNDs together. Both modules already have onboard 4.7 kΩ pull-ups on SCL/SDA — do NOT add more, that just lowers the effective pull-up too far.
Drop in the coin cell
Snap a CR2032 lithium coin cell into the DS3231 module's battery holder, positive side up. This is what keeps time when the Arduino is unplugged. The DS3231 datasheet specifies typical 3–5 year battery life because the chip draws only about 1 µA in battery-backup mode. Skip this step and the clock resets every time you cycle power.
Install the libraries
In Arduino IDE open Library Manager and install three libraries: 'RTClib' by Adafruit (handles the DS3231), 'Adafruit SSD1306', and 'Adafruit GFX Library' (Adafruit GFX is a dependency the SSD1306 library uses for fonts and primitives). All three are well-maintained and have plenty of examples.
Set the time once
Upload the RTClib example sketch 'ds3231' and check the Serial Monitor at 57600 baud — it should print the current time. If the year reads 2000 or 2165, your DS3231 has never been set. Uncomment the line `rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));` in setup(), upload once to bake your computer's clock in, then immediately re-comment that line and re-upload — otherwise every restart will reset the RTC to the moment the sketch was last compiled.
Paint the time on the OLED
In your sketch, instantiate `Adafruit_SSD1306 display(128, 64, &Wire, -1)` and `RTC_DS3231 rtc`. In loop(), call `rtc.now()` to read a DateTime object, format it as HH:MM:SS with the date underneath, and write to the display with setCursor / setTextSize / println, finishing with `display.display()` to push the frame buffer to the panel. Refresh once per second — the SSD1306's charge pump can handle continuous redraws, but you do not need to burn CPU cycles for 60 fps on a clock. Power up and the time appears in crisp white pixels, ticking forward every second.