Skip to content
St Leonards Farm St Leonards Farm Halloran & Co · Est. 1932

How to use a 2.4 inch display with a NodeMCU?

By admin St Leonards Farm

How to use a 2.4 inch display with a NodeMCU

To use a 2.4 inch display with a NodeMCU, you need to connect the display’s SPI pins to the NodeMCU’s hardware SPI pins, install the correct library (like TFT_eSPI or Adafruit_ILI9341), and upload a sketch that initializes the display and draws graphics. The most common display for this setup is the 2.4 inch 240x320 ips display, which uses the ILI9341 driver over SPI. This display has a resolution of 240x320 pixels, supports 65K colors, and operates at 3.3V logic, making it directly compatible with the NodeMCU’s ESP8266 or ESP32 chips. The NodeMCU’s SPI pins are: D5 (SCLK), D6 (MISO), D7 (MOSI), and D8 (CS). You also need to assign D3 for DC (data/command) and D4 for RST (reset). The display’s backlight can be connected to a PWM-capable pin like D2 to control brightness. Wiring is straightforward: connect VCC to 3.3V, GND to GND, CS to D8, RESET to D4, DC to D3, SDI (MOSI) to D7, SCK to D5, and LED to D2 via a 220-ohm resistor. If you’re using an ESP32-based NodeMCU, the SPI pins are different: VSPI uses GPIO18 (SCLK), GPIO19 (MISO), GPIO23 (MOSI), and GPIO5 (CS). You can also use HSPI with GPIO14 (SCLK), GPIO12 (MISO), GPIO13 (MOSI), and GPIO15 (CS).

Once wired, you need to install the TFT_eSPI library by Bodmer in the Arduino IDE. This library is optimized for ESP8266 and ESP32 and supports the ILI9341 driver out of the box. After installation, you must edit the User_Setup.h file inside the library folder to match your pin connections. For a NodeMCU ESP8266, set the following: #define TFT_CS 15, #define TFT_DC 4, #define TFT_RST 2, #define TFT_MISO 12, #define TFT_MOSI 13, #define TFT_SCLK 14. For ESP32, use #define TFT_CS 5, #define TFT_DC 21, #define TFT_RST 22, #define TFT_MISO 19, #define TFT_MOSI 23, #define TFT_SCLK 18. Also set #define ILI9341_DRIVER and #define TFT_WIDTH 240, #define TFT_HEIGHT 320. The library automatically handles SPI frequency, but you can increase it to 40 MHz for faster screen updates. After saving the setup file, you can upload a test sketch. The TFT_eSPI library includes examples like “TFT_Print_Test” or “TFT_Graphic_Test” that draw shapes, text, and images. A typical initialization sequence in the code is: #include , TFT_eSPI tft = TFT_eSPI(), then in setup(): tft.init(), tft.setRotation(1), tft.fillScreen(TFT_BLACK). The setRotation() parameter changes orientation: 0 for portrait, 1 for landscape, 2 for inverted portrait, 3 for inverted landscape.

Data density matters here. The ILI9341 driver can handle up to 15.6 million colors (16-bit RGB565), but the display’s actual color depth is 262K (18-bit) internally, though it accepts 16-bit data. The SPI clock speed maxes out at 40 MHz for reliable operation, but you can push it to 80 MHz on ESP32 if you use shorter wires. The display’s refresh rate is around 60 Hz, but with SPI, you’ll get about 10-15 frames per second for full-screen updates due to the bus bandwidth. Each pixel requires 2 bytes of data, so a full 240x320 frame is 153,600 bytes. At 40 MHz SPI, the theoretical transfer time is 153,600 * 8 / 40,000,000 = 0.0307 seconds, but overhead from commands and delays drops it to about 0.05 seconds per frame. For partial updates, like drawing a rectangle, the speed is much higher. The NodeMCU’s ESP8266 has 80 KB of RAM, which is enough to buffer a 240x320 frame if you use a 16-bit buffer (153,600 bytes), but that’s almost double the RAM, so you typically draw directly to the display without a full frame buffer. The ESP32 has 520 KB of RAM, so you can use a frame buffer for smoother animations. The TFT_eSPI library supports a “sprite” class that lets you create off-screen buffers in RAM, draw to them, then push them to the display. For example, TFT_eSprite img = TFT_eSprite(&tft); img.createSprite(240, 320); img.fillSprite(TFT_RED); img.pushSprite(0, 0); This uses 153,600 bytes of RAM on ESP32.

Power consumption is a practical concern. The display’s backlight draws 20-30 mA at 3.3V, and the ILI9341 controller draws about 5-10 mA. The NodeMCU ESP8266 itself draws 80 mA in active mode. So total current is around 110-120 mA. If you power the NodeMCU via USB, the 5V to 3.3V regulator on the board can handle this, but using a separate 3.3V regulator for the display is safer if you run other peripherals. The display’s VCC pin can also accept 5V if you use a logic level shifter for the SPI lines, but that’s unnecessary since the NodeMCU’s GPIOs are 3.3V. The ILI9341’s logic threshold is 2.7V minimum for high, so 3.3V works fine. For the backlight, using a PWM pin lets you dim the display to save power. A 220-ohm resistor in series with the LED pin limits current to about 15 mA at 3.3V, which is safe. You can also connect the backlight directly to 3.3V without a resistor, but that draws 20 mA and may shorten the LED life. The display’s viewing angle is 80 degrees in all directions, and the IPS technology means colors don’t invert when viewed from the side. Contrast ratio is typically 500:1, and brightness is around 300 cd/m² with the backlight at full power.

