Проблема прорисовке символов на экране TFT LCD ST7789 (320x170)

Идея такова: Нужен таймер, при нажатие кнопка 1 стартовал таймер а при нажатие кнопку 2 таймер остановился. После остановки таймера если нажать кнопку 1 таймер возобновился с последнего значения когда остановился. На ESP8266 Node mcu загрузил скетч, но на экране мерцает все символы. Можно ли убрать мерцание чтобы работал как часы электронные?

#include <Wire.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ST7789.h>
#include <ESP8266WiFi.h>
#include <FS.h>
#include <LittleFS.h>
#include <RTClib.h>

// Определение пинов для кнопок управления таймером
#define BTN_START D6  // Кнопка запуска таймера (GPIO12)
#define BTN_PAUSE D0  // Кнопка паузы таймера (GPIO16)

// Определение пинов для TFT LCD 1.9" ST7789
#define TFT_CS    D8  // (GPIO15)
#define TFT_RST   D3  // (GPIO2)
#define TFT_DC    D4  // (GPIO0)
#define TFT_SCLK  D5  // (GPIO14)
#define TFT_MOSI  D7  // (GPIO13)

Adafruit_ST7789 tft = Adafruit_ST7789(TFT_CS, TFT_DC, TFT_RST);
RTC_DS3231 rtc;

// Переменные для таймера
bool timerRunning = false;
unsigned long startTime = 0;
unsigned long elapsedTime = 0;
DateTime rtcStartTime;
bool startPressed = false;
bool pausePressed = false;
unsigned long lastDisplayedTime = 0;

void setup() {
  pinMode(BTN_START, INPUT_PULLUP);
  pinMode(BTN_PAUSE, INPUT_PULLUP);

  tft.init(170, 320);
  tft.setRotation(1);
  tft.fillScreen(ST77XX_BLACK);
  tft.setTextColor(ST77XX_WHITE);
  tft.setTextSize(3);
  
  if (!rtc.begin()) {
    tft.setCursor(10, 30);
    tft.println("RTC ERROR!");
  }

  if (rtc.lostPower()) {
    rtc.adjust(DateTime(F(__DATE__), F(__TIME__)));
  }
}

void loop() {
  if (digitalRead(BTN_START) == LOW) {
    if (!startPressed) {
      startPressed = true;
      if (!timerRunning) {
        timerRunning = true;
        rtcStartTime = rtc.now();
        startTime = elapsedTime;
      }
    }
  } else {
    startPressed = false;
  }

  if (digitalRead(BTN_PAUSE) == LOW) {
    if (!pausePressed) {
      pausePressed = true;
      if (timerRunning) {
        timerRunning = false;
        elapsedTime = (rtc.now().unixtime() - rtcStartTime.unixtime()) * 1000 + startTime;
      }
    }
  } else {
    pausePressed = false;
  }

  static unsigned long lastDisplayUpdate = 0;
  if (millis() - lastDisplayUpdate >= 10) {
    lastDisplayUpdate = millis();
    unsigned long currentTime = timerRunning ? (rtc.now().unixtime() - rtcStartTime.unixtime()) * 1000 + startTime : elapsedTime;
    if (currentTime != lastDisplayedTime) {
      lastDisplayedTime = currentTime;
      displayTime(currentTime);
    }
  }
}

void displayTime(unsigned long timeMillis) {
  unsigned long seconds = (timeMillis / 1000) % 60;
  unsigned long minutes = (timeMillis / 60000) % 60;
  unsigned long hours = (timeMillis / 3600000) % 24;
  unsigned long days = (timeMillis / 86400000);
  
  tft.setCursor(10, 80);
  tft.setTextSize(4);
  tft.fillRect(10, 80, 400, 50, ST77XX_BLACK); // Очищаем только область текста
  tft.printf("%03lu:%02lu:%02lu:%02lu", days, hours, minutes, seconds);
}

Мерцает, видимо, потому что в строках 97,98 выводит все данные слишком часто. Надо реже и только те, что обновились - секунды,раз в секунду, минуты, раз в минуту и т.д.

Вопрос первый: каким образом первое утверждение связано со вторым?

Далее: “убрать мерцание” довольно трудно. Более рациональным представляется другой путь - не допускать мерцания.

1 лайк