Digitální Hodiny na OLED

Popis

Tento projekt zobrazuje digitální hodiny na OLED displeji. Po připojení k WiFi se zařízení synchronizuje s internetovým časovým serverem (NTP) a zobrazuje aktuální čas ve formátu HH:MM:SS spolu s datem v levém horním rohu.

Použitý font připomíná 7-segmentový displej. Projekt podporuje automatické přepínání mezi letním a zimním časem (Evropa / Praha).

Značka

Ukázkový výstup na OLED

  • Vlevo nahoře: datum ve formátu DD.MM.YYYY př. 15.05. 2025
  • Ve středu: čas ve formátu HH:MM:SS př. 13:22:34

Ukázkový kód


#include <Arduino.h>
#include <WiFi.h>
#include <Wire.h>
#include <U8g2lib.h>
#include <time.h>

// ======== VLASTNÍ FONT: 7SEG =================
// Tento font je uložen přímo v poli (bdf_font)
const uint8_t bdf_font[372] U8G2_FONT_SECTION("bdf_font") = 
  "\21\0\4\4\4\5\5\6\6\21\37\0\341\376\0\0\0\0\0\0\0\1W \6\0 \70\3+\16\231"
  "\344\322\316\260i\36\260\31\66\15\0,\7\63dpB\2-\10\71\244\323\302\3\6.\7\63dpB"
  "\2/\6\0 \330\2\60 \337e\60G\213\20+F\244(i\177Yvtx\0\241\307\226\264\277,"
  "\221b\304\212\20-\0\61\22\323q\60K\210\7\17D\10\11\25\342\201\13I\2\62\36\337e\60\203\23"
  "\26AT\10\236\177-dE\210\26!\226\210\36<\177,BI\10&\16\63\35\337e\60\203\23\26A"
  "T\10\236\177-dE\210\66+B\13\236\177\242B\4\213\27\0\64\31\337e\60C\350\261%\355_\226"
  "\35\261\42D\233\25\241\5\317\177-<\0\65\35\337e\60\307\13\26\42\224\14\236\77\26\35bM\233\25"
  "\241\5\317\77Q!\202\305\13\0\66 \337e\60\307\13\26\42\224\14\236\77\26\35bM\213\20+\306\226"
  "\264\277,\221b\304\212\20-\0\67\30\337e\60\203\23\26AT\10\236\177-<<\360\320\202\347\277\26"
  "\36\0\70\42\337e\60G\213\20+F\244(i\177Yv\304\212\20-B\254\30[\322\376\262D\212\21"
  "+B\264\0\71\37\337e\60G\213\20+F\244(i\177Yv\304\212\20mV\204\26<\377D\205\10"
  "\26/\0:\11\363$rBz\300\11\0\0\0\4\377\377\0";

// Inicializace OLED displeje SH1107 (128x128)
U8G2_SH1107_PIMORONI_128X128_F_HW_I2C oled(U8G2_R1, U8X8_PIN_NONE);

// WiFi připojení – zadej své údaje
const char* ssid = "jmeno-wifi";
const char* password = "heslo-k-wifi";

// ======= Pomocné funkce =======

// OLED: Zobrazí dvouřádkový text na střed displeje
void showCenteredText(const char* line1, const char* line2 = nullptr) {
  oled.clearBuffer();                              // Smazat předchozí obsah
  oled.setFont(u8g2_font_6x12_tf);                 // Nastavit základní malý font

  // První řádek
  int w1 = oled.getStrWidth(line1);
  oled.setCursor((128 - w1) / 2, 50);              // Vodorovné zarovnání
  oled.print(line1);

  // Druhý řádek (volitelný)
  if (line2 && line2[0] != '\0') {
    int w2 = oled.getStrWidth(line2);
    oled.setCursor((128 - w2) / 2, 65);
    oled.print(line2);
  }

  oled.sendBuffer();                               // Vykreslit na displej
}

// Připojení k WiFi + výpis na OLED
void connectToWiFi() {
  WiFi.disconnect(true);                           // Odpojit předchozí spojení
  WiFi.mode(WIFI_STA);                             // Režim klienta
  delay(1000);
  WiFi.begin(ssid, password);                      // Připojit

  showCenteredText("WiFi se", "pripojuje...");

  unsigned long start = millis();
  const unsigned long timeout = 20000;             // 20 sekund limit

  while (WiFi.status() != WL_CONNECTED && millis() - start < timeout) {
    delay(500);
  }

  oled.clearBuffer();
  oled.setFont(u8g2_font_6x12_tf);

  if (WiFi.status() == WL_CONNECTED) {
    // Získat a zobrazit IP adresu
    String ip = WiFi.localIP().toString();
    oled.drawStr(10, 30, "Pripojeno k WiFi");
    oled.drawStr(10, 45, ip.c_str());
    oled.sendBuffer();
    delay(2000);
  } else {
    oled.drawStr(10, 30, "Nelze se");
    oled.drawStr(10, 45, "pripojit k WiFi");
    oled.sendBuffer();
    delay(3000);
  }
}

// OLED: Zobrazí datum vlevo nahoře ve formátu DD.MM.YYYY
void drawDate(struct tm *timeinfo) {
  char dateStr[11];
  sprintf(dateStr, "%02d.%02d.%04d", timeinfo->tm_mday, timeinfo->tm_mon + 1, timeinfo->tm_year + 1900);
  oled.setFont(u8g2_font_6x12_tf);
  oled.setCursor(0, 12);                            // Levý horní roh
  oled.print(dateStr);
}

// OLED: Zobrazí čas HH:MM:SS na střed s vlastním fontem
void drawCenteredTime(struct tm *timeinfo) {
  char timeStr[9];
  sprintf(timeStr, "%02d:%02d:%02d", timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec);

  oled.setFont(bdf_font);                           // Vlastní 7-segmentový font

  int textWidth = oled.getStrWidth(timeStr);
  int textHeight = 19;

  int x = (128 - textWidth) / 2;                    // Vodorovný střed
  int y = 64 + textHeight / 2 - textHeight;         // Korekce na střed výšky

  oled.setCursor(x, y);
  oled.print(timeStr);
}

// ======= Hlavní inicializace =======
void setup() {
  Serial.begin(115200);                             // Seriová konzole
  Wire.begin(14, 15);                               // I2C pro LOLIN S3 Mini
  oled.begin();                                     // Inicializace OLEDu
  oled.setI2CAddress(0x3C << 1);                    // Typická I2C adresa

  connectToWiFi();                                  // Připojit k síti

  //  Správné nastavení časové zóny (Evropa + letní čas)
  configTzTime("CET-1CEST,M3.5.0/2,M10.5.0/3", "pool.ntp.org");

  // Počkat na synchronizaci času
  while (time(nullptr) < 100000) {
    delay(100);
  }
}

// ======= Hlavní smyčka =======
void loop() {
  struct tm timeinfo;
  getLocalTime(&timeinfo);                          // Načti aktuální čas

  oled.clearBuffer();
  drawDate(&timeinfo);                              // Vykresli datum
  drawCenteredTime(&timeinfo);                      // Vykresli čas
  oled.sendBuffer();                                // Vykreslit do OLEDu

  delay(1000);                                      // Aktualizace každou sekundu
}

Tato stránka byla naposledy upravena 2025-12-30 12:53

Běží na Wiki|Docs

This page was last edited on 2025-12-30 12:53

Eduingo
info@eduingo.com

Běží na Wiki|Docs