How to draw shapes on a 1.3 inch 240x240 IPS LCD?

By admin

To draw shapes on a 1.3 inch 240x240 IPS LCD, you need to pair it with a microcontroller like an ESP32 or STM32, use the SPI interface for fast data transfer, and leverage a graphics library such as Adafruit GFX or TFT_eSPI to handle pixel-level operations. The display, often driven by the ST7789 or similar controller, has a resolution of 240x240 pixels, meaning each shape—whether a line, circle, rectangle, or triangle—is defined by coordinates within this grid. The SPI protocol, running at speeds up to 40 MHz, sends commands and data to the LCD, with typical pin connections including CS (chip select), DC (data/command), SCLK (clock), and MOSI (data). For example, drawing a filled rectangle requires setting the pixel region with a command like CASET (column address set) and RASET (row address set), then writing pixel data in RGB565 format, which uses 16 bits per pixel—5 bits for red, 6 for green, and 5 for blue. This gives you 65,536 colors to work with, but the IPS panel’s wide viewing angle (up to 178 degrees) and high contrast ratio (typically 1000:1) make colors pop even from the side. The display’s physical size is 1.3 inches diagonally, with an active area of about 23.4 mm x 23.4 mm, so each pixel is roughly 0.0975 mm square—tiny but crisp for text or icons. To start, you’ll need a library like TFT_eSPI for Arduino, which abstracts the low-level SPI writes. For instance, calling tft.fillCircle(120, 120, 50, TFT_RED) draws a red circle centered at pixel (120, 120) with a radius of 50, using Bresenham’s algorithm to compute pixel positions efficiently. The library handles the coordinate mapping: (0,0) is the top-left corner, and (239,239) is the bottom-right. If you want to draw a triangle, you define three points, say (50, 50), (190, 50), and (120, 180), then use tft.fillTriangle(x1, y1, x2, y2, x3, y3, color) to fill it with a solid color. Performance matters: the ST7789 controller can refresh the entire screen at 60 Hz, but drawing complex shapes with many pixels (like a filled circle) might take a few milliseconds due to SPI overhead. A 240x240 full-screen fill at 16-bit color requires 115,200 bytes (240 * 240 * 2), and at 40 MHz SPI, that’s about 2.88 ms per frame, but real-world tests show around 10-15 ms with library overhead. For a 1.3 inch 240x240 ips display, you can also use the Adafruit GFX library, which provides functions like drawRect(), drawRoundRect(), and drawEllipse(). The ST7789 supports hardware acceleration for rectangular fills via the RAMWR command, which lets you write a block of pixels in one burst, reducing SPI transactions. For example, to draw a 100x100 square at (70, 70), you set the column range to 70-169 and row range to 70-169, then send 10,000 pixels (100 * 100) in RGB565. The display’s controller has a 240x240 frame buffer, but it’s not double-buffered, so partial updates can cause tearing if you write too slowly—use a high SPI clock (e.g., 80 MHz on ESP32) to mitigate this. Power consumption is also key: the IPS LCD draws about 20-30 mA at 3.3V with backlight on, but the backlight alone can take 15-20 mA, so for battery projects, you might dim it via PWM on the LED pin. Now, let’s talk about shape drawing in detail. For lines, the library uses a modified Bresenham algorithm that steps through x or y coordinates, calculating the error term to decide which pixel to light up. A 45-degree line from (0,0) to (239,239) will have 240 pixels, each with a delta of 1 in both axes. For circles, the algorithm uses symmetry: it computes one octant (0 to 45 degrees) and mirrors it to the other seven octants, reducing calculations by 87.5%. For a circle of radius 100, you’ll draw about 628 pixels (2 * pi * r), but the library might use a 4x or 8x symmetry to speed it up. Rectangles are straightforward: you set the start and end coordinates, then fill the pixel region. If you want a rounded rectangle, the library adds quarter-circles at the corners, with a radius parameter. For example, tft.drawRoundRect(10, 10, 220, 220, 10, TFT_BLUE) draws a blue border with 10-pixel corner radius. The display’s pixel pitch is 0.0975 mm, so a 1-pixel line is about 0.1 mm wide—visible but thin. For thicker lines, you can draw multiple parallel lines or use a filled shape. The TFT_eSPI library includes a drawWideLine() function that uses a polygon fill algorithm for anti-aliased lines, but it’s slower. On the hardware side, the SPI interface uses 4-wire mode: CS, DC, SCLK, MOSI, and optionally MISO for readback (though most projects don’t need it). The ST7789 datasheet specifies a maximum SPI clock of 15 MHz in standard mode, but many users push it to 40-80 MHz on ESP32 with no issues, as long as wiring is short (under 10 cm) to avoid signal degradation. The display’s resolution is 240x240, so the maximum coordinate is (239, 239). If you draw a shape that goes out of bounds, the library clips it automatically—for example, a circle centered at (200, 200) with radius 50 will only show the part inside the screen. This clipping is done in software, not hardware, so it adds overhead. For performance, you can use the setRotation() function to change the orientation: rotation 0 is portrait, rotation 1 is landscape (240x240 stays square, so no change in aspect ratio). The display’s refresh rate is 60 Hz, but the ST7789 can be configured for 120 Hz if you use a faster SPI clock and reduce the frame buffer wait. Now, let’s get into data: the ST7789 controller has a 240x240x18-bit internal RAM, but you send 16-bit data, so it maps RGB565 to RGB666 internally. The color depth is 262K colors (18-bit), but you only use 65K via the 16-bit interface. For shape drawing, the library often uses a sprite technique: you create a buffer in RAM (e.g., 100x100 pixels = 20,000 bytes), draw shapes in it, then push it to the display via SPI. This reduces flicker and allows for partial updates. For example, a 50x50 sprite takes 5,000 bytes, which is feasible on an ESP32 with 520 KB SRAM. The TFT_eSPI library supports sprites with createSprite(), fillSprite(), and pushSprite() functions. You can draw shapes like circles, rectangles, and triangles inside the sprite, then push it to any position on the screen. This is useful for animations or games. The SPI speed for sprite push is the same as direct writes, but you save time by not recalculating shapes each frame. For a 1.3 inch 240x240 ips display, the pixel density is about 277 PPI (pixels per inch), which is higher than many monitors, so shapes look smooth. The IPS technology means colors don’t shift when viewed from angles up to 178 degrees, which is critical for wearable or handheld devices. The display module itself is often mounted on a PCB with a 1.5 mm thickness, and the glass is 0.5 mm thick, making it sturdy but fragile if bent. The SPI pins are usually 0.1-inch pitch headers, so you can connect them with jumper wires. For drawing shapes, you need to initialize the display with specific commands: SWRESET (software reset), SLPOUT (sleep out), COLMOD (color mode set to 16-bit), DISPON (display on). The typical init sequence is about 20 commands, each taking 1-2 ms. After init, you can draw shapes. The library’s fillScreen() function sets the entire screen to one color, which is useful for clearing. For example, tft.fillScreen(TFT_BLACK) clears to black, then you draw shapes on top. The display’s contrast ratio is 1000:1 typical, so black is deep and white is bright. The backlight is a white LED, with a forward voltage of 3.0-3.2V and current of 15-20 mA. You can control brightness with a PWM pin (e.g., pin 4 on ESP32) at 1 kHz frequency. Now, let’s talk about shape drawing algorithms in detail. For a line, the Bresenham algorithm uses integer arithmetic: it calculates the slope as (y2 - y1) / (x2 - x1), but avoids floating point by using an error term. For a line from (0,0) to (100, 50), the slope is 0.5, so the algorithm steps x from 0 to 100, and increments y when the error exceeds 0.5. This results in a jagged line, but at 240x240, it’s barely noticeable. For anti-aliasing, you’d need a library like Adafruit_GFX with a custom function, but it’s slower. For circles, the midpoint circle algorithm uses the equation x^2 + y^2 = r^2, and checks if (x+1)^2 + y^2 - r^2 is less than (x+1)^2 + (y-1)^2 - r^2 to decide whether to move diagonally. For a circle of radius 100, the center is at (120, 120), so the circle touches the edges at (20, 120) and (220, 120). The library draws it in about 1 ms on an ESP32 at 80 MHz SPI. For filled circles, the algorithm draws horizontal lines from the top to bottom of the circle, using the same symmetry. For a filled circle of radius 100, it draws 200 lines (one per pixel row), each with varying lengths. This takes about 5 ms. For rectangles, the fill is a simple loop: for each row from y1 to y2, write a horizontal line of pixels. For a 100x100 rectangle, that’s 100 rows of 100 pixels, or 10,000 pixels. At 40 MHz SPI, that’s 0.25 ms for the data transfer, but the library overhead adds another 0.5 ms. For triangles, the library uses a scanline fill algorithm: it finds the three edges, then for each row, it calculates the intersection points and fills between them. For a triangle with vertices (50, 50), (190, 50), (120, 180), the height is 130 rows, and each row has a varying width. The algorithm is efficient but uses floating point for slope calculations, which can be slow on a 32-bit MCU. The ST7789 controller has a feature called “partial mode” where you can update only a rectangular region, but it’s not commonly used for shapes. The display’s response time is 10-20 ms (typical for IPS), so fast-moving shapes might show slight blur, but it’s fine for most applications. For a 1.3 inch 240x240 ips display, you can also draw text shapes, but that’s a different topic. The library includes fonts like FreeSans12pt which are bitmapped, meaning each character is a shape of pixels. For example, the letter ‘A’ is a 12x12 pixel grid, drawn with tft.drawChar(). You can also create custom shapes by defining a bitmap array. For instance, a heart shape can be defined as a 16x16 pixel array, then drawn with tft.drawBitmap(). The bitmap is stored in flash memory to save RAM. The display’s SPI interface uses 3.3V logic, so you need level shifters if using a 5V microcontroller like Arduino Uno. The typical wiring is: VCC to 3.3V, GND to ground, CS to pin 10, DC to pin 9, SCLK to pin 13, MOSI to pin 11, and LED to 3.3V (or PWM pin). On an ESP32, you can use any GPIO pins, but the SPI pins are usually VSPI: MOSI on 23, MISO on 19, SCLK on 18, CS on 5, DC on 2. The TFT_eSPI library allows you to configure these pins in the User_Setup.h file. For example, you set TFT_CS 5, TFT_DC 2, TFT_MOSI 23, TFT_SCLK 18. The library also supports hardware SPI, which is faster than bit-banging. The SPI clock speed is set via SPI.begin() with a divider, e.g., SPI.begin(18, 19, 23, 5) for 80 MHz. Now, let’s talk about power consumption in detail. The display’s backlight uses 15-20 mA, and the LCD controller uses 5-10 mA, so total is 20-30 mA at 3.3V. That’s 66-99 mW. For a battery-powered project, you can turn off the backlight with a MOSFET, or use a sleep mode on the ST7789. The sleep command is SLPIN, which drops current to 5 µA. But you need to reinitialize after wake. For shape drawing, the library uses a buffer for the font or sprite, but for direct shapes, it writes pixels one by one. The SPI bus is shared, so if you have other SPI devices, you need to manage CS lines. The display’s resolution is 240x240, so the total pixels are 57,600. For a full-screen image, you need 115,200 bytes of RAM, which is too much for an Arduino Uno (2 KB), but fine for an ESP32 (520 KB). So, for complex shapes with gradients, you can use a frame buffer. For example, you can allocate a buffer of 115,200 bytes, draw shapes in it, then push to the display. This allows for double-buffering to avoid tearing. The library’s pushImage() function can send a buffer to the display at high speed. For a gradient rectangle, you can fill the buffer with colors that change per row, then push it. The display’s gamma correction is set by default, but you can adjust it via commands like GAMSET and GAMCTRL. The ST7789 has a 3.3V power supply, but the logic levels are 1.8V to 3.3V, so it’s compatible with most MCUs. The display’s viewing angle is 178 degrees, so shapes look consistent from all angles. The contrast ratio is 1000:1, so black is truly black, which helps shapes stand out. For a 1.3 inch 240x240 ips display, the physical dimensions are 30 mm x 30 mm x 3 mm (including PCB), so it’s small enough for a pocket device. The SPI interface is 4-wire, but you can also use 3-wire if you skip the MISO pin. The display’s driver IC is usually the ST7789V, which supports 18-bit color but you send 16-bit. The chip has a built-in oscillator for the clock, but you need an external capacitor for stability. The display’s refresh rate is 60 Hz, but you can set it to 120 Hz by changing the framerate register. For shape drawing, the library’s performance depends on the MCU. On an ESP32 at 240 MHz, a filled circle of radius 100 takes about 3 ms. On an STM32F103 at 72 MHz, it takes about 5 ms. On an Arduino Uno at 16 MHz, it takes 50 ms due to slow SPI and limited RAM. So, for real-time shape drawing, use a 32-bit MCU. The TFT_eSPI library also supports anti-aliased fonts, but shapes are not anti-aliased by default. You can implement anti-aliasing by drawing multiple pixels with different alpha values, but it’s complex. For a simple shape like a line, you can use the drawLine() function with a thickness parameter. The library’s drawWideLine() uses a polygon fill for thick lines, but it’s slower. For a 5-pixel thick line, it draws a rectangle with rounded ends. The display’s pixel pitch is 0.0975 mm, so a 5-pixel line is 0.4875 mm wide, visible. For a 1-pixel line, it’s 0.0975 mm, which is thin. The library’s drawFastVLine() and drawFastHLine() are optimized for vertical and horizontal lines, using the rectangle fill command. For example, a vertical line from (100, 0) to (100, 239) is a 1-pixel wide rectangle, so it uses the same RAMWR command. This is faster than drawing pixel by pixel. The ST7789 supports a 16-bit parallel interface as well, but most modules use SPI. The SPI interface has a maximum speed of 15 MHz per the datasheet, but many users run at 40 MHz without issues. The display’s command set includes over 100 commands, but you only need