.. _arduino_tft_clock: ============================ 1.7 TFT Digital Clock ============================ Display a ticking digital clock on the TFT LCD screen with the TFT_eSPI library. Overview ======== This example brings the onboard TFT LCD to life by rendering a watch-style digital clock. It draws a static bezel background once at startup, then updates the time display every second using a software clock. What You'll Learn ================= * Initializing the TFT display with ``TFT_eSPI`` * Drawing rectangles, rounded rectangles, and decorative lines * Using custom 7-segment fonts for digital clock displays * Simple software timekeeping with ``millis()`` Before You Begin ================ Complete the setup steps in :ref:`preparation` before continuing. .. note:: Use the recommended Arduino IDE settings in :ref:`arduino_board_settings` unless this lesson says otherwise. .. important:: The **TFT_eSPI** library must be configured for this board's display pins before this example will compile. A matching ``User_Setup.h`` is provided in the library ZIP. Open the example sketch from the code package: ``LAFVIN-ESP32-S3-Multimedia-Kit-main/1.Arduino/7.TFT_Watch/7.TFT_Watch.ino`` This example uses the **onboard** TFT LCD. No external wiring is required. Upload and Test =============== #. Connect the board with a USB Type-C data cable. #. Open ``7.TFT_Watch.ino`` in Arduino IDE. #. In the **Tools** menu, select ``ESP32S3 Dev Module`` as the board and choose the correct serial port. #. Click **Upload**. #. After uploading, the TFT screen shows a watch face with hours, minutes, and seconds. The time starts from the sketch's compile time and advances every second. The display layout: * White outer background * Dark grey rounded bezel frame * Light grey LCD face with decorative lines * ``HH:MM`` in large 7-segment font near the centre * ``SS`` in smaller size below * "LAFVIN" branding at the bottom How the Code Works ================== **Display Initialization** .. code-block:: cpp #include TFT_eSPI tft = TFT_eSPI(); tft.init(); tft.setRotation(0); // Portrait orientation tft.invertDisplay(true); // Correct colours for this panel **Drawing the Watch Face** The watch face is drawn once in ``setup()`` using filled rectangles, horizontal lines, and text labels. A dark bezel frame sits on a white background, with a lighter LCD face area inside. .. code-block:: cpp tft.fillScreen(TFT_WHITE); tft.fillRect(5, 40, 230, 220, WATCH_FRAME); tft.fillRect(15, 50, 210, 200, LCD_BACK_LIGHT); tft.drawFastHLine(20, 80, 200, TFT_BLUE); tft.drawFastHLine(20, 220, 200, TFT_BLUE); tft.setTextColor(LCD_TEXT_BLACK, LCD_BACK_LIGHT); tft.setTextDatum(TL_DATUM); tft.drawString("ALARM CHRONO", 20, 55, 2); tft.setTextDatum(TR_DATUM); tft.drawString("LIGHT", 220, 55, 2); tft.setTextDatum(MC_DATUM); tft.setTextColor(TFT_DARKGREY, TFT_WHITE); tft.drawString("LAFVIN", 120, 280, 4); **Software Clock** The initial time is parsed from the ``__TIME__`` compile-time macro using a ``conv2d()`` helper that extracts two-digit numbers from the ``"HH:MM:SS"`` string. The ``loop()`` increments seconds, minutes, and hours with carry, then redraws only the changed digits using font 7 (a 7-segment display font). .. code-block:: cpp static uint8_t conv2d(const char* p) { uint8_t v = 0; if ('0' <= *p && *p <= '9') v = *p - '0'; return 10 * v + *++p - '0'; } uint8_t hh = conv2d(__TIME__), mm = conv2d(__TIME__ + 3), ss = conv2d(__TIME__ + 6); void loop() { if (targetTime < millis()) { targetTime += 1000; ss++; if (ss == 60) { ss = 0; mm++; } if (mm > 59) { mm = 0; hh++; } if (hh > 23) { hh = 0; } String mainTime = hourStr + ":" + minStr; tft.setTextDatum(MC_DATUM); tft.drawString(mainTime, 120, 130, 7); tft.drawString(secStr, 120, 190, 7); } } In the provided sketch: * The watch face is drawn **once** in ``setup()`` and not redrawn * Only the changing time digits are updated in ``loop()`` * A 7-segment font (font 7) gives the clock an authentic digital-watch look * ``setTextDatum(MC_DATUM)`` centres the text horizontally and vertically at the given coordinate Try This Next ============= * Change ``tft.setRotation(0)`` to ``tft.setRotation(1)`` for a landscape clock * Add the date below the time using a smaller font * Replace ``__TIME__`` with an NTP-synced clock for real internet time (see :ref:`lvgl_wifi` for a Wi-Fi example)