Colourful Digital Clock Big Font P4 LED Display, ESP8266 NodeMcu with RTC3231 module

,

Connect the P10 LED Display with ESP8266 & DS3231RTC as shown in the image of the pin configuration

The Arduino Sketch & libraries can download here

// REQUIRES the following Arduino libraries:
// - RGB matrix Panel Library: https://github.com/2dom/PxMatrix
// - Adafruit_GFX Library: https://github.com/adafruit/Adafruit-GFX-Library
// - Adafruit_BusIO Library: https://github.com/adafruit/Adafruit_BusIO
// - esp8266 library (nodemcu) found at https://github.com/esp8266/Arduino
// - package_esp8266com_index.json found at http://arduino.esp8266.com/stable/package_esp8266com_index.json

#include <time.h>
#include <Adafruit_GFX.h>
#include <FreeMonoBold12pt7b.h>
#include <kongtext4pt7b.h>
#include <PxMatrix.h>
#include <Ticker.h>
#include <DS3232RTC.h>      // https://github.com/JChristensen/DS3232RTC
#include <Streaming.h>      // https://github.com/janelia-arduino/Streaming
#include <Wire.h>
DS3232RTC myRTC;



Ticker display_ticker;
#define P_LAT 16
#define P_A 5
#define P_B 4
#define P_C 15
#define P_D 12
#define P_OE 2
// Pins for LED MATRIX
#define matrix_width 64
#define matrix_height 32



static uint32_t lastTime = 0; // millis() memory
static bool flasher = false;  // seconds passing flasher
uint8_t frameDelay = 15;  // default frame delay value

int h, m, s, d, y;
String date;
String months;
String text;
String Message1 = "Please Subscribe to my YouTube channel : www.youtube.com/techlogicsindia";
uint8_t r = 0, g = 0, b = 0;
unsigned int NewRTCh = 24;
unsigned int NewRTCm = 60;
unsigned int NewRTCs = 10;
char szTime[4];

// This defines the 'on' time of the display is us. The larger this number,
// the brighter the display. If too large the ESP will crash
uint8_t display_draw_time = 10; //10-50 is usually fine
PxMATRIX display(64, 32, P_LAT, P_OE, P_A, P_B, P_C, P_D);

//PxMATRIX display(matrix_width,matrix_height,P_LAT, P_OE,P_A,P_B,P_C);
//PxMATRIX display(64,64,P_LAT, P_OE,P_A,P_B,P_C,P_D,P_E);

// Some standard colors
uint16_t myRED = display.color565(255, 0, 0);
uint16_t myGREEN = display.color565(0, 255, 0);
uint16_t myBLUE = display.color565(0, 0, 255);
uint16_t myWHITE = display.color565(255, 255, 255);
uint16_t myYELLOW = display.color565(255, 255, 0);
uint16_t myCYAN = display.color565(0, 255, 255);
uint16_t myMAGENTA = display.color565(255, 0, 255);
uint16_t myShadow = display.color565(255, 0, 0);
uint16_t myROSE = display.color565(253, 18, 111);
uint16_t myBLACK = display.color565(0, 0, 0);

uint16_t myCOLORS[90] = {myRED, myGREEN, myWHITE, myMAGENTA, myBLUE, myYELLOW, myCYAN, myRED, myGREEN, myMAGENTA,
                         myBLUE, myWHITE, myCYAN, myRED, myGREEN, myYELLOW, myMAGENTA, myBLUE, myRED, myYELLOW, 
                         myCYAN, myRED, myGREEN, myMAGENTA, myBLUE, myWHITE, myYELLOW, myCYAN, myBLUE, myWHITE,
                         myBLUE, myWHITE, myYELLOW, myCYAN, myRED, myGREEN, myMAGENTA, myBLUE, myRED, myYELLOW, 
                         myCYAN, myRED, myGREEN, myMAGENTA, myBLUE, myGREEN, myYELLOW, myCYAN, myBLUE, myWHITE,
                         myRED, myGREEN, myMAGENTA, myBLUE, myWHITE, myYELLOW, myCYAN, myRED, myGREEN, myMAGENTA,
                         myBLUE, myWHITE, myYELLOW, myCYAN, myRED, myGREEN, myMAGENTA, myBLUE, myGREEN, myYELLOW, 
                         myBLUE, myWHITE, myYELLOW, myCYAN, myRED, myGREEN, myMAGENTA, myBLUE, myShadow, myYELLOW, 
                         myCYAN, myRED, myGREEN, myMAGENTA, myBLUE, myWHITE, myYELLOW, myCYAN, myBLUE, myShadow};


