Clocks with no Knobs

This digital clock has no setting or control knobs because the date and time are automatically set using the accurate internet time. Email parts@robotsforfun.com to get the parts for this project.

Before you attempt to do this, you need to first know how to work with the ESP8266 WiFi module.

Parts needed:
  • ESP8266-12
  • Jumbo 7-segment common cathode LED displays 5x
  • MAX7219 controller
  • UDN2981A
  • 9V to 3.3V converter
  • 9V power supply
  • Wires
  • Soldering iron
internet clock internet clock internet clock
1 Connect the MAX7219 to the 7-segment displays as follows:
  • DIG0 to DIG4 to each of the display's common cathode
  • SEGA to SEGG and SEGDP to the eight inputs of the UDN2981A
  • The eight outputs of the UDN2981A to the display's segments
2 Here's the code. It's real long!
/*
 * 5 digit x 7 segment LED with NO colon display clock using the MAX7129
 * Digits: Common cathode
 * D0 is the leftmost digit
 * 
 * Connections:
 * MAX7219       ESP8266
 * DIN pin 1  to pin D14
 * CLK pin 12 to pin D12
 * CS  pin 13 to pin D13
 * 
 * After uploading this program to the ESP8266-12 module,
 * open the serial monitor and restart the ESP8266 module to 
 * see what IP address is assigned to this webserver,
 * then browse to this IP address.
 * 
 * or
 * 
 * Connect your WiFi to the default ssid 
 *     "WiFi setup ESP8266-xxxx"
 * or to the one you provided, then browse to the IP address
 *     1.2.3.4 
 * for the main page or
 *     1.2.3.4/setup
 * for the WiFi setup page
 * 
 * If the WiFi is not connected then you will have to go to
 * 1.2.3.4/setup to setup the ssid and password
 * 
 * Copyright 2020 Enoch Hwang
 */

 
//////////////////////////////////////////////////////////////
//// VCC voltage stuff
  ADC_MODE(ADC_VCC);


//////////////////////////////////////////////////////////////
//// status LED stuff
#define statusLed 2     // for ESP8266-12


//////////////////////////////////////////////////////////////
//// NTP clock stuff
#include "DateTime_RobotsForFun.h"


//////////////////////////////////////////////////////////////
//// WiFi stuff
#include "WiFi_RobotsForFun.h"

// Do delay without using the delay() function
void nonblockingDelay(int wait) {
  unsigned long timesUp;
  timesUp = millis() + wait;
  while (millis() < timesUp) {
//    flashActivityLed();
    server.handleClient();
    yield();  // must have this to give time to handle wifi background stuff
  }
}


