↩ Alle projecten en sketches This page in English
ESP8266 · SPI · ST7789

ST7789 SPI-kleurendisplay: NTP-klok met ESP8266

ST7789 SPI-kleurendisplay (320x240px) aangesloten op een ESP8266
2 inch display op Amazon — 320×240px, hoge refresh rate

Een scherp kleurenscherm met hoge refresh rate, aangestuurd via TFT_eSPI — met WiFi-statusindicator en flikkervrije partiële updates.

Wat heb je nodig?

SPI-display ST7789 (320×240px) + ESP8266

Dit display heeft een resolutie van 320 × 240 pixels, en geeft een zeer scherp beeld. Het scherm heeft een hoge refresh rate, je zou — indien gewenst — honderdsten van een seconde kunnen weergeven. De snelste en meest veelzijdige bibliotheek voor dergelijke displays is TFT-eSPI (Bodmer). Er zijn talloze voorbeelden bij, analoge klokjes, fonts, sprites, verschillende metertjes, het spel "pong", grafieken en fractals.

De code bevat een 10-tal lijnen meer dan die van de e-paper, omdat we voor het synchronisatie-interval en de callback van de synchronisatiefuncties voorzien. Omdat de bibliotheek TFT_eSPI meerdere displays ondersteunt, moet je een bestandje "User_Setup.h" instellen (of een voorgedefinieerde setup kiezen uit de folder "User_Setups" van de bibliotheek TFT_eSPI).

Verbindingen:

ESP8266	|   2 inch Waveshare (ST7739V driver) | 2.4 inch Waveshare (ILI9341 driver)
===============================
GND	------- GND
3V3	------- VCC
D3	------- DC
RST	------- RST
D5	------- CLK
D7	------- DIN
D8	------- CS
        ------- BL (not connected - niet verbonden)

Sketch:

#include <WiFiManager.h>  // https://github.com/tzapu/WiFiManager/
#include <TFT_eSPI.h>     // https://github.com/Bodmer/TFT_eSPI
#include <coredecls.h>    // ESP8266 core

struct tm tInfo;  // https://cplusplus.com/reference/ctime/tm/
char days[7][10] = { "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday" };
byte previousHour = 24, previousMinute = 61, previousSecond;
String previousWeekDay;

TFT_eSPI tft = TFT_eSPI();
WiFiManager myWiFi;

void setup() {
  Serial.begin(115200);
  tft.init();
  tft.setRotation(1);
  tft.fillScreen(TFT_BLACK);  // clear screen from any previous session
  myWiFi.setAPCallback(showMessageNoConnection);
  myWiFi.autoConnect("ST7789_ESP");
  settimeofday_cb(esp8266NtpCallback);  // we need "#include <coredecls.h>" for this
  tft.fillScreen(TFT_BLACK);            // clear screen from "showMessageNoConnection" messages
  configTzTime(PSTR("CET-1CEST,M3.5.0,M10.5.0/3"), "be.pool.ntp.org");
  tft.setTextColor(TFT_CYAN);
  tft.setTextSize(2);
  tft.setCursor(117, 14, 7);
  tft.print(":");
}

void loop() {
  showChangesOnDisplay();
  WiFi.isConnected() ? showLogoWiFi(TFT_GREEN) : showLogoWiFi(TFT_RED);
}

void showTime(char timeChar[2], int leftS, int top, bool large) {
  tft.setCursor(leftS, top, 7);  // 7 is a built in font
  tft.setTextColor(TFT_CYAN, TFT_BLACK);
  tft.setTextSize(large + 1);
  tft.print(timeChar);
  tft.setTextSize(1);
}

void showChangesOnDisplay() {                             // this function divides the screen changes
  char hourChar[3], minChar[3], secChar[3], theDate[11];  // into chunks to prevent flicker
  getLocalTime(&tInfo);
  if (tInfo.tm_sec != previousSecond) {
    sprintf(secChar, "%02d", tInfo.tm_sec);  // format 2 digits decimal
    showTime(secChar, 256, 61, false);
    previousSecond = tInfo.tm_sec;
  }
  if (tInfo.tm_min != previousMinute) {
    sprintf(minChar, "%02d", tInfo.tm_min);
    showTime(minChar, 131, 14, true);
    previousMinute = tInfo.tm_min;
  }
  if (previousHour != tInfo.tm_hour) {
    sprintf(hourChar, "%02d", tInfo.tm_hour);
    showTime(hourChar, -2, 14, true);
    previousHour = tInfo.tm_hour;
     if (previousWeekDay != days[tInfo.tm_wday]) {
      tft.fillRect(0, 134, 320, 106, TFT_BLACK);
      tft.setTextColor(TFT_YELLOW);
      tft.setFreeFont(&FreeSansBold24pt7b);  // custom font. &FreeMonoBold24pt7b is possible too
      tft.drawCentreString(days[tInfo.tm_wday], 160, 136, 1);
      tft.drawRoundRect(0, 124, 320, 70, 3, TFT_WHITE);
      tft.setTextColor(TFT_GREEN);
      strftime(theDate, sizeof(theDate), "%d-%m-%G", &tInfo);
      tft.drawCentreString(theDate, 160, 202, 1);
      tft.setTextFont(7);
      previousWeekDay = days[tInfo.tm_wday];
    }
  }
}

