Skip to content

How to create graphics for a 3.4 inch 800x800 round display?

By admin·

To create graphics for a 3.4 inch 800x800 round display, you need to design in a square canvas that matches the exact pixel dimensions, then mask or clip the output to a circular format, because the display panel itself is physically round but the underlying pixel grid is still a square matrix. The key fact is that this specific display, often referred to as a 3.4 inch 800x800 round tft display, uses a MIPI interface and has a resolution of 800 pixels by 800 pixels, which is unusually high for a small round panel—about 329 pixels per inch (PPI) based on the 3.4-inch diagonal measurement. That pixel density is comparable to high-end smartphones, so your graphics must be sharp, with vector sources or high-resolution raster images to avoid blurriness. The physical active area diameter is roughly 86.36 mm (since 3.4 inches diagonal in a square gives a side of about 2.4 inches, or 60.96 mm, but the round shape means the diagonal is the diameter, so 3.4 inches equals 86.36 mm). This means each pixel is about 0.108 mm wide, which is tiny, so anti-aliasing on edges is critical for text and fine lines.

When you start designing, your canvas must be 800x800 pixels in a square layout, but only the central circular area—with a diameter of 800 pixels—will be visible. The corners of the square canvas will be physically cut off by the display bezel or masked by the driver firmware. Many graphics libraries like LVGL, TouchGFX, or even raw frame buffer code require you to handle this clipping manually. For example, in LVGL, you can set a circular display driver by defining the resolution as 800x800 and then using a custom flush callback that only writes pixels within a circle of radius 400 pixels from the center (400, 400). You can compute this with a simple distance check: if (dx^2 + dy^2) <= 400^2, then write the pixel; otherwise, skip it. This avoids rendering artifacts in the corners. If you use a raw frame buffer, you need to allocate 800x800x3 bytes (for RGB888) or 800x800x2 bytes (for RGB565), which is about 1.92 MB or 1.28 MB respectively. That’s a lot of RAM for a microcontroller, so you might need external SDRAM or a DMA-capable MCU like an STM32H7 series with at least 2 MB of SRAM. The MIPI interface typically runs at 4 lanes, with a clock speed of 500 MHz to 1 GHz, giving a theoretical bandwidth of 2 Gbps to 4 Gbps, which is enough to push 60 frames per second at 800x800 resolution with 24-bit color—that’s about 1.15 Gbps raw data rate, so you have headroom.

For graphic content, consider the viewing distance. Since the display is only 3.4 inches, it’s likely used in a smartwatch, dashboard, or portable device held 30 to 50 cm from the eyes. At that distance, the 329 PPI means you can display fine details like 8-point font sizes without aliasing, but you should use vector fonts or pre-rendered bitmaps at 2x scaling. The round shape creates a natural focal point in the center, so place critical information like time, notifications, or gauges within the inner 70% of the radius (280 pixels from center). The outer ring, from radius 280 to 400, is often used for decorative elements like gradients, tick marks, or secondary data, but avoid putting text there because the curvature distorts readability. For example, if you draw a circular progress bar, the arc length at radius 380 pixels is about 2387 pixels (2 * pi * 380), so each degree of arc is about 6.63 pixels wide, which is enough for smooth gradients but not for fine text. Use a minimum of 2-pixel wide strokes for lines to ensure visibility, since the display’s small size makes thin lines look like hairline cracks.

Color depth is another factor. The display supports 16.7 million colors (24-bit RGB), but your graphic pipeline might be limited to 16-bit (RGB565) due to MCU constraints. RGB565 gives 65,536 colors, which is fine for most UI elements, but gradients and photographic images will show banding. To mitigate this, use dithering algorithms like Floyd-Steinberg when converting from 24-bit to 16-bit. For example, a gradient from blue to green in RGB565 might show distinct steps every 8 to 10 pixels, but dithering spreads the error across neighboring pixels, making it look smooth. The display’s gamma curve is typically 2.2, so you should pre-correct your graphics in software to avoid washed-out or crushed shadows. If you’re using a tool like Photoshop, set the color space to sRGB and export as PNG with gamma correction. Alternatively, use a lookup table (LUT) in firmware to map 8-bit per channel values to linearized values.

