Простые часы на ESP8266 с синхронизацией с сервером NTP и адресной светодиодной ленте WS2812 60 светодиодов на метр. Из органов управления - единственная кнопка, переключающая часы с летнего на зимнее время.

Светодиодная лента нарезана и поклеена на основание, получилось по три светодиода в вертикальных сегментах (5 см длинной) и по два в горизонтальных. Всего с точками ушло 74 светодиода. Общее потребление при LEDS.setBrightness(50) равно 200-300 миллиампер, в зависимости от цвета свечения (один цвет меньше, белый - больше, так как при этом работают все три цвета). При таком потреблении Часы можно запитать от зарядки для мобильных телефонов. 


На картинке стрелочкой показано место подключения адресной светодиодной ленты. И далее красной линией путь сигнала. Напряжение питания 5 Вольт и Земля подключаются в произвольном порядке. 

К модулю ESP8266 лента подключается на 2 контакт, на плате WEMOS D1 Mini он обозначается как D4 и кнопка подключается в выводу D3 (0). Кстати выбор этих контактов позволяет в качестве управляющего микроконтроллера использовать даже ESP-01!


С затеняющей пленкой 5% 




// Часы с переводом с летнего на зимний и обратно
// WEMOS D1 Mini и лента WS2812 (3 на вертикальные сегменты, 2 на горизонтальные, всего 74 с двумя точками)

#include <NTPClient.h>
#include <ESP8266WiFi.h>
#include <WiFiUdp.h>

#define LED_PIN 2   // номер пина к которому подключаем ленту (на плате Wemos 2 = D4)
#define LED_NUM 74  // количество светодиодов
#include "FastLED.h"
CRGB leds[LED_NUM];
byte digits[10][18] =
{
  {1,1,1,   1,1,1,   1,1,   1,1,1,   1,1,1,   1,1,   0,0 },  // Digit 0
  {0,0,0,   0,0,0,   0,0,   1,1,1,   1,1,1,   0,0,   0,0 },  // 1
  {0,0,0,   1,1,1,   1,1,   0,0,0,   1,1,1,   1,1,   1,1 },  // 2
  {0,0,0,   0,0,0,   1,1,   1,1,1,   1,1,1,   1,1,   1,1 },  // 3
  {1,1,1,   0,0,0,   0,0,   1,1,1,   1,1,1,   0,0,   1,1 },  // 4
  {1,1,1,   0,0,0,   1,1,   1,1,1,   0,0,0,   1,1,   1,1 },  // 5
  {1,1,1,   1,1,1,   1,1,   1,1,1,   0,0,0,   1,1,   1,1 },  // 6
  {0,0,0,   0,0,0,   0,0,   1,1,1,   1,1,1,   1,1,   0,0 },  // 7
  {1,1,1,   1,1,1,   1,1,   1,1,1,   1,1,1,   1,1,   1,1 },  // 8
  {1,1,1,   0,0,0,   1,1,   1,1,1,   1,1,1,   1,1,   1,1 }   // 9
}; 

bool Dot = true;          // Состояние точки
long ledColor = CRGB::Aqua ; // Используется в ф-ции Time2Array для задания цвета точек

const char* ssid     = "Точка доступа";
const char* password = "Пароль к ТД";

#define CLBUTTOM 0 // номер кнопки переключения с зимнего на летнее время (0 = D3 контакт)
byte hour, minute;
boolean second = true;

WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP);

void setup(){
  Serial.begin(115200);

  pinMode(CLBUTTOM, INPUT);         // назначить выводу порт ввода
  // подтянем пин физически резистором 10к

  FastLED.addLeds<WS2812, LED_PIN, GRB>(leds, LED_NUM);
  FastLED.setBrightness(50);  

  WiFi.begin(ssid, password);

  while ( WiFi.status() != WL_CONNECTED ) {
    delay ( 500 ); Serial.print ( "." );
  }

  timeClient.begin();              // Инициализация клиента времени
  timeClient.setTimeOffset(10800); // Наш часовой пояс +3 UTC
}

void loop() {
  if (digitalRead(CLBUTTOM) == HIGH) {  // Летнее или зимнее время
    timeClient.setTimeOffset(10800); 
  } else {
    timeClient.setTimeOffset(7200); 
  }

// Следующие строки гарантируют, что мы получим правильную дату и время:
  while(!timeClient.update()) {
    timeClient.forceUpdate();
  }
// Примечание: иногда NTP-клиент извлекает 1970-е годы. Чтобы этого не произошло, нам нужно принудительно установить обновление.

  hour = timeClient.getHours();    // Часы
  minute = timeClient.getMinutes();// Минуты
   
  // Смена режима часовых точек 
  if (Dot) Dot = false;
      else Dot = true;
  // Или так
  // Dot = !Dot;

  TimeToArray(); 
  FastLED.show();

  delay(1000);
}

// Функция перевода числа в точки на дисплее
void TimeToArray(){
  int Now = (hour*100+minute);  // Записываем время в виде числа типа 1843 (18:43)
  int cursor = LED_NUM;

  // Смена режима точек
  if (Dot){leds[36]=ledColor; leds[37]=ledColor; }
    else  {leds[36]=0x000000; leds[37]=0x000000; }
    
  for(int i=1;i<=4;i++){
    int digit = Now % 10; // get last digit in time
    if (i==1){
      cursor =56;
      for(int k=0; k<18;k++){ 
        if (digits[digit][k]== 1){leds[cursor]=ledColor;}
         else if (digits[digit][k]==0){leds[cursor]=0x000000;};
         cursor ++;
        };
      }
    else if (i==2){
      cursor =38;
      for(int k=0; k<18;k++){ 
        if (digits[digit][k]== 1){leds[cursor]=ledColor;}
         else if (digits[digit][k]==0){leds[cursor]=0x000000;};
         cursor ++;
        };
      }
    else if (i==3){
      cursor =18;
      for(int k=0; k<18;k++){ 
        if (digits[digit][k]== 1){leds[cursor]=ledColor;}
         else if (digits[digit][k]==0){leds[cursor]=0x000000;};
         cursor ++;
        };
      }
    else if (i==4){
      cursor =0;
      for(int k=0; k<18;k++){ 
        if (digits[digit][k]== 1){leds[cursor]=ledColor;}
         else if (digits[digit][k]==0){leds[cursor]=0x000000;};
         cursor ++;
        };
      }
    Now /= 10;
  } 
}