In this project we are going to make ESP01 Internet Clock with OLED SSD1306
Introduction
I was looking for a straightforward clock to use with a 128x64 OLED I got from Adafruit but found that a lot of the implementations were too cumbersome, involved a ton of code, weren't clear on what NTP servers to use and how, and basically offered very little in terms of making a clock with the LOCAL time (not UTC, which is easy enough to get). So I set about doing my own research and ended up with this simple clock that leverages already made libraries to minimize the code footprint while offering some interesting tweaks in displaying the time (like AM/PM, 12-hour format, names for months, days, etc). We assume you have ESP-01 programming experience so Let's Get Started!
JLCPCB is the foremost PCB prototype & manufacturing company in china, providing us with the best service we have ever experienced regarding (Quality, Price Service & Time).PCB Prototype for 5$
// Libraries needed:
// Time.h & TimeLib.h: https://github.com/PaulStoffregen/Time
// Timezone.h: https://github.com/JChristensen/Timezone
// SSD1306.h & SSD1306Wire.h: https://github.com/squix78/esp8266-oled-ssd1306
// NTPClient.h: https://github.com/arduino-libraries/NTPClient
// ESP8266WiFi.h & WifiUDP.h: https://github.com/ekstrand/ESP8266wifi
//
// 128x64 OLED pinout:
// GND goes to ground
// Vin goes to 3.3V
// Data to I2C SDA (GPIO 0)
// Clk to I2C SCL (GPIO 2)
#include <ESP8266WiFi.h>
#include <WifiUDP.h>
#include <String.h>
#include <Wire.h>
#include <SSD1306.h>
//#include <SSD1306Wire.h>
#include <NTPClient.h>
#include <Time.h>
#include <TimeLib.h>
#include <Timezone.h>
// Define NTP properties
#define NTP_OFFSET 60 * 60 // In seconds
#define NTP_INTERVAL 60 * 1000 // In miliseconds
#define NTP_ADDRESS "ca.pool.ntp.org" // change this to whatever pool is closest (see ntp.org)
// Set up the NTP UDP client
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, NTP_ADDRESS, NTP_OFFSET, NTP_INTERVAL);
// Create a display object
SSD1306 display(0x3c, 0, 2); //0x3d for the Adafruit 1.3" OLED, 0x3C being the usual address of the OLED
const char* ssid = "TP-LINK_CD2ED6"; // insert your own ssid
const char* password = "20244064"; // and password
String date;
String t;
const char * days[] = {"Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"} ;
const char * months[] = {"Jan", "Feb", "Mar", "Apr", "May", "June", "July", "Aug", "Sep", "Oct", "Nov", "Dec"} ;
const char * ampm[] = {"AM", "PM"} ;
void setup ()
{
Serial.begin(115200); // most ESP-01's use 115200 but this could vary
timeClient.begin(); // Start the NTP UDP client
Wire.pins(0, 2); // Start the OLED with GPIO 0 and 2 on ESP-01
Wire.begin(0, 2); // 0=sda, 2=scl
display.init();
display.flipScreenVertically();
// Connect to wifi
Serial.println("");
Serial.print("Connecting to ");
Serial.print(ssid);
display.drawString(0, 10, "Connecting to Wifi...");
display.display();
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED)
{
delay(500);
Serial.print(".");
}
Serial.println("");
Serial.print("Connected to WiFi at ");
Serial.print(WiFi.localIP());
Serial.println("");
display.drawString(0, 24, "Connected.");
display.display();
delay(1000);
}
void loop()
{
if (WiFi.status() == WL_CONNECTED) //Check WiFi connection status
{
date = ""; // clear the variables
t = "";
// update the NTP client and get the UNIX UTC timestamp
timeClient.update();
unsigned long epochTime = timeClient.getEpochTime();
// convert received time stamp to time_t object
time_t local, utc;
utc = epochTime;
// Then convert the UTC UNIX timestamp to local time
TimeChangeRule usEDT = {"EDT", Second, Sun, Mar, 2, -300}; //UTC - 5 hours - change this as needed
TimeChangeRule usEST = {"EST", First, Sun, Nov, 2, -360}; //UTC - 6 hours - change this as needed
Timezone usEastern(usEDT, usEST);
local = usEastern.toLocal(utc);
// now format the Time variables into strings with proper names for month, day etc
date += days[weekday(local)-1];
date += ", ";
date += months[month(local)-1];
date += " ";
date += day(local);
date += ", ";
date += year(local);
// format the time to 12-hour format with AM/PM and no seconds
t += hourFormat12(local);
t += ":";
if(minute(local) < 10) // add a zero if minute is under 10
t += "0";
t += minute(local);
t += " ";
t += ampm[isPM(local)];
// Display the date and time
Serial.println("");
Serial.print("Local date: ");
Serial.print(date);
Serial.println("");
Serial.print("Local time: ");
Serial.print(t);
// print the date and time on the OLED
display.clear();
display.setTextAlignment(TEXT_ALIGN_CENTER);
display.setFont(ArialMT_Plain_24);
display.drawStringMaxWidth(64, 10, 128, t);
display.setFont(ArialMT_Plain_10);
display.drawStringMaxWidth(64, 38, 128, date);
display.display();
}
else // attempt to connect to wifi again if disconnected
{
display.clear();
display.drawString(0, 10, "Connecting to Wifi...");
display.display();
WiFi.begin(ssid, password);
display.drawString(0, 24, "Connected.");
display.display();
delay(1000);
}
delay(10000); //Send a request to update every 10 sec (= 10,000 ms)
}