ESP32 a ILI9143 TFT displej

09.05.2023 Arduino #esp32 #tft

Rychlý příklad jak kompletně zapojit ESP32 s TFT dotykovým displej a vypsat na něm libovolný text.


ILI9341 je 262 144 barevný jednočipový SOC ovladač pro TFT displej z tekutých krystalů s rozlišením 320x240 pixelů.

ILI9341 může pracovat s napětím rozhraní 1,65V ~ 3,3VI/O a integrovaným sledovacím obvodem napětí pro generování úrovní napětí pro řízení LCD.

Zobrazovací modul použitý v tomto projektu má vestavěné dotykové rozhraní se slotem pro čtečku karet SD, který lze použít ke čtení dat z karty SD.

Piny ILI9341

  • VIN: Napájení modulu – 3,3-5 V
  • GND: Zem
  • RST: reset LCD
  • CS: Signál výběru čipu LCD, povolení nízké úrovně
  • D/C: Signál výběru dat
  • MOSI: SPI sběrnice zápis datový signál
  • SCK: Hodinový signál sběrnice SPI
  • LED: Ovládání podsvícení
  • T_CLK: Dotkněte se hodinového signálu sběrnice SPI
  • T_CS: Signál výběru čipu dotykové obrazovky, povolení nízké úrovně
  • T_DIN: Dotkněte se vstupu sběrnice SPI
  • T_DO: Dotkněte se vstupu sběrnice SPI
  • T_IRQ: Signál přerušení dotykové obrazovky, nízká úroveň při detekci dotyku
  • SD-MOSI: SPI sběrnice zápis datový signál
  • SD-MISO: SPI sběrnice čte datový signál, pokud nepotřebujete funkci čtení, nemůžete ji připojit
  • SD-SCK: Hodinový signál sběrnice SPI
  • SD-CS: Signál výběru čipu pro protokol SPI (SD karta)

Zapojení ESP32 a displeje

ESP 32 (LPKIT) TFT displej
3V3 Vcc
GND GND
D15 CS
D4 RST
D2 DC
D23 MOSI
D18 SCK
3V3 LED
D19 MISO
D18 T_CLK
D5 T_CS
D23 T_DIN
D19 T_DO
T_IRQ

 

Zdrojový kód

Pro řízení displeje ILI9341 lze využít oblíbenou knihovnu TFT_eSPI, která poskytuje nástroje pro všechny funkce displeje.

Ve složce knihovny TFT_eSPI se musí provést nastavení pro konkrétní displej. V souboru User_Setup_Select.h odkomentujte řádek:

#include <User_Setups/Setup42_ILI9341_ESP32.h>           // Setup file for ESP32 and SPI ILI9341 240x320

Jedná se o přednastavení souboru pro použitý displej.

Výkonný zdrojový kód je pak velmi jednoduchý.

#include <SPI.h>
#include <TFT_eSPI.h>

TFT_eSPI tft = TFT_eSPI(240, 320);  // Invoke custom library

void setup(void){
  tft.init();  
  tft.setRotation(1);                     // Set the screen in Landscape
  tft.fillScreen(TFT_BLACK); 

  tft.setTextColor(TFT_WHITE, TFT_BLACK); // Set the font colour to be white with a black background
  tft.setCursor(0, 0, 4);                 // Set "cursor" at top left corner of display (0,0) and select font 4
  tft.println("Initialised default\n");
  tft.println("White text");
  tft.setTextColor(TFT_RED, TFT_BLACK);
  tft.println("Red text");
  tft.setTextColor(TFT_GREEN, TFT_BLACK);
  tft.println("Green text");
  tft.setTextColor(TFT_BLUE, TFT_BLACK);
  tft.println("Blue text");
  delay(5000);

  tft.setTextColor(TFT_WHITE, TFT_BLACK); // Set the font colour to be white with a black background
}