//////////////////////////////////////////////////////////////
//// HTML webpage 
void indexHTML() {
  String msg = "";
  msg += "";
  msg += "";
  msg += ""; // keep fonts consistent between devices
  msg += ""; // auto refresh page every 1 second
  
  msg += "LED Clock";
  msg += "  ";
  msg += "";
  
  msg += "";
  msg += "
Jumbo LED Network Clock
"; msg += "Real time clock for the
5x7 segment LED display
using the MAX7219 controller"; msg += "
" + formattedTime() + ""; msg += "
"; msg += "
"; if (!isTimeValid()) { msg += "
"; msg += " Year: "; msg += " Month: "; msg += "       Day: "; msg += "
Hour: "; msg += "     Minute: "; msg += " Second: "; msg += "
"; msg += "
"; msg += "
"; } // wifi setup and info links msg += "IP address: "; if (wifiIsConnected) { msg += "" + WiFi.localIP().toString() + ""; msg += "
Wifi setup and info: "; msg += "" + WiFi.localIP().toString() + "/setup"; } else { msg += "1.2.3.4"; msg += "
Wifi setup and info: "; msg += "1.2.3.4/setup"; } msg += ""; msg += ""; // send webpage to browser server.send(200, "text/html", msg); // get url arguments and process the command that DO have time delays if (server.hasArg("YR")) { // set the clock int yr, mo, da, hr, mi, se; yr = server.arg("YR").toInt(); mo = server.arg("MO").toInt(); da = server.arg("DA").toInt(); hr = server.arg("HR").toInt(); mi = server.arg("MI").toInt(); se = server.arg("SE").toInt(); if (yr == 0) yr = year(); if (mo == 0) mo = month(); if (da == 0) da = day(); if (hr == 0) hr = hour(); if (mi == 0) mi = minute(); setClock(yr, mo, da, hr, mi, se); } } ////////////////////////////////////////////////////////////// //// MAX7219 7x5 LED display stuff #include "LedControl.h" #define DIN 14 #define CS 12 #define CLK 13 #define NO 1 // number of MAX72XX devices connected LedControl led = LedControl(DIN, CLK, CS, NO); int brightness = 15; // 15=max bright bool hr12 = true; void displayClock() { const static char w10[7] = {'S','M','T','W','T','F','S'}; // The "T" is changed in the LedControl.h definition const static char w1[7] = {'u','o','u','d','h','r','A'}; time_t t = time(nullptr); // get current date/time struct tm st = *gmtime(&t); // convert to time structure int h = hour12(st); // extract the parts int h24 = hour(st); int m = minute(st); int s = second(st); int w = weekday(st); // 0=Sunday int mo = month(st); int d = day(st); int h10 = h/10; // separate the 10th and unit digits int h1 = h - h10*10; int m10 = m/10; int m1 = m - m10*10; int s10 = s/10; int s1 = s - s10*10; int mo10 = mo/10; int mo1 = mo - mo10*10; int d10 = d/10; int d1 = d - d10*10; // set brightness depending on time of day if (h24 < 5) led.setIntensity(0, 2); // set the brightness else if (h24 >= 5 && h24 <= 22) led.setIntensity(0, 15); else led.setIntensity(0, 7); if (s1 < 7) { // display hour, minute led.setDigit(0, 0, h10, false); led.setDigit(0, 1, h1, false); led.setDigit(0, 3, m10, false); led.setDigit(0, 4, m1, false); // led.setLed(0, 2, 7, false); // turn digit 2, segment 7 off // led.setLed(0, 2, 3, false); // led.setLed(0, 2, 5, true); // turn digit 2, segment 5 on led.setChar(0, 2, ' ', true); // turn on digit 2 decimal point nonblockingDelay(500); // flash the dot // led.setLed(0, 2, 7, false); // led.setLed(0, 2, 3, true); // led.setLed(0, 2, 5, false); led.setChar(0, 2, ' ', false); // turn off digit 2 decimal point } else { // display weekday, day led.setChar(0, 0, w10[w], false); led.setChar(0, 1, w1[w], false); led.setChar(0, 2, '-', false); led.setDigit(0, 3, d10, false); led.setDigit(0, 4, d1, false); } } void setup() { Serial.begin(115200); pinMode(statusLed, OUTPUT); //// MAX7219 LED display stuff led.shutdown(0, false); // The MAX72XX is in power-saving mode on startup led.setIntensity(0, 15); // set the brightness 15=max led.clearDisplay(0); led.setChar(0, 0, 'C', false); led.setChar(0, 1, 'o', false); led.setChar(0, 2, 'n', false); led.setChar(0, 3, 'n', false); led.setChar(0, 4, '-', false); //// WiFi stuff char devicename[] = "Jumbo LED clock"; // optional. change to whatever you want. Use "ping ESP8266" to test setupAP(devicename); // setup access point using default ssid "WiFi setup ESP8266-xxxx" and no password IPAddress staticIP(192, 168, 1, 54); // for the Jumbo LED Network clock bool blocking = false; if (!setupWiFi(devicename, staticIP, blocking)) { // if (!setupWiFi(devicename, blocking)) { // use DHCP led.setChar(0, 0, 'F', false); led.setChar(0, 1, 'A', false); led.setChar(0, 2, 'I', false); led.setChar(0, 3, 'L', false); // block for 3 minutes unsigned long timeout = millis() + 180000; // 3 minutes while(millis() < timeout) { flashActivityLed(3000,150,1); server.handleClient(); yield(); // must have this to give time to handle wifi background stuff } ESP.restart(); // have not connected to the internet in 3 minutes so just reboot } // connected to wifi // set the clock while (!setClock(PST)) { delay(1000); } // update systemStartTime and systemStartCount systemStartTime = now(); EEPROM.get(EEPROM_ADDRESS_systemStartCount, systemStartCount); // get systemStartCount from EEPROM systemStartCount++; EEPROM.put(EEPROM_ADDRESS_systemStartCount, systemStartCount); EEPROM.commit(); } void loop() { static time_t prevDisplay; if (now() != prevDisplay) { //update the display only if time has changed prevDisplay = now(); // Serial.println(formattedTime()); displayClock(); } if (APisOn && (millis() > 600000)) turnOffAP(); // turn off AP after 10 minutes flashActivityLed(); // checkWifiConnection(); // reboot if wifi is disconnected syncClock(); // need to call this frequently to sync the clock server.handleClient(); }