Skip to content
Lyme Regis Arts Festival Jurassic Coast · Est. 2007

How to display an image on a 1.14 inch 240x135 screen?

By admin ·

To display an image on a 1.14 inch 240x135 screen, you need to interface it with a microcontroller like an ESP32 or STM32 using the SPI protocol, initialize the display driver (typically ST7789 or similar), convert your image to a raw RGB565 byte array, and send that data via SPI to the screen’s frame buffer. The key is understanding the pixel format and timing constraints. For a 240x135 resolution, each pixel is represented by 16 bits (2 bytes) in RGB565 format, meaning the entire image buffer is 240 * 135 * 2 = 64,800 bytes. This is a manageable size for most modern microcontrollers, but you must ensure your SPI clock speed is high enough to refresh the display smoothly—typically 20 MHz to 40 MHz for a 60 Hz refresh rate. The display module itself uses a 4-wire SPI interface (CS, DC, MOSI, SCK) plus a reset pin, and it operates at 3.3V logic levels. If you’re using a 5V MCU, you’ll need level shifters. The controller chip inside the 1.14 inch 240x135 ips display is often the ST7789V, which supports 16-bit color depth and has a built-in frame buffer of 240x135 pixels. The display’s refresh rate is typically 60 Hz, but you can push it to 90 Hz with careful SPI timing. The pixel clock for a 60 Hz refresh is 240 * 135 * 60 = 1,944,000 pixels per second, or about 3.888 MB/s data rate. With an SPI clock of 40 MHz, you can achieve 5 MB/s, leaving headroom for other tasks.

When you’re coding the image display, the first step is to initialize the display driver. The ST7789 requires a sequence of commands: SWRESET (0x01), SLPOUT (0x11), COLMOD (0x3A) set to 0x05 for 16-bit color, DISPON (0x29), and then set the memory data access control (MADCTL, 0x36) to match your orientation. For a 240x135 screen, the default orientation is portrait, but if you want landscape, you’ll need to set MADCTL to 0x70 (which flips the X and Y axes). The display’s physical dimensions are 14.7 mm x 28.7 mm, with a pixel pitch of 0.114 mm. The viewing angle is typically 160 degrees in all directions, thanks to the IPS technology. The contrast ratio is around 800:1, and the brightness is usually 300 cd/m². These specs are important if you’re designing for outdoor use or high ambient light. The display consumes about 20 mA at 3.3V when active, which is low enough for battery-powered projects.

To convert an image for the display, you need to extract the raw pixel data. Most image editing tools (like GIMP or Photoshop) can export as C source code or raw binary. For a 240x135 image, you’ll typically get a 64,800-byte array. If you’re using a compressed format like JPEG, you’ll need to decode it on the MCU, which adds complexity. A simpler approach is to use a tool like ImageMagick to convert to RGB565: convert input.jpg -resize 240x135 -depth 8 -colorspace sRGB -define bayer:pattern=rgbrgbrgbrgb -define bayer:scale=2 -define bayer:order=2 -define bayer:width=240 -define bayer:height=135 -define bayer:offset=0 -define bayer:type=rgb565 output.raw. The raw file can then be included in your firmware as a const array. For example, in Arduino IDE, you can use PROGMEM to store it in flash memory: const uint16_t image_data[] PROGMEM = { ... };.

When sending the data, you must set the display’s window address. The ST7789 uses CASET (0x2A) for column address and RASET (0x2B) for row address. For a 240x135 screen, the column range is 0 to 239, and the row range is 0 to 134. After setting the window, you send the RAMWR command (0x2C), followed by the pixel data. Each pixel is two bytes, with the first byte being the high byte (bits 15-8: R[4:0], G[5:3]) and the second byte being the low byte (bits 7-0: G[2:0], B[4:0]). The byte order is big-endian, but some libraries expect little-endian, so check your driver’s documentation. The SPI transaction should be atomic: pull CS low, send command byte, send data bytes, then pull CS high. The DC pin is used to differentiate between command (DC=0) and data (DC=1).

Performance is critical for smooth animation. If you’re displaying a static image, you can send the entire buffer at once, which takes about 12.96 ms at 40 MHz SPI (64,800 bytes * 8 bits / 40,000,000 = 0.01296 seconds). But if you’re updating partial regions, you can use the display’s partial update mode. The ST7789 supports partial display mode with commands like PTLAR (0x30) and VSCRDEF (0x33). For example, to update only a 100x100 region, you set CASET to 100 to 199 and RASET to 0 to 99, then send only 20,000 bytes. This reduces SPI traffic by 69%. The display’s response time is 2.5 ms (typical), which is fast enough for 60 FPS updates. If you’re using a microcontroller with DMA, you can offload the SPI transfer to the background, freeing the CPU for other tasks.

