ESP8266 OLED Clock
revised d. bodnar 6-28-2017
The ESP8266 has the ability to connect to
the Internet wirelessly. One of these connections can be to an
Internet time server where accurate time information can be used to
synchronize a clock.
This project is designed to create a simple clock that displays the time on a small OLED screen. It connects to the Internet to set the time. The core of the software is based on two sources. One that gets the time information and the other that sets up the OLED display. |
Arduino Code Clock-8266-12-V2-H-M-S-via-serialOnly-plus-OLED-v2-0-WORKS D:\shared_stuff\Dropbox\Arduino\ESP8266\Clock-OLED-experiment\Clock-8266-12-V2-H-M-S-via-serialOnly-plus-OLED-v2-0-WORKS //NOTE: some reminants from the original clock program remain // An experiment using the ESP-8266 to lock onto time server and display it on an OLED // Using board from BangGood as ESP-12E module // 6-28-2017 working // TO GET OLED WORKING I NEEDED TO MAKE CHANGES SHOWN HERE // https://github.com/structure7/fridgeTemps // OLED_RESET=0, etc and it works // ON OLED/ESP12 pin D1 to SCL and pin D2 to SDA //************* Wol Clock by Jon Fuge ****************************** // http://www.instructables.com/id/Wol-Clock-ESP8266-12E-60-LED-WS2812B-Analogue-Digi/?ALLSTEPS //************* Declare included libraries ****************************** #include <NTPClient.h> #include <Time.h> #include <TimeLib.h> #include <Adafruit_NeoPixel.h> #include <ESP8266WiFi.h> #include <WiFiUdp.h> #include <SPI.h> #include <Wire.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define SSD1306_128_64 #define OLED_RESET 0 Adafruit_SSD1306 display(OLED_RESET); #define NUMFLAKES 10 #define XPOS 0 #define YPOS 1 #define DELTAY 2 //Set your timezone in hours difference rom GMT const int hours_Offset_From_GMT = -5; //Set your wifi details so the board can connect and get the time from the internet const char *ssid = "XXXX"; // your network SSID (name) const char *password = "PASSWORD"; // your network password byte SetClock; // By default 'time.nist.gov' is used. WiFiUDP ntpUDP; NTPClient timeClient(ntpUDP); // Which pin on the ESP8266 is connected to the NeoPixels? #define PIN 14 // This is the D5 pin //************* Declare user functions ****************************** void Draw_Clock(time_t t, byte Phase); int ClockCorrect(int Pixel); void SetBrightness(time_t t); void SetClockFromNTP (); bool IsDst(); //************* Declare NeoPixel ****************************** Adafruit_NeoPixel pixels = Adafruit_NeoPixel(60, PIN, NEO_GRB + NEO_KHZ800); //************* Setup function for Wol_Clock ****************************** #if (SSD1306_LCDHEIGHT != 32) #error("Height incorrect, please fix Adafruit_SSD1306.h!"); #endif void setup() { Serial.begin(115200); Serial.println("Test of clock!!!!!"); Serial.println("Test of clock!!!!!"); Serial.println("Test of clock!!!!!"); WiFi.begin(ssid, password); // Try to connect to WiFi while ( WiFi.status() != WL_CONNECTED ) delay ( 500 ); // keep waiging until we successfully connect to the WiFi SetClockFromNTP(); // get the time from the NTP server with timezone correction Wire.begin(4, 5); Serial.begin(9600); // by default, we'll generate the high voltage from the 3.3v line internally! (neat!) display.begin(SSD1306_SWITCHCAPVCC, 0x3C); // initialize with the I2C addr 0x3C (for the 128x32) display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(12, 9); // over (X) then down (Y) display.println("Syncing V2"); display.display(); } void SetClockFromNTP () { timeClient.update(); // get the time from the NTP server setTime(timeClient.getEpochTime()); // Set the system yime from the clock if (IsDst()) adjustTime((hours_Offset_From_GMT + 1) * 3600); // offset the system time with the user defined timezone (3600 seconds in an hour) else adjustTime(hours_Offset_From_GMT * 3600); // offset the system time with the user defined timezone (3600 seconds in an hour) } bool IsDst() { if (month() < 3 || month() > 10) return false; if (month() > 3 && month() < 10) return true; int previousSunday = day() - weekday(); if (month() == 3) return previousSunday >= 24; if (month() == 10) return previousSunday < 24; return false; // this line never gonna happend } //************* Main program loop for Wol_Clock ****************************** void loop() { time_t t = now(); // Get the current time SetBrightness(t); if (minute(t) == 0) // at the start of each hour, update the time from the time server if (SetClock == 1) { SetClockFromNTP(); // get the time from the NTP server with timezone correction SetClock = 0; } else { delay(200); // Just wait for 0.1 seconds SetClock = 1; } } //************* Function to set the clock brightness ****************************** void SetBrightness(time_t t) { int NowHour = hour(t); int NowMinute = minute(t); int NowSecond = second(t); Serial.print("Hour = "); Serial.print(NowHour); Serial.print(" Minute= "); Serial.print(NowMinute); Serial.print(" Second= "); Serial.println(NowSecond); display.clearDisplay(); display.setTextSize(2); display.setTextColor(WHITE); display.setCursor(12, 9); // over (X) then down (Y) display.print(NowHour); display.print(":"); if (NowMinute <= 9) { display.print("0"); // pad #s < 10 with leading zero } display.print(NowMinute); display.print(":"); if (NowSecond <= 9) { // pad #s < 10 with leading zero display.print("0"); } display.print(NowSecond); display.display(); delay(1000); }
|
A Better Program After working on the program above I found a better program that includes the day and date - I changed it a bit to show seconds and only P or A for PM / AM. The pins used also changed- D3--SDA and D4 --SCL If was found here: http://www.instructables.com/id/Simplest-ESP8266-Local-Time-Internet-Clock-With-OL/ D:\shared_stuff\Dropbox\Arduino\ESP8266\Clock-OLED-experiment\simplestesp8266clock-w-seconds // simplestesp8266clock.ino // // 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 = "sssssss"; // insert your own ssid const char* password = "pppppppp"; // 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 += ":"; if(second(local) < 10) // add a zero if minute is under 10 t += "0"; t+= second(local); 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(1000); //Send a request to update every 10 sec (= 10,000 ms) }
|