// ISR for display refresh
void display_updater()
{
  display.display(display_draw_time);
}
void display_update_enable(bool is_enable)
{
  if (is_enable)
    display_ticker.attach(0.002, display_updater);
  else
    display_ticker.detach();
}


void Date_text(uint8_t yp)
{

  int currentDate = d;
  String currentMonth = months;
  int currentYear = y;
  display.setCursor(1, yp);
  display.fillRect(0, yp, 64, 8, myBLACK);
  display.setFont(&kongtext4pt7b);
  display.setTextColor(myRED);
  
  if (d < 10) {
    display.print("0");
  } 
  display.print(currentDate);
  display.setTextColor(myYELLOW);
  display.print(text);
  display.setTextColor(myGREEN);
  display.print(currentMonth);
  display.setTextColor(myYELLOW);
  display.print(currentYear);
  display.setFont();
}


void getTim(char *psz)
{
  if (flasher)
  {
    display.fillRect(54, 10, 10, 6, myBLACK);
    display.setCursor(20, 8);
    display.setTextSize(2);
    display.setTextColor(myCOLORS[g]);
    display.print(":");
    b = random(0,8);
  }else
  {
    display.fillRect(24, 12, 2, 6, myBLACK);
    display.setCursor(54, 10);
    display.setTextSize(1);
    display.setFont(&kongtext4pt7b);
    display.setTextColor(myCOLORS[b]);
    display.print("*");
    display.setFont();
    g = random(0,8);
  }
  if (NewRTCs != s / 10)
  {  
    display.fillRect(51, 17, 13, 6, myBLACK);
    NewRTCs = s / 10;
    r = random(0,8);
  } else
  {
    display.fillRect(58, 17, 6, 6, myBLACK);
  }
  sprintf(psz, "%02d", s);
    display.setCursor(51, 16);
    display.setTextSize(1);
    display.setTextColor(myCOLORS[r]);
    display.setFont(&kongtext4pt7b);
  display.print(szTime);
    display.setFont();
   if (NewRTCm != m)
      {
  sprintf(psz, "%02d", m);
  display.setCursor(26, 16);
  display.setFont(&FreeMonoBold12pt7b);
  display.setTextColor(myBLUE);
  display.fillRect(26, 8, 25, 15, myBLACK);
  display.print(szTime);
  display.setFont();
  NewRTCm = m;
      }
  if (NewRTCh != h)
      {
  sprintf(psz, "%02d", h);
  display.setCursor(0, 16);
  display.setFont(&FreeMonoBold12pt7b);
  display.setTextColor(myBLUE);
  display.fillRect(0, 8, 24, 15, myBLACK);
  display.print(szTime);
  display.setFont();
  NewRTCh = h;
      }
}
void scroll_text(uint8_t ypos, unsigned long scroll_delay, String text)
{
  int y = 0;
  uint16_t text_length = text.length();
  // Asuming 5 pixel average character width
  for (int xpos = matrix_width; xpos > -(matrix_width + text_length * 7); xpos--)
  {
 // webServer.handleClient();    
    display.setCursor(xpos, ypos);
    display.fillRect(0, ypos, 64, 8, myBLACK);
    display.setFont(&kongtext4pt7b);
  for (int x = 0; x < text_length; x++) {
    display.setTextColor(myCOLORS[x+r]);
    display.print(text[x]);
  }
    display.setFont();
    delay(scroll_delay);
    yield();
    if (millis() - lastTime >= 1000)
    {
      lastTime = millis();
//      updateTime();
      getTime();

      getTim(szTime);
      flasher = !flasher;
    }
  }
}