Another consideration is the display’s backlight. The 1.14 inch screen typically has a white LED backlight with a forward voltage of 3.0V to 3.3V and a current of 20 mA. You can control brightness via PWM on the backlight pin. A 10-bit PWM at 1 kHz is sufficient for smooth dimming without flicker. The backlight’s maximum brightness is 300 cd/m², but you can reduce it to 50 cd/m² for low-power modes. The display’s power consumption scales linearly with backlight brightness: at 50% duty cycle, the backlight draws about 10 mA, and the total system current is around 15 mA. If you’re using a battery, you can also turn off the display entirely by pulling the backlight pin low and putting the ST7789 into sleep mode (SLPIN command 0x10). In sleep mode, the display draws less than 5 µA.

For image quality, the IPS panel offers consistent color reproduction across viewing angles. The color gamut is typically 60% of the NTSC standard, which is adequate for most icons and text. The 240x135 resolution at 1.14 inches gives a pixel density of 247 PPI (pixels per inch), which is sharp enough for readable text at 8-point font size. The display’s gamma is fixed at 2.2, and the contrast ratio is 800:1, meaning blacks are deep but not as dark as OLED. If you need higher contrast, consider using a dark background with bright text. The display’s refresh rate is 60 Hz, but you can run it at 90 Hz by reducing the SPI clock to 20 MHz and using double buffering. However, the human eye can’t perceive flicker above 60 Hz, so 90 Hz is only useful for motion blur reduction in fast-moving graphics.

When interfacing with a Raspberry Pi Pico, use the SPI pins: GP10 (MOSI), GP11 (SCK), GP12 (CS), GP13 (DC), and GP14 (RST). The Pico’s SPI clock can go up to 62.5 MHz, but the ST7789’s maximum is 40 MHz, so set the clock divider accordingly. For the ESP32, use VSPI with pins: MOSI=23, SCK=18, CS=5, DC=2, RST=4. The ESP32’s SPI clock can reach 80 MHz, but again, limit to 40 MHz. The display’s logic level is 3.3V, so if you’re using a 5V Arduino Uno, you’ll need a level shifter for the SPI lines. The display’s maximum SPI frequency is 40 MHz, but at 20 MHz, the signal integrity is better for longer wires (up to 10 cm). For longer distances, use shielded cables and keep the SPI clock below 10 MHz.

In terms of software, the Adafruit ST7789 library is widely used, but it’s not optimized for the 240x135 resolution. The library uses a 240x240 buffer internally, which wastes memory. A better approach is to use the TFT_eSPI library, which supports custom resolutions and has a fast 16-bit color mode. Set the TFT_WIDTH to 240 and TFT_HEIGHT to 135 in the User_Setup.h file. The library uses DMA on ESP32 and can achieve 60 FPS with full-screen updates. For the STM32, use the HAL library with DMA-SPI. The STM32F4’s SPI can run at 42 MHz, and with DMA, you can achieve 60 FPS with 0% CPU load. The display’s frame buffer can be stored in the MCU’s RAM, but if you’re low on memory, use a double-buffer approach: one buffer for the current frame and one for the next frame, swapping them during vertical blanking.

One common issue is ghosting or image retention. This happens when the display’s pixel voltage is not fully discharged. To fix this, you can add a delay of 10 ms between frames or use the display’s inversion command (INVON, 0x21). The ST7789 supports column inversion, which reduces flicker. The display’s response time is 2.5 ms, so a 10 ms delay is enough for the pixels to settle. If you’re displaying static images for long periods, use a screensaver that shifts the image by 1 pixel every minute to prevent burn-in. The IPS panel is less prone to burn-in than OLED, but it’s still a good practice.

For color accuracy, the ST7789’s gamma curve is fixed, but you can adjust the color balance by modifying the pixel data. For example, to make the image warmer, multiply the red channel by 1.1 and the blue channel by 0.9. The display’s color temperature is around 6500K, which is neutral. If you’re working with a specific color space like sRGB, you’ll need to apply a gamma correction. The ST7789’s gamma is 2.2, so you can pre-correct the image data using a lookup table. For a 16-bit RGB565 image, the gamma correction is applied per channel (5 bits for red, 6 bits for green, 5 bits for blue). A simple LUT of 32 entries for red and blue, and 64 entries for green, is sufficient. The correction formula is: output = pow(input / 255, 1/2.2) * 255.

In terms of mechanical integration, the 1.14 inch screen has a 0.5mm pitch FPC connector with 8 pins (GND, VCC, SCL, SDA, RES, DC, CS, BL). The connector is a 0.5mm pitch FPC, so you’ll need a matching connector on your PCB. The display’s thickness is 1.2 mm (excluding the FPC), and the active area is 14.7 mm x 28.7 mm. The overall module size is 17.5 mm x 31.5 mm, with a 2.0 mm bezel around the active area. The display’s operating temperature range is -20°C to +70°C, and the storage temperature is -30°C to +80°C. This makes it suitable for indoor and outdoor use, but avoid direct sunlight for extended periods as the backlight can degrade.

