ESP32/ESP8266 drives 1.8″tft_oled screen imitation digital tube clock based on Arduino framework


ESP32/ESP8266 drives 1.8″tft_oled screen imitation digital tube clock based on Arduino framework

  • Related article “ESP32 drives I2C OLED time display based on U8g2 under Arduino framework”
  • Effect demonstration:
  • The screen display part uses the TFT_eSPI library driver and uses the unique font display that comes with the library.
  • The screen adopts 128*160 1.8″tft_Oled screen.
  • This project has only been verified on esp32, and there should be no problem displaying it on esp8266.
? Mainly to be familiar with the use of the screen driver display library, combined with the use of the network to obtain time as display content.

Required libraries

  • All dependent libraries can be searched in the Arduino IDE management library and installed directly.
  • TFT_eSPI (screen driver display)
  • NTPClient (get network time)

?Notes

  • After installing the library, you need to manually modify the User_Setup.h configuration in the TFT_eSPI library directory. Modify according to the screen you use.
    • If it is esp32: (The pins can be set according to personal usage)
// For ESP32 Dev board (only tested with GC9A01 display)
// The hardware SPI can be mapped to any pins

#define TFT_MOSI 23 // In some display driver board, it might be written as "SDA" and so on.
#define TFT_SCLK 18
#define TFT_CS 5 // Chip select control pin
#define TFT_DC 19 // Data Command control pin
#define TFT_RST 21 // Reset pin (could connect to Arduino RESET pin)
#define TFT_BL 22 // LED back-light
  • The following parameters are adapted according to the screen model and display effect.
// For ST7735 ONLY, define the type of display, originally this was based on the
// color of the tab on the screen protector film but this is not always true, so try
// out the different options below if the screen does not display graphics correctly,
// e.g. colors wrong, mirror images, or stray pixels at the edges.
// Comment out ALL BUT ONE of these options for a ST7735 display driver, save this
// this User_Setup file, then rebuild and upload the sketch to the board again:

 //#define ST7735_INITB
// #define ST7735_GREENTAB
// #define ST7735_GREENTAB2
// #define ST7735_GREENTAB3
// #define ST7735_GREENTAB128 // For 128 x 128 display
// #define ST7735_GREENTAB160x80 // For 160 x 80 display (BGR, inverted, 26 offset)
// #define ST7735_ROBOTLCD // For some RobotLCD arduino shields (128x160, BGR, https://docs.arduino.cc/retired/getting-started-guides/TFT)
// #define ST7735_REDTAB
 #define ST7735_BLACKTAB
// #define ST7735_REDTAB160x80 // For 160 x 80 display with 24 pixel offset

// If colors are inverted (white shows as black) then uncomment one of the next
// 2 lines try both options, one of the options should correct the inversion.

 #define TFT_INVERSION_ON
// #define TFT_INVERSION_OFF

– If it is esp8266

// For NodeMCU - use pin numbers in the form PIN_Dx where Dx is the NodeMCU pin designation
#define TFT_CS PIN_D8 // Chip select control pin D8
#define TFT_DC PIN_D3 // Data Command control pin
#define TFT_RST PIN_D4 // Reset pin (could connect to NodeMCU RST, see next line)
//#define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V

//#define TFT_BL PIN_D1 // LED back-light (only for ST7789 with backlight control pin)
//#define TOUCH_CS PIN_D2 // Chip select pin (T_CS) of touch screen

SDA ---- D7
SCL----D5
CS----D8
DC----D3
BL ---- 3.3V
RST ---- D4 or 3.3v

Program code

/*
 An example digital clock using a TFT LCD screen to show the time.
 Demonstrates use of the font printing routines. (Time updates but date does not.)
 
 For a more accurate clock, it would be better to use the RTClib library.
 But this is just a demo.
 
 This examples uses the hardware SPI only. Non-hardware SPI
 is just too slow (~8 times slower!)
 
 Based on clock sketch by Gilchrist 6/2/2014 1.0
 Updated by Bodmer
A few color codes:
 
code color
0x0000 Black
0xFFFFWhite
0xBDF7 Light Gray
0x7BEF Dark Gray
0xF800Red
0xFFE0 Yellow
0xFBE0 Orange
0x79E0 Brown
0x7E0 Green
0x7FF Cyan
0x1F Blue
0xF81F Pink

 */