void setup() {
  display.begin(16);
  // Initialize Serial Monitor
  Serial.begin(9600);
  display.setFastUpdate(true);
  display.setRotation(0); // we don't wrap text so it scrolls nicely
  display.setTextWrap(false);
  display_update_enable(true);
  display.clearDisplay();
  display.setTextColor(myCYAN);
  display.setCursor(2, 0);
  display.print("Connecting");
  display.setTextColor(myYELLOW);
  display.setCursor(2, 8);

    Serial << F( "\n" __FILE__ "\n" __DATE__ " " __TIME__ "\n" );
    Wire.begin(9, 10);   //Setting wire (5 untuk SDA dan 4 untuk SCL)
    myRTC.begin();

    // setSyncProvider() causes the Time library to synchronize with the
    // external RTC by calling RTC.get() every five minutes by default.
    setSyncProvider(myRTC.get);
    Serial << F("RTC Sync");
    if (timeStatus() != timeSet) Serial << F(" FAIL!");
    Serial << endl;

}



  
void getTime() 
{
  
static time_t tLast;
    time_t t;
    tmElements_t tm;

    // check for input to set the RTC, minimum length is 12, i.e. yy,m,d,h,m,s
    if (Serial.available() >= 12) {
        // note that the tmElements_t Year member is an offset from 1970,
        // but the RTC wants the last two digits of the calendar year.
        // use the convenience macros from the Time Library to do the conversions.
        int y = Serial.parseInt();
        if (y >= 100 && y < 1000)
            Serial << F("Error: Year must be two digits or four digits!") << endl;
        else {
            if (y >= 1000)
                tm.Year = CalendarYrToTm(y);
            else    // (y < 100)
                tm.Year = y2kYearToTm(y);
            tm.Month = Serial.parseInt();
            tm.Day = Serial.parseInt();
            tm.Hour = Serial.parseInt();
            tm.Minute = Serial.parseInt();
            tm.Second = Serial.parseInt();
            t = makeTime(tm);
            myRTC.set(t);   // use the time_t value to ensure correct weekday is set
            setTime(t);
            Serial << F("RTC set to: ");
            printDateTime(t);
            Serial << endl;
            // dump any extraneous input
            while (Serial.available() > 0) Serial.read();
        }
    }

    t = now();
    if (t != tLast) {
        tLast = t;
        printDateTime(t);
        if (second(t) == 0) {
            float c = myRTC.temperature() / 4.;
            float f = c * 9. / 5. + 32.;
            Serial << F("  ") << c << F(" C  ") << f << F(" F");
        }
        Serial << endl;
    }
}

// print date and time to Serial
void printDateTime(time_t t)
{
    printDate(t);
    Serial << ' ';
    printTime(t);
}

// print time to Serial
void printTime(time_t t)
{
    printI00(hour(t), ':');
    printI00(minute(t), ':');
    printI00(second(t), ' ');
    h = hour(t);
    m = minute(t);
    s = second(t);
}

// print date to Serial
void printDate(time_t t)
{
    printI00(day(t), 0);
    Serial << monthShortStr(month(t)) << _DEC(year(t));
    d = day(t);
    months = monthShortStr(month(t));
    y = year(t);
}

// Print an integer in "00" format (with leading zero),
// followed by a delimiter character to Serial.
// Input value assumed to be between 0 and 99.
void printI00(int val, char delim)
{
    if (val < 10) Serial << '0';
    Serial << _DEC(val);
    if (delim > 0) Serial << delim;
    return;
}

void loop() 
{
  getTime();
  Date_text(0);
  scroll_text(23, frameDelay, Message1);
}