void showLogoWiFi(int myColor) {
  tft.fillCircle(294, 30, 6, myColor);
  for (byte tel = 0; tel < 3; tel++) {
    tft.drawSmoothArc(294, 32, 30 - tel * 7, 28 - tel * 7, 135, 225, myColor, myColor, true);
  }
}

void showMessageNoConnection(WiFiManager* myWiFi) {
  tft.setCursor(0, 0, 4);
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.print(F("\nWiFi: no connection\nConnect to hotspot:\n"));
  tft.print(F("ST7789_ESP and open\na browser at address \n192.168.4.1\n"));
  tft.print(F("to enter network name\nand password"));
}

void esp8266NtpCallback(bool from_sntp) {  // in setup: "settimeofday_cb(esp8266NtpCallback)";
  if (from_sntp) Serial.printf("\n*** NTP Sync ***\n%s \n", getenv("TZ"));
}

uint32_t sntp_update_delay_MS_rfc_not_less_than_15000() {  // declare only, unnecessary to call this function
  return 4 * 60 * 60 * 1000UL;                             // SNTP sync every 4 hr
}

Je vindt bij de voorgedefinieerde "User_Setups" de meest voorkomende configuraties. Bijvoorbeeld de "Setup18_ST7789.h" in deze folder is bruikbaar voor dit project. Moesten de weergegeven kleuren niet kloppen (rood en groen verwisseld: ligt eigenlijk aan de hardwarefabrikanten), dan kan je de 3de lijn actief zetten en de 4de lijn uitcommenten:

//            ST7789
#define USER_SETUP_INFO "User_Setup"
#define ST7789_DRIVER 
// #define TFT_RGB_ORDER TFT_RGB  // Colour order Red-Green-Blue
#define TFT_RGB_ORDER TFT_BGR  // Colour order Blue-Green-Red
#define TFT_HEIGHT 320 // ST7789 240 x 320
#define TFT_CS   PIN_D8  // Chip select control pin D8
#define TFT_DC   PIN_D3  // Data Command control pin
#define TFT_RST  -1    // Set TFT_RST to -1 if the display RESET is connected to NodeMCU RST or 3.3V
// fonts die je niet gebruikt best uitcommenten om FLASH te besparen
#define LOAD_GLCD   // Font 1. Original Adafruit 8 pixel font needs ~1820 bytes in FLASH
#define LOAD_FONT2  // Font 2. Small 16 pixel high font, needs ~3534 bytes in FLASH, 96 characters
#define LOAD_FONT4  // Font 4. Medium 26 pixel high font, needs ~5848 bytes in FLASH, 96 characters
#define LOAD_FONT6  // Font 6. Large 48 pixel font, needs ~2666 bytes in FLASH, only characters 1234567890:-.apm
#define LOAD_FONT7  // Font 7. 7 segment 48 pixel font, needs ~2438 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8  // Font 8. Large 75 pixel font needs ~3256 bytes in FLASH, only characters 1234567890:-.
#define LOAD_FONT8N // Font 8. Alternative to Font 8 above, slightly narrower, so 3 digits fit a 160 pixel TFT
#define LOAD_GFXFF  // FreeFonts. Include access to the 48 Adafruit_GFX free fonts FF1 to FF48 and custom fonts

#define SPI_FREQUENCY  27000000
#define SPI_READ_FREQUENCY  20000000
#define SPI_TOUCH_FREQUENCY  2500000
TFT_eSPI — opgelet Om hier een gemakkelijk overzicht weer te geven passen we de inhoud van het bestand "User_Setup.h" aan. Dat is een snelle oplossing als je 1 scherm aan de praat wil krijgen en vlug resultaat wil zien.

Als je meerdere displays gebruikt en/of geen gegevens wil verliezen als je een nieuwe kopij van deze bibliotheek installeert, kan je beter de tip volgen van de ontwerper van de bibliotheek: github.com/Bodmer/TFT_eSPI/#tips.

Je kan de volledige inhoud van "User_Setup.h" uitcommenten als je zo werkt.

De weekdag "vrijdag" wordt op beide displays weergegeven in dezelfde grootte en in exact hetzelfde lettertype. Je kan dat ook gewoon lezen in de code voor beide klokjes. Omdat het TFT-display een veel hogere resolutie heeft — vooral in de hoogte — zie je toch grote verschillen: 250×128 px versus 320×240 px.

Vergelijking van de weekdagweergave op het TFT-display en het e-paper display

Op het Arduino forum kan je zien hoe 3 prominente ontwikkelaars van bibliotheken (waarvan 2 bibliotheken hier gebruikt worden) elkaar verder helpen. Zo moet het! Kennis moet je delen, niet voor jezelf houden.

Meer displays met de ESP8266 / ESP32

Benieuwd naar andere displays? Bekijk het volledige overzicht met o.a. TM1637, SSD1306, SH1106, ST7735, e-paper en geïntegreerde displays zoals de Lilygo T-Display en de Waveshare ESP32-S3.