Introduction: MULTI-EFFECTS INTERNET CLOCK

About: PLC, Arduino - Do it yourself project

I have six red matrix LEDs in my warehouse, it seemed I bought them when I was a student about 15 years ago. It's surprising that they’re still in good condition. Today I'd like to share how to make by handmade an 16x24 led matrix - internet clock from these LED matrixes. It is controlled by ESP8266 NODEMCU with some cool effects...

Step 1: PARTS LIST

Step 2: SCHEMATIC

The overall schematic is as follows:

You can download schematic with high resolution PDF file HERE.

For led board's row scanning, we can use 1pcs x 74HC154 - 4 to 16 Line Decoder or 2pcs x 74HC138 - 3 to 8 Line Decoder. In my case, I used 1pcs x 74HC154.

Step 3: SOLDERING WORK

The internal structure of LED MATRIX 8x8 - common anode - is shown below:

Each 8x8 LED matrix consists of:

  • 8 positive pins are eight rows. They will be connected to the row scanning circuit with 74HC154 (or 2pcs x 74HC138) + NPN Transistors.
  • 8 negative pins are eight columns. They will be connected to the column scanning circuit with TPIC6B595N Power Logic 8-Bit Shift Register + R100 current limiting resistor.

ESP8266 pins usage is as diagram below:

I soldered all components following to the schematic diagram in STEP 2. I did this circuit by handmade, so there were many wires connecting between components. Soldering is a meticulous job, and it takes your patience. You can design and do etching printed circuit board following my schematic. And pictures below is my final result.

  • Led board - TOP VIEW.

  • Led board - BOTTOM VIEW.

  • Finally, I mounted 6 led matrix on the board.

Step 4: LED'S BOX AND BASE

  • Made a box cover for led board with clear acrylic plate in front side and white acrylic plate in back side.

  • Mounting led board inside this box and drilling a hole just enough the size of ESP8266 at back side.

  • For the led base, I reused broken wooden toy from my daughter. I drilled some holes and attached a DC female jack and push button through them. It look like this.

  • Then I used hot glue to sticked the led board to the wooden base.

  • Finish. It looks pretty cool...

Step 5: PROGRAMING

In my project, I get date and time information from an NTP server and clock will be updated over wifi, so firstly we have to install the "NTPClient" library. And base on file "timezone.h", you need to check and adjust the time offset for your timezone.

int myTimeZone = VST; // change this to your timezone (see in timezone.h)

ESP8266 NodeMCU has 4 pins D5 ~ D8 available for SPI communication. As you saw in the diagram on previous step, I connected D6 pin to the push button. Because SPI communication uses D6 pin (MISO) for sending data from the slave to the master (with the NodeMCU as the master device), therefore push button will not work properly.

To deal with this issue, I referenced to original shiftOut() function in file "core_esp8266_wiring_shift.cpp" to create for my own SPI function. You can search this file on your computer or check below link:

https://github.com/esp8266/Arduino/blob/master/cor...

void DIY_SPI(uint8_t DATA)
{
    for (uint8_t i = 0; i<8; i++)  
    {
      digitalWrite(DATA_Pin, !!(DATA & (1 << (7 - i))));
      digitalWrite(CLOCK_Pin,HIGH);
      digitalWrite(CLOCK_Pin,LOW);                
    }
}

In my program, I used Timer 1 in NodeMCU and a callback interrupt service routine.

timer1_isr_init();
timer1_attachInterrupt(timer1_ISR);
timer1_enable(TIM_DIV16, TIM_EDGE, TIM_SINGLE);
timer1_write(500);

With above setup, Timer 1 will runs at 5MHz (80MHz/16=5MHz) or 1/5MHz = 0.2us. When we set timer1_write (500), this means the interrupt will be called timer1_ISR() every 500 x 0.2us = 100us.

void ICACHE_RAM_ATTR timer1_ISR(void)
{   
  digitalWrite(BLANK_Pin, HIGH);
  
  DIY_SPI((matrixBuffer[level + 0]));
  DIY_SPI((matrixBuffer[level + 1]));
  DIY_SPI((matrixBuffer[level + 2]));
  
  rowscan(row);
  
  digitalWrite(LATCH_Pin, HIGH);
  digitalWrite(LATCH_Pin, LOW);
  digitalWrite(BLANK_Pin, LOW);
  
  row++;
  level = row * 3;
  if (row == 16) row=0;
  if (level == 48) level=0;
 
  pinMode(BLANK_Pin, OUTPUT);
  timer1_write(500);
}

For row scanning, it takes 4 NodeMCU's ouputs to activate 1 of the 16 led board's rows through 74HC154 + 16 x A1013 Transistors.

void rowscan(byte row)
{
if (row & 0x08)   digitalWrite(RowA3_Pin,HIGH);
  else            digitalWrite(RowA3_Pin,LOW);
if (row & 0x04)   digitalWrite(RowA2_Pin,HIGH);   
  else            digitalWrite(RowA2_Pin,LOW);
if (row & 0x02)   digitalWrite(RowA1_Pin,HIGH);   
  else            digitalWrite(RowA1_Pin,LOW);
if (row & 0x01)   digitalWrite(RowA0_Pin,HIGH);   
  else            digitalWrite(RowA0_Pin,LOW);      
}

The push button state will be read after every "samplingtime3" and the number of push is recorded to perform clock effects.

void ReadButton()
{
  if ( (unsigned long) (millis() - samplingtime3) > 55  )
  {   
  buttonState = digitalRead(BUTTON); 
  if (buttonState != lastButtonState) {
    if (buttonState == HIGH) {
      buttonPushCounter++;
    }
    else {    }
  }
  lastButtonState = buttonState;
  switch (buttonPushCounter % 13) 
  {
    case 0:
    animation=0;
    break;
    case 1:
    animation=1;    
    break;
    case 2:
    animation=2;   
    break;
    case 3:
    animation=3;
    break;
    case 4:
    animation=4;
    break;
    case 5:
    animation=5;    
    break;
    case 6:
    animation=6;   
    break;
    case 7:
    animation=7;
    break; 
    case 8:
    animation=8;
    break;
    case 9:
    animation=9;    
    break;
    case 10:
    animation=10;   
    break;
    case 11:
    animation=11;
    break; 
    case 12:
    animation=12;
    break;         
  }
  samplingtime3 = millis();
  }
}

My project has 13 clock effects in total as listed below. Besides, the led panel will display date and time with horizontal scrolling messages every 90 seconds in all effects mode.

For each effect, at the units digit and tens digit of hour, minute and second, before showing the newly updated time, we have to erase the time that was shown previously.

void MutiEffect_S1()
{ 
  if ( (unsigned long) (micros() - samplingtimes1) > 155  )
  {                  
    s1 = HHMMSS[20];             
    if (s1 != prves1)  
      {                  
        EraseShowNumber(16, 9, 8, 8, prves1, s1, 1, 0, animation);
        prves1 = s1;         
      } 
      samplingtimes1 = micros(); 
    }
}

The project code for multi-effects internet clock by NodeMCU is available at my GitHub:

https://github.com/tuenhidiy/MULTI_EFFECTS_INTERNE...

Step 6: FINISH

This is another version of the internet clock with updated time every 5 seconds.

THANK FOR YOUR READING!!!

Made with Math Contest

Participated in the
Made with Math Contest