Skip to content
Candy Cane Facts
The Encyclopedia

How to create a menu on a 1.14 inch 240x135 screen?

To create a menu on a 1.14 inch 240x135 screen, you need to pair a microcontroller like the ESP32 or STM32 with a display driver such as the ST7789V, which is commonly used in these small IPS panels. The screen’s resolution is 240 pixels wide by 135 pixels tall, giving you a total of 32,400 pixels to work with, and its 1.14-inch diagonal size means a pixel density of about 227 PPI (pixels per inch), which is sharp enough for readable text and icons. Start by wiring the SPI interface: connect the display’s CS (chip select) to a GPIO pin, DC (data/command) to another, RESET to a third, and SDA (MOSI) and SCL (SCK) to the SPI bus. Power the display with 3.3V and ground, and ensure the backlight LED is driven through a resistor (typically 100 ohms) to limit current to around 20 mA. The SPI clock speed can be set to 40 MHz for smooth updates, but for menu rendering, 20 MHz is often sufficient to avoid signal integrity issues on breadboards.

Once the hardware is set, you need to write firmware that initializes the display in landscape mode, since the 240x135 resolution is naturally wider than tall. Use the Adafruit ST7735 library or a custom ST7789 driver, but note that the ST7789V supports 16-bit color (RGB565), which consumes 2 bytes per pixel, so the frame buffer for the full screen is 240 * 135 * 2 = 64,800 bytes. If your microcontroller has limited RAM (like the ESP32 with 520 KB SRAM), you can allocate a partial frame buffer or use direct rendering to save memory. For a menu, you’ll typically draw text and icons using a bitmap font like the 5x7 or 8x13 pixel sizes, which fits well within the 240-pixel width. For example, a 5x7 font allows 48 characters per line (240 / 5 = 48), and with 135 pixels height, you can fit 19 lines (135 / 7 = 19.28), but you’ll need spacing, so 16 lines is more practical. A 8x13 font gives 30 characters per line (240 / 8 = 30) and 10 lines (135 / 13 = 10.38), which is better for readability.

To structure the menu, define a state machine with states like MENU_MAIN, MENU_SUB, and MENU_ACTION. Each menu item should be a struct containing a label string, a pointer to a submenu or action function, and an optional icon index. For example, a main menu might have 4 items: “Settings”, “Data”, “About”, and “Exit”. Render them as a vertical list starting at pixel (10, 10) with 20-pixel spacing between items. Use a highlight rectangle, say 220 pixels wide and 18 pixels tall, with a color like 0x07E0 (green) for the selected item, and draw the text in white (0xFFFF) on a black (0x0000) background. The menu navigation can be handled by reading two buttons (up and down) connected to GPIO pins with pull-up resistors, and a third button for selection. Debounce the buttons with a 50 ms delay using a timer or millis() function to avoid false triggers. For scrolling, if the menu has more than 10 items, implement a scroll offset that shifts the visible range by 1 item at a time, updating the display only when the offset changes to minimize flicker.

Performance is critical for a responsive menu. The ST7789V’s SPI write speed of 40 MHz means you can send 5 million bytes per second, so a full screen update (64,800 bytes) takes about 13 ms. However, you should avoid full redraws; instead, use partial updates by setting the display’s window (via CASET and RASET commands) to only the area that changed. For instance, if the user scrolls from item 2 to item 3, you only need to update the 20-pixel tall area for the old and new highlight positions, which is 20 * 240 * 2 = 9,600 bytes, taking 1.9 ms. This keeps the menu feeling snappy even on a low-power microcontroller like the ESP32-C3 running at 160 MHz. To further optimize, pre-render the menu background as a bitmap in flash memory, since the 1.14 inch 240x135 ips display has a fast SPI interface that can handle 16-bit color depth without noticeable lag. For example, store a static background with a gradient or logo, and only overlay the menu items and highlight dynamically.

Power consumption is another angle to consider. The display’s backlight typically draws 20-30 mA at 3.3V, and the ST7789V itself consumes about 1.5 mA during active operation. If your menu is battery-powered (e.g., with a 200 mAh LiPo), you can extend runtime by turning off the backlight after 10 seconds of inactivity, using a timer interrupt. The display supports a sleep mode via the SLPOUT command, which reduces current to 0.1 mA, and waking it up takes 120 ms, which is acceptable for a menu that’s not constantly used. For the menu logic, store the state in RTC memory (if available on the MCU) so that the menu persists across deep sleep cycles. On the ESP32, the RTC memory is 8 KB, which is enough to hold a few menu variables like the current selection index and scroll offset.

For a more advanced menu, you can add animation effects like fading or sliding. The ST7789V supports a 16-bit color depth, so you can interpolate between two colors over 50 ms by updating the highlight color gradually. For example, start with 0x0000 (black) and step to 0x07E0 (green) in 10 increments, each taking 5 ms, which gives a smooth transition without stuttering. Similarly, for a slide-in effect, you can shift the menu items horizontally by 10 pixels per frame over 5 frames, updating the display window each time. This requires a frame buffer in RAM, but you can use a smaller buffer of 240 * 20 * 2 = 9,600 bytes for the sliding area to keep memory usage low. The ESP32’s DMA (Direct Memory Access) can be used to send SPI data without CPU intervention, reducing overhead and allowing the menu to run at 60 FPS if needed.