void loop()
{
  // Binary inversion of colors
  tft.invertDisplay(true); // Where is true or false
  tft.setCursor(0, 0, 4);
  tft.println("Invert ON                  \n");
  delay(1000);

  // Normal colors
  tft.invertDisplay(false); // Where is true or false
  tft.setCursor(0, 0, 4);
  tft.println("Invert OFF                  \n");
  delay(1000);
}

Dotyková vrstva

Příklad vykresluje tlačítko u prostřed displeje. Při stisknutí tlačítka se na sériovém monitoru zobrazí odpovídající zpráva a tlačítko na 10 sekund zmizí.

#include "Arduino.h"
#include <Wire.h>
#include <SPI.h>
#include <TFT_eSPI.h>
#include <TFT_eWidget.h>

TFT_eSPI tft = TFT_eSPI(240, 320);

#define CALIBRATION_FILE "/TouchCalData1"
#define REPEAT_CAL false

ButtonWidget btn = ButtonWidget(&tft);

#define BUTTON_W 100
#define BUTTON_H 100

ButtonWidget* btnArr[] = {&btn};;
uint8_t buttonCount = sizeof(btnArr) / sizeof(btnArr[0]);

unsigned long previousMillis = 0;
const long interval = 50;
unsigned long previousMillisForView = 0;
const long intervalForView=5000;

void btn_releaseAction(void)
{
  static uint32_t waitTime = 1000;
  if (btn.justReleased()) {
    Serial.println("Left button just released");
    btn.drawSmoothButton(false);
    btn.setReleaseTime(millis());
    tft.fillScreen(TFT_BLACK); 
    waitTime = 10000;
  }
  else {
    if (millis() - btn.getReleaseTime() >= waitTime) {
      waitTime = 1000;
    }
  }
}

void btn_pressAction(void)
{
  if (btn.justPressed()) {
    Serial.println("Left button just pressed");
    btn.drawSmoothButton(true);
  }
}

void initButtons() {
  uint16_t x = (tft.width() - BUTTON_W) / 2;
  uint16_t y = (tft.height() - BUTTON_H)  / 2;
  btn.initButtonUL(x, y, BUTTON_W, BUTTON_H, TFT_WHITE, TFT_GREEN, TFT_BLACK, "Press", 1);
  btn.setPressAction(btn_pressAction);
  btn.setReleaseAction(btn_releaseAction);
  btn.drawSmoothButton(false, 2, TFT_BLACK); // 3 is outline width, TFT_BLACK is the surrounding background colour for anti-aliasing
}

void setup() {

// Display  
  Serial.begin(115200);
  tft.init();  
  tft.setRotation(1);                     // Set the screen in Landscape
  tft.setTextWrap(true);
  tft.fillScreen(TFT_BLACK); 

  tft.setTextColor(TFT_WHITE, TFT_BLACK); // Set the font colour to be white with a black background
  tft.setCursor(0, 0, 4);                 // Set "cursor" at top left corner of display (0,0) and select font 4
  tft.println("Initialising ...\n");
  delay(1000);
  tft.fillScreen(TFT_BLACK); 

  initButtons();
}

void loop() {
  uint16_t t_x = 9999, t_y = 9999;
  unsigned long currentMillisForView = millis();
  if (currentMillisForView - previousMillisForView >= intervalForView) {
    initButtons();
    previousMillisForView = currentMillisForView;
  }

  unsigned long currentMillis = millis();
  if (currentMillis - previousMillis >= interval) {
    bool pressed = tft.getTouch(&t_x, &t_y);
    for (uint8_t b = 0; b < buttonCount; b++) {
      if (pressed) {      
        if (btnArr[b]->contains(t_x, t_y)) {
          btnArr[b]->press(true);
          btnArr[b]->pressAction();
        }
      }
      else {
        btnArr[b]->press(false);
        btnArr[b]->releaseAction();
      }
    }
    previousMillis = currentMillis;
  }
  
}