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;
}
}