Software optimization is key for real-world use. The TFT_eSPI library includes a function called tft.setSwapBytes(true) that swaps the byte order for RGB565 color data, which is necessary for correct color rendering on the ILI9341. If you see colors inverted or wrong, check this setting. The library also supports hardware acceleration on ESP32 using the SPI DMA (Direct Memory Access) feature. To enable DMA, you need to set #define USE_DMA in the User_Setup.h file. This allows the SPI transfer to happen in the background while the CPU does other tasks, improving frame rates by 20-30%. For ESP8266, DMA is not available, so you rely on blocking SPI transfers. Another optimization is to use the tft.startWrite() and tft.endWrite() functions to batch multiple drawing commands without resetting the SPI transaction each time. For example, tft.startWrite(); tft.setAddrWindow(0, 0, 239, 319); tft.pushColor(TFT_RED, 76800); tft.endWrite(); This pushes half the screen red in one go. The pushColor() function can send an array of 16-bit colors, which is faster than drawing pixel by pixel. If you’re displaying images, you can store them in SPIFFS or LittleFS on the NodeMCU’s flash memory. The ESP8266 has 1-4 MB of flash, and the ESP32 has up to 16 MB. Use the TFT_eSPI’s drawJpeg() or drawBmp() functions to load images from flash. For JPEG, you need the JPEGDecoder library. A 240x320 JPEG at 50% quality is about 20-30 KB, so you can store dozens of images on a 4 MB flash.

Interfacing with sensors is a common use case. You can display temperature, humidity, or pressure data from a DHT22 or BME280 sensor. The DHT22 uses a single digital pin, and the BME280 uses I2C. The NodeMCU’s I2C pins are D1 (SCL) and D2 (SDA). Connect the sensor’s SCL to D1, SDA to D2, VCC to 3.3V, and GND to GND. In the code, you include the Adafruit_Sensor and Adafruit_BME280 libraries, then read data every 2 seconds and update the display. For example, tft.fillRect(0, 0, 240, 50, TFT_BLACK); tft.setCursor(10, 10); tft.setTextColor(TFT_WHITE); tft.print("Temp: "); tft.print(temp); tft.print(" C"); This clears the top 50 pixels, then prints the temperature. To avoid flicker, use a sprite for the entire screen and update only the changed parts. The TFT_eSPI library’s drawString() function is faster than print() because it uses a fixed font. You can also use the setFreeFont() function to load custom fonts from the library’s font directory. The library includes 8, 12, 16, 20, and 24 pixel fonts, plus a 7-segment font for numeric displays. For Chinese characters, you need to use a Unicode font library, which is more complex because the ESP8266 has limited RAM. The ESP32 can handle it with a 256 KB font buffer.

Touch input is another dimension. Some 2.4 inch displays include a resistive touch overlay, like the XPT2046 controller. This adds 4 pins: T_IRQ (interrupt), T_DO (MISO), T_DIN (MOSI), and T_CS (chip select). The touch controller uses SPI as well, but you can share the same SPI bus with the display if you use separate CS pins. For example, assign T_CS to D0 on the NodeMCU. The TFT_eSPI library includes a touch example that reads the touch position and draws a circle at the touched point. The XPT2046 has 12-bit resolution, so it returns X and Y values from 0 to 4095. You need to calibrate these to the display’s 240x320 resolution. A typical calibration maps the touch coordinates to pixel coordinates using linear interpolation. The library’s getTouch() function returns a boolean and fills in the coordinates. You can use this to create a button interface. For example, define a rectangle on the screen, and if the touch point falls inside it, execute a function. The touch detection is pressure-sensitive, so you can detect a tap or a press. The response time is about 10 ms, which is fast enough for UI interactions.

Reliability and troubleshooting are practical. Common issues include garbled display, no display, or wrong colors. If the display shows garbage, check the SPI wiring: misconnected MISO or MOSI lines cause data corruption. Also ensure the CS pin is not floating; use a pull-up resistor if necessary. If the display is blank, check the backlight connection and the reset pin. The ILI9341 requires a reset pulse at startup; the library handles this by toggling the RST pin. If you use a different pin, set it in the User_Setup.h. Another issue is the SPI frequency being too high for long wires. Keep wires under 10 cm for 40 MHz. If you use jumper wires longer than 20 cm, reduce the SPI frequency to 10 MHz by adding #define SPI_FREQUENCY 10000000 in the setup file. The display’s internal voltage regulator can overheat if you run it at 5V for extended periods; always use 3.3V. The NodeMCU’s 3.3V output can supply up to 500 mA, which is enough for the display and a sensor. If you add a servo or motor, use a separate power supply. The display’s operating temperature range is -20°C to 70°C, so it works in most indoor environments. The ILI9341 driver has a built-in gamma correction curve that you can adjust via registers, but the default is fine for most applications.