Performance is a real concern. The 800x800 resolution means 640,000 pixels total, but only the circular area has about 502,654 pixels (area of a circle with radius 400 pixels is pi * 160000 = 502,654). That’s still a lot to update at 60 Hz. If you’re doing partial updates, like only changing a small widget, you can use a dirty rectangle approach, but the round shape complicates it because you can’t just update a rectangular region—you have to clip to the circle. Many MIPI controllers support command mode, where you send a column and page address range, but for a round display, you’d have to send the full frame buffer each time, or use a custom clipping algorithm. For example, if you update a 100x100 pixel square in the center, you can send a column range of 350 to 450 and a page range of 350 to 450, but the pixels in the corners of that square that fall outside the circle will still be written to the display’s memory, causing wasted bandwidth. To avoid that, you can pre-calculate a mask of valid pixels and only write those. This is why many round display drivers use a circular frame buffer in RAM, where each pixel is stored in a linear array indexed by angle and radius, but that requires more complex math and memory fragmentation.

Let’s talk about the physical interface. The MIPI DSI (Display Serial Interface) uses differential signaling, so you need to route the four data lanes and one clock lane with controlled impedance of 100 ohms differential. The PCB trace length should be matched to within 0.5 mm to avoid skew. The typical voltage swing is 200 mV to 1.2 V, so you need a proper level shifter if your MCU uses 3.3V logic. The display also has a backlight, usually with a separate LED driver that can handle up to 20 mA per LED, with 6 to 8 LEDs in series, so total current is around 120 mA to 160 mA. The backlight brightness is controlled by PWM, typically at 1 kHz to 20 kHz to avoid flicker. For graphics, you should design your UI with a dark background to save power, because OLED-like displays (though this is TFT) still have backlight that consumes constant power, but if it’s an AMOLED variant, then black pixels use less power. Check the datasheet—most round TFTs are actually IPS LCDs with a backlight, so power consumption is around 200 mW to 400 mW depending on brightness.

Software tools for creating graphics include Adobe Illustrator, Figma, or Inkscape for vector design, with the canvas set to 800x800 pixels and a circular clipping mask. Export as PNG with transparency, then use a tool like ImageMagick to crop to the circle: `convert input.png -gravity center -extent 800x800 -alpha set -draw "circle 400,400 400,0" output.png`. This gives you a square image with transparent corners, which you can then convert to a raw RGB565 array using a Python script. For example, using the Pillow library, you can load the image, iterate over each pixel, and if the pixel is within the circle, convert it to 16-bit RGB565 format (5 bits red, 6 bits green, 5 bits blue) and store it in a byte array. The formula is: `r5 = (r >> 3) & 0x1F; g6 = (g >> 2) & 0x3F; b5 = (b >> 3) & 0x1F; rgb565 = (r5 << 11) | (g6 << 5) | b5`. Then write the array to a C header file as a const uint16_t array. This can be stored in flash memory, which is cheaper than RAM. For a full 800x800 RGB565 image, that’s 1.28 MB, which is large but manageable on a 16 MB flash chip.

Typography is tricky on a round display. The curvature means that straight lines of text will appear to bend if placed near the edge. The best practice is to use radial text, where each character is rotated along the circle’s arc. For example, for a clock face, you can place the hour numbers at 30-degree intervals, with each number rotated to point outward from the center. The font size should be at least 24 pixels tall for readability, which corresponds to about 2.6 mm physical height. At 329 PPI, that’s 24 pixels, which is fine for a 3.4-inch display held at arm’s length. Avoid using serif fonts because the small size makes serifs blurry; stick to sans-serif like Roboto or Open Sans. For anti-aliasing, use a font rendering engine like FreeType with sub-pixel rendering, but be aware that the display’s RGB stripe orientation might be different from typical monitors. Check the datasheet for the sub-pixel layout—some round displays use a standard RGB stripe, but others might use a diamond pattern or pentile, which requires custom sub-pixel rendering. If the datasheet doesn’t specify, assume RGB stripe and use standard ClearType-like rendering.

Animation and transitions are possible but require careful optimization. For example, a smooth fade-in effect can be done by adjusting the backlight PWM from 0% to 100% over 200 ms, which is simpler than updating the frame buffer. For sliding animations, you can use a double buffer technique: one buffer for the current frame, one for the next, and then swap them during vertical blanking (V-sync). The MIPI interface supports V-sync via the TE (tearing effect) pin, which triggers an interrupt when the display is ready for a new frame. You can use this to avoid tearing. The typical refresh rate is 60 Hz, so you have 16.67 ms per frame. To update the entire circular area, you need to write 502,654 pixels, each 2 bytes, so 1,005,308 bytes per frame. At a MIPI data rate of 4 Gbps, that’s about 2 ms to transfer the data, leaving 14 ms for rendering. That’s plenty for simple UI updates, but if you’re doing complex 3D rendering or heavy image processing, you might need a GPU like the G2D engine on an i.MX RT1170 or a dedicated graphics coprocessor.