#ifdef ESP32
#include <WiFi.h>
#else
#include <ESP8266WiFi.h>
// #include <WiFiClient.h>//New in 3.0.2
// #include <ESP8266HTTPClient.h>
#endif
// Get network time related libraries
#include <NTPClient.h>
#include <WiFiUdp.h>//esp32/esp8266 core firmware comes with
#include <SPI.h>
//screen display
#include <TFT_eSPI.h> // Graphics and font library for ST7735 driver chip
#include <SPI.h>

#define SERIAL_DEBUG //Whether to enable serial port debugging information output

TFT_eSPI tft = TFT_eSPI(); // Invoke library, pins defined in User_Setup.h
TFT_eSprite sprite = TFT_eSprite( & amp;tft); // Create double buffer

//Define a string array
const char weekdays_en[][4] = {<!-- --> "Sun", "Mon", "Tue", "Wed", "Thu", "Fri ", "Sat" };

//Network time related definitions
const char *ssid = "#######"; // Fill in the WiFi account
const char *password = "********"; // WiFi password
WiFiUDP ntpUDP;
NTPClient timeClient(ntpUDP, "ntp.aliyun.com"); // NTP server address

uint32_t targetTime = 0; // for next 1 second timeout
//Define time variables
int16_t currentYear = 0;
int16_t currentWeekDay = 0;
int16_t currentMonth = 0;
int16_t currentMonthDay = 0;
int16_t currentHour = 0;
int16_t currentMin = 0;
int16_t currentSec = 0;

byte omm = 99;
bool initial = 1;
byte xcolon = 0;
unsigned int color = 0;
uint8_t ss,mm;
void updateTime();

void setup(void) {<!-- -->

#ifdef SERIAL_DEBUG
  Serial.begin(115200); // Initialize serial communication, baud rate is 115200
#endif
  // ===Network time initialization setting===
  // Connect to WiFi
  WiFi.begin(ssid, password);
  while (WiFi.status() != WL_CONNECTED) {<!-- --> // Wait for WiFi connection to be successful
    delay(500);
#ifdef SERIAL_DEBUG
    Serial.print(".");
#endif
  }
  timeClient.begin(); //Initialize NTPClient
  timeClient.setTimeOffset(28800); // Time zone setting, time offset is 28800 seconds (8 hours)
  // ===TFT initialization settings===
  tft.begin(); //Initialize display register
  tft.setRotation(1); //Set the display rotation angle (0 means no rotation, adjust as needed) 0, 1, 2, 3 represent 0°, 90°, 180°, 270° respectively, 4 can be set to mirror .
  sprite.setColorDepth(16); //Set color depth (according to your needs)
  sprite.setSwapBytes(true); //Set the byte order and convert RGB color order to BGR to display colors correctly.
  sprite.createSprite(160, 128); // Create a 128x160 pixel drawing window
  sprite.fillScreen(TFT_BLACK);

  sprite.setTextColor(TFT_YELLOW, TFT_BLACK); // Note: the new fonts do not draw the background color
  updateTime();//Update once
  targetTime = millis() + 1000;
}

