How to read data from a 1.14 inch display?
How to read data from a 1.14 inch display
To read data from a 1.14 inch display, you actually don’t “read” data from the display itself—you send data to it. The display is an output device, typically a TFT-LCD panel with a resolution of 240x135 pixels, like the 1.14 inch 240x135 ips display, which uses an SPI (Serial Peripheral Interface) protocol. You read data from a sensor or microcontroller, then write it to the display’s frame buffer via SPI commands. The process involves initializing the display controller (usually ST7789 or similar), setting up the SPI bus with correct clock speed (typically 4-8 MHz on Arduino, up to 32 MHz on STM32), and then sending pixel data in RGB565 format (16 bits per pixel, 5 bits red, 6 bits green, 5 bits blue). For a 240x135 resolution, that’s 32,400 pixels, each requiring 2 bytes, so total frame buffer size is 64,800 bytes. You read data from a source—like a temperature sensor via I2C, an ADC for analog signals, or a file from an SD card—then map that data to pixel colors and write it to the display’s GRAM (Graphics RAM). The display doesn’t store data for later retrieval; it’s a volatile buffer. If you need to “read” back what’s displayed, you’d need external memory or a separate capture method, but that’s rare. Most practical work involves reading input data from peripherals, processing it (e.g., scaling to 0-255 for brightness), and then pushing it to the display. Let’s drill into the hardware and software specifics.
Hardware interface: SPI wiring and timing
To communicate with a 1.14 inch display, you need at least 4 SPI lines: SCK (clock), MOSI (master out slave in), DC (data/command select), and CS (chip select). Plus a reset pin (RST) and a backlight pin (BL). The ST7789 controller inside these displays runs at 3.3V logic, but many boards like ESP32 or Raspberry Pi work at 3.3V natively. If you’re using a 5V Arduino Uno, you must use level shifters or voltage dividers on SCK, MOSI, DC, CS, and RST—otherwise, you risk frying the display. The SPI clock frequency matters: too slow (under 1 MHz) causes flickering during screen updates, especially for animations. At 8 MHz on an Arduino Mega, a full frame write takes about 40 ms (32,400 pixels * 2 bytes * 8 bits per byte / 8,000,000 bits per second = 64.8 ms theoretical, but overhead adds ~20-30 ms). For smooth 30 FPS, you need under 33 ms per frame, so 8 MHz is borderline. On an ESP32 with 40 MHz SPI, frame write drops to ~8 ms, allowing real-time data display. The display’s datasheet specifies minimum timing for SPI commands: SCK high time 16 ns, low time 16 ns, so 32 ns period = 31.25 MHz max. But many cheap clones have longer traces, so stick to 20 MHz max for reliability. Use 4-wire SPI mode (mode 0: CPOL=0, CPHA=0) or mode 3, depending on your library. The ST7789 supports both, but mode 0 is standard in Adafruit libraries.
Initialization sequence: Command table
Before you can send data, you must initialize the display with a specific sequence of commands. This is critical—skip a step, and you’ll get a blank screen or scrambled colors. The ST7789 datasheet provides a typical init sequence, but many vendors tweak it. Here’s a common one for 1.14 inch 240x135 displays:
| Command | Hex Code | Parameters | Purpose |
|---|---|---|---|
| SWRESET | 0x01 | None (delay 150 ms) | Software reset |
| SLPOUT | 0x11 | None (delay 150 ms) | Sleep out |
| COLMOD | 0x3A | 0x05 (16-bit RGB565) | Set color mode |
| MADCTL | 0x36 | 0x70 (for 240x135 portrait) | Memory access control |
| CASET | 0x2A | 0x00, 0x00, 0x00, 0xEF (240) | Column address set |
| RASET | 0x2B | 0x00, 0x00, 0x00, 0x87 (135) | Row address set |
| INVON | 0x21 | None | Inversion on |
| DISPON | 0x29 | None (delay 100 ms) | Display on |
Note: The MADCTL parameter 0x70 sets RGB order, horizontal refresh, and column/row swap. If your display shows mirrored or rotated, tweak this byte. For landscape 135x240, use 0x60 or 0xE0 depending on your orientation. The CASET and RASET values define the active window. Some displays have a 135x240 native resolution but are mounted as 240x135, so you need to set the window to 240 columns by 135 rows. If you skip this, you’ll write pixels outside the visible area, causing no output.
Reading data from sensors: Real-world example
Let’s say you want to read temperature from a DS18B20 sensor (1-Wire protocol) and show it on the display. The DS18B20 outputs a 12-bit value (0.0625°C resolution) over 1-Wire. You read it using a OneWire library, then convert to Celsius: tempC = raw / 16.0. For a 240x135 display, you can show this as a large number. You allocate a 64,800-byte buffer in RAM (if using a microcontroller with enough memory, like ESP32 with 520 KB SRAM). On Arduino Uno (2 KB SRAM), you can’t store the full buffer—you must write pixels line by line. Use the display’s windowing feature: set CASET and RASET to a small area (e.g., 100x50 pixels for the number), then write only those pixels. This reduces memory and speed overhead. For example, to display “23.5°C”, you’d render each digit using a 5x7 font, which requires 5*7*2 bytes = 70 bytes per character. With 4 characters, that’s 280 bytes—easily fits in Uno’s RAM. You read the sensor every 1 second (DS18B20 conversion takes 750 ms max), then update the display area. The SPI transaction for 280 bytes at 8 MHz takes 280 * 2 * 8 / 8,000,000 = 0.56 ms, negligible. The bottleneck is the sensor reading, not the display.
Data format: RGB565 vs RGB888
The 1.14 inch display expects RGB565 color format. Each pixel is 2 bytes: high byte contains bits 15-8 (R4-R0, G5-G3), low byte contains bits 7-0 (G2-G0, B4-B0). So red uses 5 bits (0-31), green 6 bits (0-63), blue 5 bits (0-31). To convert from 8-bit RGB888 (common in sensors), use: R5 = R8 >> 3; G6 = G8 >> 2; B5 = B8 >> 3; then color = (R5 << 11) | (G6 << 5) | B5. For example, pure red (255,0,0) becomes (31 << 11) = 0xF800. If you send the wrong format, like RGB888 directly, the display will show garbled colors—each pixel will be interpreted as two 16-bit values, doubling the image size and shifting colors. Always check your library’s color conversion. Adafruit’s ST7735 library (often used for ST7789) has a Color565() function that does this. But if you’re writing raw SPI data, you must handle it yourself. For a 240x135 image, you’d need to convert each pixel from a source format (e.g., JPEG decoded to RGB888) to RGB565. This takes CPU time: on an ESP32 at 240 MHz, converting 32,400 pixels takes about 2 ms. On an Arduino Uno at 16 MHz, it’s closer to 100 ms, which limits frame rate to 10 FPS if you do full-screen updates.
Reading from SD card: Storing display data
If you want to show a bitmap image on the 1.14 inch display, you read the image data from an SD card. A 240x135 RGB565 bitmap is 64,800 bytes. On an SD card, you’d store it as a .bmp file with a 54-byte header (for 24-bit BMP) or a 138-byte header (for 16-bit BMP). You read the file using SPI (SD card library), seek to the pixel data offset, then read 64,800 bytes into a buffer. But on a microcontroller with limited RAM, you can’t buffer the whole image. Instead, read line by line: set the display’s window to one row (240 pixels, 480 bytes), read 480 bytes from SD, write to SPI. This uses only 480 bytes of RAM. The SD card SPI speed is typically 4-8 MHz, so reading 480 bytes takes 480 * 8 / 4,000,000 = 0.96 ms. Writing to display at 8 MHz takes 480 * 8 / 8,000,000 = 0.48 ms. Total per row: 1.44 ms. For 135 rows, that’s 194 ms—about 5 FPS. To speed up, use DMA on ESP32 to read SD and write SPI simultaneously, or use a faster SD card (class 10) and increase SPI to 20 MHz. But note: the display’s SPI and SD card’s SPI often share the same bus (if you’re using a single SPI module), so you must switch chip selects and manage bus contention. Some boards like the ESP32 have two SPI interfaces (VSPI and HSPI), so you can dedicate one to display and one to SD card, avoiding conflicts.
Power consumption and data reading impact
Reading data from a sensor or SD card and writing to the display consumes power. The 1.14 inch display itself draws about 20-30 mA when backlight is on (typical backlight LED forward voltage 3.0V, current 15-20 mA). The ST7789 controller draws 2-4 mA in active mode. SPI communication adds 1-2 mA per transaction. When you read data from a sensor (e.g., DS18B20 draws 1.5 mA during conversion), the total system current for an ESP32 can be 80-100 mA. If you’re battery-powered, you need to optimize: read sensor data every 10 seconds instead of 1 second, turn off backlight between updates (use PWM on BL pin), and put the display into sleep mode (command 0x10) when idle. The ST7789 sleep mode draws less than 5 µA. But waking from sleep requires re-initialization (send SLPOUT and DISPON again), which takes ~250 ms. So for infrequent updates, sleep is worth it. For real-time data logging (e.g., every 100 ms), keep display on but reduce brightness to 50% PWM—this cuts backlight current to 10 mA.
Common pitfalls when reading data for display
One frequent issue: the display shows noise or random pixels when you first power it up. This happens because the ST7789 requires a stable 3.3V supply and a proper reset sequence. The reset pin must be held low for at least 10 µs, then high. Many libraries do this automatically, but if you’re using a bare-metal approach, you must do it manually. Another pitfall: SPI data lines are high impedance when not driven, so floating pins can cause spurious writes. Always pull CS high (inactive) when not using the display. For reading data from a sensor that shares the same SPI bus (e.g., an SPI ADC), you must ensure the display’s CS is high before toggling the sensor’s CS. If you accidentally write to the display while reading the sensor, you’ll corrupt the display’s GRAM. Use a logic analyzer to verify SPI timing—I’ve seen cases where a 1 ms delay between commands fixes ghosting. Also, the display’s datasheet specifies a maximum SPI clock speed of 15 MHz for write operations, but many Chinese clones fail above 10 MHz. Test your specific unit by sending a pattern (e.g., alternating red and blue pixels) and checking for color bleeding. If you see horizontal streaks, reduce SPI clock.
Advanced: Reading from external memory via DMA
For high-speed data visualization (e.g., plotting a waveform from an ADC sampling at 1 kHz), you can read ADC data into a circular buffer, then map it to pixel rows. The 1.14 inch display has 135 rows, so you can plot a 135-sample waveform. Read ADC at 1 kHz, store in a 135-byte array, convert each sample to a pixel column (0-239) using scaling: col = (sample - min) * 239 / (max - min). Then write those 135 pixels as a vertical line. Use DMA on the ESP32 to read ADC (via I2S or RMT) and write to SPI simultaneously. The ESP32’s I2S ADC can sample at up to 200 kHz, but for 1 kHz, you can use a simple timer interrupt. The DMA controller handles SPI writes without CPU intervention, so you can read ADC data while the display updates. This gives you a real-time oscilloscope-like display. The frame rate depends on how many samples you plot: for 135 rows, you update one row per sample, so at 1 kHz, you get 1000 rows per second, but the display only has 135 rows, so you scroll the plot. Use a FIFO buffer: shift old rows up and add new row at bottom. This requires rewriting the entire screen every 135 samples (135 ms), which at 8 MHz SPI takes ~65 ms, so you can achieve ~7.7 FPS. With DMA, CPU overhead is near zero.
Data integrity: Checksums and error handling
When reading data from a sensor over a noisy bus (e.g., long wires for DS18B20), bit errors can corrupt the temperature value. The DS18B20 has a built-in CRC check (8-bit CRC for the scratchpad). Always verify the CRC before using the data. If CRC fails, skip the update and retry. For the display, bit errors during SPI transmission can cause wrong pixels. The ST7789 doesn’t have error detection, so you must ensure your SPI lines are short (under 10 cm) and shielded if near motors. Use a 100 nF capacitor between VCC and GND on the display module to filter noise. If you’re reading data from an SD card, the FAT file system has CRC checks for file allocation table, but not for data blocks. You can add a simple XOR checksum to your bitmap file: store a checksum byte at the end of each row, then verify it after reading. If mismatch, re-read the row. This adds 1 byte per row (135 bytes per frame), which is negligible. For critical applications (e.g., medical data), use a 16-bit CRC and retry up to 3 times.
Performance benchmarks: Different microcontrollers
Here’s a comparison of how fast you can read data from a sensor and write to the 1.14 inch display on common platforms:
| Microcontroller | SPI Clock (MHz) | Full Frame Write (ms) | Sensor Read (DS18B20, ms) | Max FPS (full screen) |
|---|---|---|---|---|
| Arduino Uno (16 MHz) | 8 | 85 | 750 | 1.1 |
| ESP32 (240 MHz) | 40 | 8 | 750 | 1.3 (sensor limited) |
Reserve a room at Hotel Mora
Independent hospitality, Italian-crafted rooms, and a concierge that picks up on the first ring.
Check Availability