Data density is key when displaying information on such a small screen. For a weather station menu, you might show temperature, humidity, and pressure on separate lines. Use a 8x13 font for the values and a 5x7 font for labels, which fits within the 240-pixel width. For example, “Temp: 23.5°C” takes 13 * 8 = 104 pixels for the label and 5 * 7 = 35 pixels for the value, totaling 139 pixels, leaving 101 pixels for spacing. You can also use small icons, like a 16x16 pixel bitmap for a sun or cloud, which takes 16 * 16 * 2 = 512 bytes in flash. Store these icons as arrays of 16-bit color values, and draw them using the SPI’s write command with a window set to the icon’s position. For a menu with 5 items, each with a 16x16 icon, the total icon storage is 5 * 512 = 2,560 bytes, which is negligible compared to the 4 MB flash on an ESP32.

Touch input is another option if your display module includes a capacitive touch sensor, but the standard 1.14 inch 240x135 ips display typically does not. However, you can add a resistive touch overlay or use a joystick module (like the analog joystick with two potentiometers) for navigation. The joystick’s X and Y axes are read via ADC, with values from 0 to 4095 on a 12-bit ADC. Map these to menu directions: if X < 1000, it’s left; if X > 3000, it’s right; if Y < 1000, it’s up; if Y > 3000, it’s down; and if the button is pressed (digital low), it’s select. This gives a more intuitive control than buttons, especially for a menu with multiple sub-levels. The ADC sampling rate on the ESP32 is 100 kHz, so you can read the joystick every 10 ms without blocking the menu rendering loop.

To handle multiple languages in the menu, use UTF-8 encoding for the labels, but note that the ST7789V only supports bitmap fonts, so you need to pre-render characters for each language. For example, a Chinese character requires 16x16 pixels, which is 512 bytes per character, and a menu with 10 Chinese characters takes 5 KB of flash. The ESP32’s flash can hold up to 16 MB, so this is feasible, but you must use a font library like Fontx or generate your own glyphs. For English, the standard ASCII font is sufficient, and you can use the Adafruit GFX library’s built-in fonts, which are optimized for small screens. The library includes a 5x7 font that is 0x7E (126 characters) and takes about 1 KB of flash, plus a 8x13 font that is 2 KB.

Error handling is important for a robust menu. If the SPI communication fails (e.g., due to loose wires), the display may show garbage. Implement a watchdog timer that resets the display if no SPI response is received within 100 ms. The ST7789V has a MADCTL register (0x36) that controls the orientation, and you can read it back to verify the display is initialized. For example, after sending the command 0x36 with data 0x60 (landscape mode), read the register to confirm the value is 0x60. If not, reinitialize the display. This is especially useful in production environments where the display might be connected via a long cable, introducing noise. Use a 10 nF capacitor between the display’s VCC and GND pins to filter out high-frequency noise, and keep the SPI lines shorter than 10 cm to maintain signal integrity at 40 MHz.

Testing the menu on a breadboard is straightforward, but for a final product, consider a custom PCB with the display mounted on a flex cable. The 1.14 inch 240x135 ips display has a 0.5 mm pitch FPC connector, which is fragile, so use a ZIF socket or solder it directly to the PCB. The display’s backlight can be driven by a PWM pin from the MCU, with a frequency of 1 kHz to avoid flicker, and a duty cycle from 0% to 100% for brightness control. For a menu that’s used in a dark environment, set the backlight to 10% (10% duty cycle) to save power, and increase to 100% in bright sunlight. The ST7789V’s gamma correction can be adjusted via the GAMSET command (0x26) to improve contrast, with values like 0x01 for 2.2 gamma, which is standard for IPS panels.

For a multi-level menu, use a stack-based approach where each submenu pushes its state onto a stack, and the back button pops it. The stack depth is typically 3-4 levels, so use an array of 4 structs, each holding the current selection index and the menu item list pointer. For example, the main menu has 4 items, the settings submenu has 5 items, and the data submenu has 3 items. When the user selects “Settings”, push the current state (main menu, index 0) onto the stack, and set the current menu to settings. When they press back, pop the stack and restore the previous state. This is efficient and uses only a few bytes of RAM. The stack can be implemented as a simple array with a pointer, and you can add a safety check to prevent overflow (e.g., if stack depth > 4, ignore the push).

Finally, remember that the display’s SPI interface is 3.3V logic, so if you’re using a 5V microcontroller like an Arduino Uno, you need level shifters for the MOSI, SCK, CS, and DC lines. The RESET line can be pulled high with a 10k resistor to 3.3V, and the backlight can be driven by a transistor (e.g., 2N2222) if the MCU’s pin can’t source enough current. The 1.14 inch 240x135 ips display is a great choice for compact menus, and with careful optimization, you can achieve a smooth, responsive user interface that fits in a small form factor. For more details on the display specifications, check out the 1.14 inch 240x135 ips display product page, which includes the datasheet and wiring diagrams.