void loop() {<!-- -->
  if (targetTime < millis()) {<!-- -->
    targetTime = millis() + 1000;
    updateTime();
    byte Sec_Point = 82;
    if (ss != currentSec) {<!-- -->
      ss = currentSec; // Advance second
      sprite.setTextColor(TFT_GREEN, TFT_BLACK);
      // sprite.setCursor (8, 110);
      //sprite.println(timeClient.getFormattedTime());
      char buffer2[11];
      // sprite.printf(" d- d- d", currentYear, currentMonth, currentMonthDay);//Display date
      sprintf_P(buffer2, " d- d- d", currentYear, currentMonth, currentMonthDay);
      sprite.drawString(buffer2, 16, 105, 4); //Display date
      sprite.setTextColor(TFT_BLUE, TFT_BLACK); //Orange
      //sprite.setTextColor(0xF81F, TFT_BLACK); // Pink
      // sprite.drawCentreString("",120,48,2); // (center)Next size up font 2
      sprite.drawString(weekdays_en[currentWeekDay], 8, 64, 4); //Draw a string and print the day of the week
      sprite.pushSprite(0, 0);
      // sprite.setTextColor(0xFBE0); // Orange
      sprite.setTextColor(TFT_GREEN, TFT_BLACK);
      if (currentSec < 10) {<!-- -->//Display seconds
        Sec_Point + =sprite.drawChar('0', Sec_Point, 50, 7);
      }
      sprite.drawNumber(currentSec, Sec_Point, 50, 7); //Display seconds
      sprite.pushSprite(0, 0);
    }

    // Update digital time
    byte xpos = 6;
    byte ypos = 0;
    if (omm != currentMin) {<!-- --> // Only redraw every minute to minimize flicker
      sprite.setTextColor(0x39C4, TFT_BLACK); // Leave a 7 segment ghost image, comment out next line!
      // Font 7 is to show a pseudo 7 segment display.
      // Font 7 only contains characters [space] 0 1 2 3 4 5 6 7 8 9 0 : .
      sprite.drawString("88:88", xpos, ypos, 7); // Overwrite the text to clear it
      sprite.setTextColor(0xFBE0); // Orange
      omm = currentMin;

      if (currentHour < 10) xpos + = sprite.drawChar('0', xpos, ypos, 7);
      xpos + = sprite.drawNumber(currentHour, xpos, ypos, 7); //When displaying
      sprite.pushSprite(0, 0);
      xcolon = xpos;
      xpos + = sprite.drawChar(':', xpos, ypos, 7);
      if (currentMin < 10) xpos + = sprite.drawChar('0', xpos, ypos, 7);
      sprite.drawNumber(currentMin, xpos, ypos, 7); //Display points
      sprite.pushSprite(0, 0);
    }

    if (ss % 2) {<!-- --> // Flash the colon
      sprite.setTextColor(0x39C4, TFT_BLACK); //Font color
      xpos + = sprite.drawChar(':', xcolon, ypos, 7);
      sprite.pushSprite(0, 0);

    } else {<!-- -->
      sprite.drawChar(':', xcolon, ypos, 7);
      sprite.pushSprite(0, 0);
      // Erase the old text with a rectangle, the disadvantage of this method is increased display flicker
      sprite.fillRect(0, 64, 160, 20, TFT_BLACK);//Region clearing
    }
  }
}

void updateTime() {<!-- -->
  timeClient.update(); // Update time information
  unsigned long epochTime = timeClient.getEpochTime(); // Get the timestamp of the current time
#ifdef ESP32
  struct tm *ptm = gmtime((time_t *) & epochTime); // Convert timestamp to tm structure
#else
  time_t ntpTime = (time_t)epochTime;
  struct tm *ptm = localtime( & amp;ntpTime); // Convert timestamp to tm structure
#endif
  //Convert epochTime to years, months and days
  currentYear = ptm->tm_year + 1900; // Get the year
  currentMonth = ptm->tm_mon + 1; // Get the month
  currentMonthDay = ptm->tm_mday; // Get the day of the month
#ifdef ESP32
  currentWeekDay = ptm->tm_wday; // Get the day of the week
  if (currentWeekDay < 0) {<!-- -->
    currentWeekDay + = 7; // Convert negative numbers to positive numbers
  }
  currentHour = ptm->tm_hour; // when getting
  currentMin = ptm->tm_min; // Get points
  currentSec = ptm->tm_sec; // Get seconds
#else
  currentHour = timeClient.getHours(); // when getting
  currentMin = timeClient.getMinutes(); // Get minutes
  currentSec = timeClient.getSeconds(); // Get seconds
  currentWeekDay = timeClient.getDay(); // Get the day of the week
#endif
#ifdef SERIAL_DEBUG
  // Print Time
  Serial.println("Epoch Time: " + String(epochTime)); // Print timestamp
  Serial.println(timeClient.getFormattedTime()); // Print time format
  Serial.printf("NTP Time: d- d- d\\
", currentYear, currentMonth, currentMonthDay);
#endif
}