Testing your graphics on the actual display is essential. You can use a development board like the ESP32-S3 or STM32F769 with a MIPI breakout. Connect the display via a 30-pin FPC connector, and use a logic analyzer to verify the MIPI signals. The display’s datasheet will specify the initialization sequence, which is a series of commands sent over the MIPI bus. For example, you might need to send commands like 0x11 (sleep out), 0x29 (display on), and then set the column and page addresses. The command set is usually compatible with the ST7789 or ILI9341 controller, but the round shape requires a custom gamma setting to compensate for the non-uniform backlight distribution. Some round displays have a built-in circular mask in the controller, which automatically clips the output to a circle. Check the datasheet for a register like “MADCTL” or “CIRCLE_MODE” that enables this. If it’s available, you can set it and then treat the display as a normal 800x800 square, but only the circular area will light up. This saves you from having to do software clipping.

Data visualization is a common use case. For example, a circular gauge with a needle requires drawing an arc and a line from the center. The arc can be drawn using Bresenham’s circle algorithm or a trigonometric approach. For a needle, you can draw a line from the center to the edge at a specific angle. The math is straightforward: for angle theta, the endpoint is (400 + 400 * cos(theta), 400 + 400 * sin(theta)). Use a look-up table for sine and cosine to avoid floating-point math on an MCU. For a 1-degree resolution, you need 360 entries, each stored as a 16-bit integer scaled by 400, so 360 * 2 bytes = 720 bytes, which is trivial. For a smoother needle, use 0.1-degree steps, but that’s 3600 entries, still only 7.2 KB. The needle width should be at least 2 pixels to be visible. For a progress ring, you can draw a thick arc using the midpoint circle algorithm, with a thickness of 10 to 20 pixels. The outer radius is 380, inner radius 360, so you draw two concentric circles and fill the area between them. This can be done with a flood fill or by scanning each row and checking if the pixel is between the two radii.

Power consumption and thermal management are practical considerations. The display’s backlight LED driver can generate heat, especially at full brightness. At 160 mA and 3.3V, that’s 528 mW just for the backlight. The TFT panel itself consumes about 50 mW for the pixel driver. Total is around 600 mW, which is fine for a battery-powered device, but if you’re using a 200 mAh battery, you’ll get about 20 minutes of continuous use. To extend battery life, use a lower brightness (e.g., 50% PWM) and a dark UI theme. You can also implement a sleep mode where the display is turned off after a few seconds of inactivity. The MIPI interface supports low-power mode (LPM) where the data lanes are in a high-impedance state, reducing power consumption to near zero. The datasheet will specify the sleep current, typically 10 uA to 50 uA.

Manufacturing tolerances can affect your graphics. The round display’s active area might not be perfectly centered within the 800x800 pixel grid. There could be a misalignment of up to 0.1 mm, which is about 1 pixel. So if you draw a perfect circle, it might be slightly off-center. To compensate, you can add a 1-pixel margin around the edge, meaning you design for a 798-pixel diameter circle centered at (400, 400) and leave a 1-pixel gap. This ensures that even if the display is misaligned, no graphics are cut off. Also, the display’s bezel might be black, so a black background in the corners will blend in, but a white or colored background will show the bezel edge. So design with a black background to make the bezel disappear.

Finally, consider the user interface layout. For a smartwatch, the top area (0 to 200 pixels from top) is for status icons like battery, Bluetooth, and time. The center (200 to 600 pixels) is for main content like notifications or a watch face. The bottom (600 to 800 pixels) is for buttons or swipe areas. Since the display is round, you can use a radial menu where options are arranged around the edge. For example, a settings menu could have icons at 0°, 45°, 90°, etc., each 80 pixels from the edge. Touch input is often capacitive, so you need to map touch coordinates to polar coordinates. The touch controller might report (x, y) in the 800x800 square, but you need to ignore touches outside the circle. The typical touch resolution is 800x800 as well, so you can use the same distance check. For gesture recognition, like swipe up, you can detect a change in the y-coordinate over time, but only if the touch points are within the circle.

In summary, creating graphics for this display requires a square canvas, circular clipping, high-resolution assets, careful color management, and performance optimization for the MIPI interface. The display’s 329 PPI and 800x800 resolution demand vector graphics or high-DPI bitmaps, and the round shape forces you to think in polar coordinates for layout and interaction. Use tools like LVGL with a circular driver, or write your own frame buffer with distance-based clipping. Always test on the actual hardware to account for manufacturing tolerances and backlight uniformity. The datasheet for the 3.4 inch 800x800 round tft display is your primary reference for timing, command set, and physical dimensions, so study it carefully before finalizing your design.