ESP8266 with Touchscreen
The ILI9341 is a powerful and cost effective screen.
Here is a project with some suggestions on how the screen and touch functions can be managed. These make use of Bodmer’s splendid libraries.
This version goes into a 3d printed box along with a charger module and small LiPo battery. For this application, some serious sleep management is needed to keep the battery life reasonable.
The main challenges are :
– screen wiring and matching code.
– touch recognition
– display layout
Wiring
I used a socket for the ILI9341 and soldered directly to the Wemos 8266 to keep the unit as small as possible. The socket turned out to be a good idea since one of my screens turned out to be faulty.
Note that I have taken the liberty of driving the screen led directly from a Wemos output. This isn’t great practice, but the units all work. ( I have built several of these and they are reliable.)

IMPORTANT: Check the User_Setup.h file in the TFT_eSPI library. This may need adjustments to suit the wiring of the project. (Back up this file!) For the above setup, User_Setup.h needs the following information:
#define ILI9341_DRIVER #define TFT_CS PIN_D8 // Chip select control pin D8 #define TFT_DC PIN_D4 // Data Command control pin #define TFT_RST -1 // Set TFT_RST to -1 if the display RESET is #define TOUCH_CS PIN_D3
Otherwise the setup file is the same as generic ILI9314 in terms of Frequencies & Fonts.
Sample code for this setup features:
- Initialise graphics
- Simple text handling
- Menu example
- Touch recognition
- Initialise SPIFFS memory
- Display a JPG image from SPIFFS.



/*
ILI9341 and Wemos demo http://www.lecity.edu.au
Credit to Bodmer's TFT_eSPI library https://github.com/Bodmer/TFT_eSPI
*/
#include <FS.h> //needed for SPIFFS
#include "Free_Fonts.h" // Include the header file attached to this sketch
#include <SPI.h>
#include <TFT_eSPI.h> //Newer driver see https://github.com/Bodmer/TFT_eSPI Config in /Library User_Setup.h
#include <TJpg_Decoder.h>
#define FS_NO_GLOBALS
TFT_eSPI tft = TFT_eSPI();
bool tft_output(int16_t x, int16_t y, uint16_t w, uint16_t h, uint16_t* bitmap)
{
if ( y >= tft.height() ) return 0;
tft.pushImage(x, y, w, h, bitmap);
return 1;
}
String swVersion = __FILE__;
bool reLoad = true;
void setup(void) {
Serial.begin(115200);
if (!SPIFFS.begin()) {
Serial.println("SPIFFS initialisation failed!");
while (1) yield(); // Stay here twiddling thumbs waiting
}
pinMode(4, OUTPUT); // The pin needs to set to Output : HIGH screen on / LOW screen off // GPIO4 (D2) is connected to LED
digitalWrite(4, HIGH);
tft.begin();
tft.setRotation(0);
tft.fillScreen(TFT_BLACK);
tft.drawRect(5, 5, 235, 315, TFT_YELLOW);
tft.drawRect(8, 8, 227, 307, TFT_GREEN);
tft.setFreeFont(FSS12);
tft.setCursor(20, 35);
tft.setTextColor(TFT_YELLOW);
Serial.println("Loading the splash screen");
tft.setCursor(20, 70);
tft.println("TFT Touch Menu");
tft.setCursor(20, 105);
tft.setTextColor(0x5F59);
tft.println(swVersion);
/// Put Wifi, MQTT, httpGet , OTA init, EEPROM etc things in here too.
TJpgDec.setSwapBytes(true);
TJpgDec.setCallback(tft_output);
delay(2000);
}
///////////////////////////////// Main Loop //////////////////////////////////////
void loop() {
uint16_t x, y; // Init touch
if (reLoad) {
// delay(200);
mainMenu();
// delay(500); //Trying to avoid boot up crashes??
reLoad = false;
} else { // No longer firstLoad
if (tft.getTouch(&x, &y)) {
///////// Start 10 Buttons /////////
//Button 1/10
if (x > 0 && x < 40 && y > 161 && y < 304) {
mainMenu();
}
//Button 2/10
if (x > 0 && x < 40 && y > 0 && y < 142) {
Serial.println("Top right button!");
tft.fillScreen(TFT_BLACK);
// doAirCon things.....
tft.setCursor(20, 70);
tft.setTextColor(TFT_WHITE);
tft.println("Air Con menu etc");
delay(3000);
reLoad = true;
}
// Button 3/10
if (x > 48 && x < 86 && y > 161 && y < 304) {
appGallery();
reLoad = true;
}
/// Add other buttons as above.....
} /// end Touch
} /// end reLoad
}
void mainMenu() {
/////// 10 buttons Descriptions /////
tft.fillScreen(TFT_BLACK);
tft.setFreeFont(FSS12);
tft.setTextColor(TFT_WHITE);
tft.fillRect(0, 0, 118, 62, TFT_BLUE);
tft.setCursor(6, 45);
tft.println("Menu");
tft.setTextColor(TFT_WHITE);
tft.drawRect(120, 0, 118, 62, TFT_BLUE);
tft.setCursor(126, 45);
tft.println("AirCon");
tft.drawRect(0, 64, 118, 62, TFT_BLUE);
tft.setCursor(6, 110);
tft.println("Pictures");
tft.drawRect(120, 64, 118, 62, TFT_BLUE);
tft.setCursor(126, 110);
tft.println("4");
tft.drawRect(0, 128, 118, 62, TFT_BLUE);
tft.setCursor(6, 170);
tft.println("5");
tft.drawRect(120, 128, 118, 62, TFT_BLUE);
tft.setCursor(126, 170);
tft.println("6");
tft.drawRect(0, 192, 118, 62, TFT_BLUE);
tft.setCursor(6, 230);
tft.println("7");
tft.drawRect(120, 192, 118, 62, TFT_BLUE);
tft.setCursor(126, 230);
tft.println("8");
tft.drawRect(0, 256, 118, 64, TFT_BLUE);
tft.setCursor(6, 300);
tft.println("9");
tft.drawRect(120, 256, 118, 64, TFT_BLUE);
tft.setCursor(126, 300);
tft.println("10");
}
///// end 10 Buttons //////////
void appGallery() { /// Draws jpg from the SPIFFS ( 240wx320h px )
fs::Dir directory = SPIFFS.openDir("/");
tft.fillScreen(TFT_BLACK);
TJpgDec.drawFsJpg(0,0, "/bavo.jpg");
delay(5000);
}
Preparation:
Image(s) need to be prepared. Use jpg sized to 240x320px or smaller.
These need to uploaded to the SPIFFS memory:
- Create a folder called data in the sketch folder
- Use Arduino Tools > ESP8266 Data upload to send these images to the SPIFFS memory of the ESP.
Tip: Serial monitor may need to be disabled while uploading.
