A tiny box that counts down the days until an event, whatever it may be, and displays it on the small OLED screen on the front. Controlled by an ESP32-S2 chip on an Adafruit QT PY development board this device accurately keeps track of time even when the device loses power via a second onboard piece of hardware, the PCF8523.
Here is a showcase gallery of the finished device, including images of the inner electronics, outer shell, and design work. Below are sections detailing the actual step-by-step development process for the device.
Start to finish of how I developed the device.
To begin the project, as I had a general idea of what I wanted the final product to be (some sort of display counting down time accurately), I needed to find the needed parts to build it but had a general idea of what I wanted. In particular with this project I wanted to challenge myself to make the device as compact as possible, as I knew the previous ESP32 boards I had been using prior to this project were rather large, so I wanted to challenge myself by constraining the size as much as possible. I picked up a PCF8523 clock module as my timing device for the project, as it was able to track time independently even if the rest of the system lost power as it runs off of its own coin cell battery, drawing current in the micro amp range ensuring longevity. From here, I opted to use QT PY ESP32-S2 board by Adafruit, a tiny (in comparison to the WROOM ESP32 boards I was used to previously) yet powerful board with plenty of memory and storage on board ensuring I'd be able to upload the display libraries necessary. Speaking of displays, I chose the 0.96 inch LCD OLED board from Amazon.
To begin I built a simple breadboard prototype using jumpers, the components, and a breadboard. I used example code to start, and got a working prototype on the breadboard.
From here, I began doing some in-depth 3D modeling for the housing of the electronics involved. After many 3D printed prototypes, I had a simple cube design that was super compact, mounting modules and the microcontroller to the inner walls of the box. I then printed these pieces out, and after a few attempts and edits, I got a working box that properly housed everything.
The final code and wiring for the entire project goes as follows:
//Libraries
#include "Arduino.h"
#include "Wire.h"
#include "RTClib.h"
#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_SSD1306.h>
//Vars
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
//Vars - Devices
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, -1);
RTC_PCF8523 rtcPCF;
int goalDay = 17;
int goalMonth = 10;
void setup()
{
Serial.begin(9600);
Serial.println("start");
if (! rtcPCF.begin()) {
Serial.println("Couldn't find RTC");
while (1);
}
if (! rtcPCF.initialized()) {
Serial.println("RTC lost power, lets set the time!");
SetTime(2024, 8, 15, 11, 16, 0);
}
if(!display.begin(SSD1306_SWITCHCAPVCC, 0x3C)) {
Serial.println(F("SSD1306 allocation failed"));
for(;;);
}
Display("??:??");
delay(4000);
}
void loop()
{
//Print time data to serial monitor
DateTime now = rtcPCF.now();
Serial.print(now.month(), DEC);
Serial.print('/');
Serial.print(now.day(), DEC);
Serial.print('/');
Serial.print(now.year(), DEC);
Serial.print(" ");
Serial.print(now.hour(), DEC);
Serial.print(':');
Serial.print(now.minute(), DEC);
Serial.print(':');
Serial.print(now.second(), DEC);
Serial.println();
DisplayCountdown();
}
void Display(String text){
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 10);
display.println(text);
display.display();
}
void DisplayCountdown(){
display.clearDisplay();
DateTime now = rtcPCF.now();
int daysLeft = (goalMonth - now.month()) * 30;
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(40, 10);
display.print(daysLeft);
display.setCursor(2, 45);
display.setTextSize(2);
display.println(" Days Left");
display.display();
}
void DisplayTime(int fir, int sec){
display.clearDisplay();
display.setTextSize(4);
display.setTextColor(WHITE);
display.setCursor(0, 10);
if (fir > 9){
display.print(fir);
}
else{
display.print("0");
display.print(fir);
}
display.print(':');
if (sec > 9){
display.println(sec);
}
else{
display.print("0");
display.println(sec);
}
display.display();
}
void SetTime(int y, int m, int d, int hou, int minu, int sec){
rtcPCF.adjust(DateTime(y, m, d, hou, minu, sec));
}
The circuit was wired as follows:
Other Pin | ESP32 Pin |
---|---|
Screen VCC | 3.3V |
Screen GND | GND |
Screen SCA | SCA |
Screen SCL | SCL |
Clock Module VCC | 3.3V |
Clock Module GND | GND |
Clock Module SCA | SCA |
Clock Module SCL | SCL |