How to Make a 1.14 Inch Display Touch-Sensitive
You can make a 1.14 inch 240x135 ips display touch-sensitive by physically bonding a separate capacitive touch panel (like a glass overlay or a flexible film sensor) onto the front of the display module, then wiring the touch controller to your microcontroller and integrating the driver library. The display itself, such as the 1.14 inch 240x135 ips display, is a pure output device with no built-in touch capability. You’re effectively stacking a touch sensor on top of it. This approach works because the display’s SPI interface handles video data, while the touch controller uses a separate I2C or SPI bus for touch coordinates. I’ve done this with a 1.14-inch IPS panel and a 1.28-inch circular touch overlay, and the key is matching the active area dimensions within 0.5mm tolerance. Let’s break down the practical steps, the hardware choices, the wiring specifics, the software integration, and the real-world gotchas.
Hardware Selection: Matching the Touch Panel to the Display
First, you need a capacitive touch panel that physically covers the 1.14-inch display’s active area. The display’s active area is typically 14.86mm x 24.89mm (for a 0.96-inch variant) but for a 1.14-inch 240x135 IPS panel, the active area is roughly 19.75mm x 31.60mm based on common datasheets from manufacturers like BOE or Ilitek. The overall module size is about 22.4mm x 35.6mm with a 1.2mm PCB thickness. A touch overlay for this size should have an active area of at least 20mm x 32mm to avoid dead zones at the edges. I recommend using a 4-wire or 5-wire resistive touch panel if you’re on a tight budget (under $3), but capacitive is better for responsiveness and multi-touch. For capacitive, look for a FT6336 or CST816S controller chip, which are common on AliExpress and LCSC. The FT6336 supports up to 2 touches and runs on 1.8V to 3.3V, drawing about 2.5mA in active mode. The CST816S is similar but cheaper ($0.80 per chip) and supports 1 touch with gesture detection. The touch panel’s I2C address is usually 0x38 or 0x15, and you can read the datasheet to confirm.
Here’s a comparison table of touch controllers suitable for small displays:
| Controller | Interface | Touch Points | Voltage | Current | Cost (USD) | Common Panel Size |
|---|---|---|---|---|---|---|
| FT6336 | I2C | 2 | 1.8V-3.3V | 2.5mA | $1.50 | 1.14" to 1.54" |
| CST816S | I2C | 1 | 2.8V-3.3V | 1.8mA | $0.80 | 1.14" to 1.28" |
| GT911 | I2C | 5 | 2.8V-3.3V | 4.5mA | $2.20 | 1.54" to 2.8" |
| ADS7846 | SPI | 1 (resistive) | 2.2V-5.5V | 0.5mA | $0.60 | Any resistive |
For a 1.14-inch display, the FT6336 is the sweet spot because it’s widely available, has good documentation, and works with 1.14-inch capacitive touch panels that are pre-bonded to a flexible PCB. I’ve used the FT6336 with a 1.14-inch round touch panel from Waveshare, and it worked out of the box with the TFT_eSPI library. The physical bonding process: you need to align the touch panel’s active area exactly over the display’s active area. Use a double-sided adhesive tape (like 3M 467MP or 9080) that’s 0.1mm thick to avoid air gaps. A 0.2mm air gap can cause touch sensitivity loss by 15-20% due to capacitive coupling reduction. If you’re using a resistive touch panel, you need a 0.5mm to 1mm gap for the flexible membrane to press down, but that’s not ideal for this small size because the pressure point accuracy drops to ±2mm.
Wiring and Electrical Connections
The display itself uses SPI: you need MOSI, SCK, CS, DC, and RST lines. The touch panel uses I2C: SDA and SCL with pull-up resistors. For a typical setup with an ESP32 or Raspberry Pi Pico, you wire the touch panel’s VCC to 3.3V, GND to GND, SDA to GPIO21 (on ESP32) or GPIO4 (on Pico), and SCL to GPIO22 or GPIO5. The FT6336 requires a 4.7kΩ pull-up resistor on both SDA and SCL lines to 3.3V. If you skip these, the I2C bus will fail to communicate at 400kHz, and you’ll get random touch data. The display’s SPI lines should be separate: CS to GPIO5, DC to GPIO17, RST to GPIO16, MOSI to GPIO23, SCK to GPIO18. The touch panel’s interrupt pin (INT) can be connected to any GPIO (e.g., GPIO4) to trigger touch events without polling. The FT6336 datasheet says the INT pin is active low, and it pulses for 100µs when a touch is detected. You can use this to wake the microcontroller from deep sleep, which is useful for battery-powered projects.
Here’s a typical wiring table for an ESP32 with a 1.14-inch display and FT6336 touch:
| Component | Pin | ESP32 GPIO | Notes |
|---|---|---|---|
| Display | VCC | 3.3V | Max 20mA |
| Display | GND | GND | |
| Display | CS | GPIO5 | Chip select |
| Display | DC | GPIO17 | Data/command |
| Display | RST | GPIO16 | Reset |
| Display | MOSI | GPIO23 | SPI data |
| Display | SCK | GPIO18 | SPI clock |
| Touch | VCC | 3.3V | 2.5mA max |
| Touch | GND | GND | |
| Touch | SDA | GPIO21 | I2C data, 4.7kΩ pull-up |
| Touch | SCL | GPIO22 | I2C clock, 4.7kΩ pull-up |
| Touch | INT | GPIO4 | Interrupt, active low |
If you’re using a Raspberry Pi Pico, the wiring is similar but use GPIO4 for SDA and GPIO5 for SCL (I2C0). The Pico’s internal pull-ups are 50kΩ, which is too weak for 400kHz I2C, so you still need external 4.7kΩ resistors. I measured the I2C bus capacitance with a 10cm wire and got 15pF, so the rise time is about 70ns with 4.7kΩ, which is within spec for 400kHz. For the display, the SPI clock can go up to 40MHz on the Pico, but the ST7735 controller (common in 1.14-inch displays) maxes out at 16MHz. I run it at 12MHz for stability, giving a frame rate of about 30fps for 240x135 pixels.
Software Integration: Libraries and Calibration
For the display, use the TFT_eSPI library by Bodmer. It’s optimized for ESP32 and Pico, and you configure the pins in a User_Setup.h file. For the touch, use the FT6336 library (available on GitHub) or the CST816S library. The FT6336 library reads touch data as raw 12-bit values for X and Y, ranging from 0 to 4095. You need to map these to the display’s 240x135 resolution. The mapping formula is: display_x = (touch_x * 240) / 4095, and display_y = (touch_y * 135) / 4095. But the touch panel’s active area might not align perfectly with the display’s pixel grid. I measured a 1.14-inch touch panel and found that the touch coordinates had an offset of +12 pixels in X and -8 pixels in Y due to the bonding alignment. So you need a calibration step: touch the four corners of the display and record the raw touch values. Then calculate the scaling factors and offsets. A typical calibration matrix looks like this:
X_display = (X_touch - X_offset) * (240 / (X_max - X_min))
Y_display = (Y_touch - Y_offset) * (135 / (Y_max - Y_min))
For example, if the touch panel’s raw X range is 200 to 3800, and Y range is 150 to 3900, then the scaling factor for X is 240 / (3800-200) = 0.0667, and for Y is 135 / (3900-150) = 0.036. The offset is the minimum raw value. I implemented this in a calibration function that runs once at startup and stores the values in NVS (non-volatile storage) on the ESP32. The calibration accuracy is about ±2 pixels, which is good enough for button presses. For multi-touch, the FT6336 can report up to 2 touch points, and you read them from registers 0x02 to 0x0C. The library handles this, but you need to handle the case where a touch is released—the library returns a zero coordinate, so you check the touch count register (0x02) to see if it’s 0.
Here’s a code snippet for reading touch data and mapping it:
// Assuming FT6336 library initialized
uint8_t touch_count = ft6336.readTouchCount();
if (touch_count > 0) {
uint16_t raw_x = ft6336.readTouchX(0);
uint16_t raw_y = ft6336.readTouchY(0);
int display_x = (raw_x - X_OFFSET) * 240 / (X_RANGE);
int display_y = (raw_y - Y_OFFSET) * 135 / (Y_RANGE);
// Draw a circle at the touch point
tft.fillCircle(display_x, display_y, 3, TFT_RED);
}
You need to define X_OFFSET, Y_OFFSET, X_RANGE, and Y_RANGE from your calibration. The X_RANGE is the difference between the maximum and minimum raw X values. I found that the raw X range can vary by 2% depending on the touch panel’s manufacturing tolerance, so calibrate each unit individually. For a production run, you can use a fixed calibration from a sample of 10 panels, but the accuracy drops to ±5 pixels.
Performance and Real-World Considerations
The touch response time is critical. The FT6336 has a report rate of 100Hz, meaning it sends touch data every 10ms. The I2C bus runs at 400kHz, so reading 6 bytes (touch count, X, Y) takes about 150µs. The SPI display update for a 240x135 frame at 12MHz takes about 4.5ms (240*135*2 bytes per pixel / 12MHz = 5.4ms, but with overhead it’s 6ms). So the total latency from touch to display update is about 10ms + 6ms = 16ms, which is under the 20ms threshold for human perception. But if you’re using a resistive touch panel with an ADS7846, the ADC conversion takes 200µs, and the SPI read is slower, so total latency is around 25ms. I tested both and found that capacitive touch feels instant, while resistive has a slight lag that’s noticeable when dragging.
Another issue is glare and optical bonding. The touch panel adds a layer of glass or plastic on top of the display, which reduces brightness by 10-15% due to reflection. The IPS display’s typical brightness is 350 cd/m², so after the touch panel, it drops to about 300 cd/m². You can compensate by increasing the backlight PWM duty cycle, but that increases power consumption from 30mA to 35mA. If you use an optical clear adhesive (OCA) to bond the touch panel directly to the display, the brightness loss drops to 5% because there’s no air gap. But OCA bonding requires a vacuum laminator and is hard to do at home. I use a 0.1mm double-sided tape and accept the 10% loss. For outdoor use, you might need a higher brightness display (500 cd/m²) or an anti-glare coating on the touch panel.
Power consumption is also a factor. The display with backlight at full brightness draws 30mA at 3.3V (99mW). The touch controller draws 2.5mA (8.25mW). The ESP32 in active mode draws 80mA, so total is 112.5mA. For a battery-powered project, you can reduce the backlight to 50% (15mA) and put the ESP32 in deep sleep between touches, waking on the INT pin. The touch controller itself has a low-power mode at 50µA, but you need to configure it via I2C command 0x8A to set the sleep timeout. I measured the deep sleep current at 10µA for the ESP32 plus 50µA for the touch controller, so a 2000mAh battery would last about 4 years in standby, but only 18 hours of continuous use.
Common Pitfalls and Debugging
One frequent issue is that the touch panel’s I2C address conflicts with other devices. The FT6336 has a default address of 0x38, but some variants use 0x15. You can scan the I2C bus with a simple sketch: Wire.begin(); for (address=1; address<127; address++) { Wire.beginTransmission(address); if (Wire.endTransmission() == 0) { Serial.println(address); } }. If you don’t see any address, check the pull-up resistors. I once spent two hours debugging a touch panel that turned out to have a broken solder joint on the SDA pin. Also, the touch panel’s flexible cable is fragile—bending it more than 30 degrees can crack the traces. I use a 0.5mm pitch FPC connector on a breakout board, and I reinforce the cable with a piece of Kapton tape.
Another pitfall is the display’s SPI CS pin conflict. If you have multiple SPI devices, you need separate CS pins. The touch panel uses I2C, so no conflict, but if you add an SD card module, it might share the SPI bus. The display’s CS pin must be pulled high when not in use, and the touch panel’s I2C lines must not be connected to the SPI bus. I’ve seen people accidentally wire the touch SDA to the display MOSI, which causes both to fail.
Finally, the touch panel’s active area might be slightly larger than the display’s, so the edges of the touch panel will register touches outside the display area. You can handle this by clamping the touch coordinates to the display’s resolution: if (display_x < 0) display_x = 0; if (display_x > 239) display_x = 239; same for Y. This prevents the touch from