Now, let’s talk about the SPI timing in detail. The ST7789’s SPI interface is a 4-wire type with a maximum clock frequency of 40 MHz. The setup time for the DC pin is 10 ns, and the hold time is 5 ns. The data setup time is 10 ns, and the data hold time is 5 ns. The CS pin must be high for at least 10 ns between transactions. The command byte is sent with DC=0, and the data bytes are sent with DC=1. The display expects the data in MSB-first order. The SPI mode is 0 (CPOL=0, CPHA=0) or 3 (CPOL=1, CPHA=1), but most libraries use mode 0. The display’s command set includes 0x36 (MADCTL) for orientation, 0x3A (COLMOD) for color mode, 0x2A (CASET) for column address, 0x2B (RASET) for row address, and 0x2C (RAMWR) for memory write. The display also supports read commands, but they’re rarely used.

For a real-world example, let’s say you want to display a 240x135 image of a cat. You’ll first convert the image to a 64,800-byte raw file. Then, in your Arduino code, you include the file using #include "cat.h". The initialization sequence is: reset the display by pulling the RST pin low for 10 ms, then high. Send the SWRESET command, wait 150 ms. Send SLPOUT, wait 10 ms. Send COLMOD with 0x05, wait 10 ms. Send DISPON, wait 10 ms. Then set the window to full screen: CASET(0, 239), RASET(0, 134). Finally, send the RAMWR command followed by the 64,800 bytes of pixel data. The entire process takes about 200 ms, but the image is displayed instantly after the data transfer. If you’re using a faster MCU like the ESP32, you can reduce the delays to 5 ms each.

One important detail: the display’s frame buffer is organized in row-major order, starting from the top-left corner. The pixel (0,0) is the top-left, and (239,134) is the bottom-right. If you’re using a different orientation, the MADCTL register changes the scan direction. For example, if you set MADCTL to 0x70, the display will be in landscape mode, and the pixel (0,0) becomes the top-left in landscape orientation. The physical dimensions remain the same, but the logical coordinates change. The display’s internal memory is 240x320, but only 240x135 is used. The unused rows are not accessible, so you don’t need to worry about them.

In terms of power management, the display can be turned off by sending the SLPIN command (0x10) and pulling the backlight pin low. The sleep current is 5 µA, and the backlight current is 0 mA. To wake up, send SLPOUT (0x11) and wait 10 ms, then turn on the backlight. The display’s power-on sequence should include a delay of 120 ms after initial power-up to allow the internal regulator to stabilize. The display’s VCC pin should be connected to a 3.3V supply capable of 30 mA. The backlight pin can be driven by a GPIO with a 100 ohm resistor in series to limit inrush current. If you’re using a battery, a low-dropout regulator (LDO) like the MCP1700-3302E is recommended.

For debugging, you can use a logic analyzer to check the SPI signals. The CS line should go low before the first clock edge, and the DC line should be stable during the transaction. The data lines should be sampled on the rising edge of SCK. If you see glitches, check the wiring and reduce the SPI clock speed. The display’s FPC connector is fragile, so avoid bending it more than 30 degrees. The connector’s lifespan is about 5000 insertion cycles, so use a locking connector on your PCB. The display’s glass is 0.5 mm thick, so handle it with care to avoid cracks.

Another advanced technique is using the display’s hardware scrolling. The ST7789 supports vertical scrolling with the VSCRDEF command (0x33). You can define a scrolling area and then use the VSCRSADD command (0x37) to set the scroll offset. This is useful for text scrolling or for displaying a long image that scrolls horizontally. The scrolling speed is controlled by the MCU’s timer, and you can achieve smooth scrolling at 60 FPS. The display’s response time is 2.5 ms, so there’s no motion blur. The scrolling area can be any size up to 240x135, and the offset wraps around automatically.

If you’re working with a camera module, you can display live video on the 1.14 inch screen. The OV2640 camera outputs JPEG or raw data, which you can decode on the MCU and send to the display. The frame rate is limited by the JPEG decode time. On an ESP32, you can achieve 15 FPS with a 240x135 JPEG image. The display’s 60 Hz refresh rate is fast enough for video, but the bottleneck is the camera’s data rate. The OV2640’s maximum resolution is 1600x1200, but downscaling to 240x135 reduces the data to 64,800 bytes per frame. With a 40 MHz SPI, the display update time is 12.96 ms, leaving 53 ms for JPEG decoding. This is achievable with the ESP32’s dual-core processor.

Finally, let’s discuss the cost and availability. The Festival Programme Exhibitors Visit Lyme Regis

Ten days of art, sea and stories — on the Jurassic Coast.

Now in its 18th edition. Free entry throughout, across 27 venues in and around Lyme Regis. Download the 2025 programme guide.

Get the 2025 Programme