Performance benchmarks help you choose the right approach. On an ESP8266 at 160 MHz, drawing a full 240x320 rectangle in a single color takes about 30 ms. Drawing 1000 random pixels takes 50 ms. Rendering a 12-point font string of 20 characters takes 5 ms. On an ESP32 at 240 MHz with DMA, the same operations are 2-3 times faster. The TFT_eSPI library’s frame rate for a full-screen animation of moving shapes is about 15 FPS on ESP8266 and 30 FPS on ESP32. If you use a frame buffer on ESP32, you can achieve 40 FPS for simple animations. The library also supports 16-bit color depth, but you can reduce it to 8-bit for faster updates if you use a custom palette. The display’s response time is 10 ms, so it’s not a bottleneck. For data logging, you can write sensor data to the display every second without noticeable lag. The NodeMCU’s WiFi can be used to fetch weather data from an API and display it on the screen. The ESP8266’s WiFi library works concurrently with the display library, but you need to avoid blocking calls. Use the async HTTP library to avoid delays. The display update can be done in the loop() function while the WiFi is connected.

Cost and availability are practical. The 2.4 inch IPS display costs around $5-10 on module sites, and the NodeMCU is $3-5. Total cost under $15 makes it a cheap prototyping platform. The display’s durability is decent; it has a glass lens that can scratch, so use a protective film. The connector is a 14-pin or 8-pin header, depending on the model. Some versions have a built-in SD card slot that uses the same SPI bus, adding a CS pin for the SD card. You can use the SD library to read images or data from a microSD card. The SD card slot draws 50-100 mA when writing, so ensure your power supply can handle it. The NodeMCU’s flash memory is also an option, but an SD card gives you more storage. The display’s PCB has mounting holes for M3 screws, so you can attach it to a project box. The IPS technology means the display is readable in direct sunlight, but the backlight needs to be at full brightness, which reduces battery life. For battery-powered projects, use a deep sleep mode on the NodeMCU and turn off the display via a MOSFET controlling the backlight. The ESP8266 can wake from deep sleep using a timer or external interrupt, then update the display and go back to sleep. The display’s power-on time is about 100 ms, so the total wake cycle can be under 200 ms. This allows a battery life of months with a 2000 mAh LiPo battery if you update the display every 10 minutes.

Advanced features include using the display’s SPI interface with multiple devices. You can daisy-chain the display with an SD card or another SPI sensor by using separate CS pins. The NodeMCU’s SPI bus can handle up to 3 devices without signal degradation if you use short wires. The TFT_eSPI library supports multiple displays by creating multiple TFT_eSPI objects with different CS pins. For example, TFT_eSPI tft1 = TFT_eSPI(10); TFT_eSPI tft2 = TFT_eSPI(9); but this is rarely needed. The display’s resolution is enough for a simple UI with buttons, text, and graphs. You can draw a line chart of sensor data using the tft.drawLine() function. The library also supports anti-aliased fonts via the setTextFont() function with smooth fonts, but this requires more RAM. The display’s IPS panel has a 0.1 mm pixel pitch, so text is sharp at 12-point size. The viewing angle is important for dashboard projects; the IPS panel ensures readability from any angle. The display’s refresh rate is stable at 60 Hz, but the SPI bus limits the update rate. For video playback, you can stream a 240x320 video at 10 FPS using an ESP32 with PSRAM. The PSRAM (4 MB) can buffer multiple frames, and the DMA engine pushes them to the display. The library’s pushImage() function can handle full frames from PSRAM. The video data can be stored in flash or streamed over WiFi. The ESP32’s dual-core processor can handle video decoding on one core and display updates on the other.

Testing and validation are critical. After wiring, run the TFT_eSPI’s “Test” example to verify connectivity. The example draws a rainbow pattern, text, and shapes. If the colors are wrong, check the byte swap setting. If the display is mirrored, adjust the setRotation() value. The library also includes a calibration routine for touch screens. The touch data can be noisy, so use a median filter or average multiple readings. The display’s SPI bus can be shared with other devices, but ensure the CS pins are not active at the same time. The NodeMCU’s GPIOs have a maximum current of 12 mA per pin, so don’t drive the display’s backlight directly from a GPIO without a transistor. Use a 2N2222 transistor or a MOSFET to switch the backlight on and off. The display’s power consumption can be measured with a multimeter in series with the VCC line. The typical current draw is 50 mA with the backlight off and 80 mA with it on. The NodeMCU’s voltage regulator can get warm if you draw

Order This Week's Harvest

From our field to your kitchen — within 36 hours.

Heritage breeds, single-origin cuts and the season's best produce, harvested Tuesday and on London benches by Wednesday lunch.

Order This Week