Driving an ST7735-Based LCD with MicroPython on the Luat ESP32-C3

  1. Installing USB-to-Serial Drivers

Before flashing or communicating with the Luat ESP32-C3, install the CH343 USB-to-serial driver. Download latest version from the official source, run it as administrator, and follow the installation prompts. After successful installation, connecting the board should show a new COM port in your system's device manager.

  1. Flashing MicroPython onto the ESP32-C3

What is MicroPython?

MicroPython is a lightweight implementation of Python 3 optimized for microcontrollers. It enables direct hardware interaction using familiar Python syntax, making embedded development accessible without sacrificing performance on resource-constrained devices like the ESP32-C3.

Choosing a Development Environment

Two popular editors are supported:

  • Thonny: A beginner-friendly IDE with built-in MicroPython support. Note: it lacks code completion.
  • VS Code: Install the "RT-Thread MicroPython" extension for full IntelliSense, debugging, and file management capabilities.

Flashing the Firmware

Download the correct MicroPython firmware for your ESP32-C3 variant—typical either ESP32C3 or ESP32C3-with-usb. The file will have a .bin extension.

Method 1: Using Thonny
In Thonny, go to Run → Select Interpreter → MicroPython (ESP32), then choose Select local MicroPython image... and point to your downloaded .bin file. After rebooting, the device should appear in the file browser.

Method 2: Using Flash Download Tool (Recommended)
Use the Flash Download Tool (available via third-party links) to erase the flash and write the firmware at offset 0x0000. This method is more reliable, especially if Thonny fails to recognize the device post-flash.

  1. Uploading Code to the Device

In Thonny, create a new .py file in the device’s file system and press F5 to run/upload. In VS Code with the RT-Thread extension, right-click your script and select "Upload to Device." Files uploaded via either tool are visible across both environments.

  1. Interfacing the Luat Air101 LCD

The Air101 module integrates an ST7735-driven 80×160 color TFT display. It connects directly to the ESP32-C3 via onboard SPI pins—no external wiring is needed if using the official Luat carrier board.

Download a compatible ST7735.py driver (modified for MicroPython and Chinese font support). Upload this file to the root of the device’s filesystem using your chosen IDE.

  1. Using the ST7735 Display Driver

Initialization

from machine import SPI, Pin
from ST7735 import TFT
import time

spi = SPI(1, baudrate=40_000_000, sck=Pin(2), mosi=Pin(3), miso=Pin(10))
tft = TFT(spi, '/combined.bin', dc=6, rst=10, cs=7)
tft.init_7735(TFT.REDTAB80x160)
tft.fill(TFT.WHITE)  # Clears screen (appears black due to inversion)

Basic Graphics Demo

import random

phrases = ['你好!', '世界!', '在干嘛?', '上号!', '氪不改非']
font_w, font_h = 11, 14

def display_random_text():
    x = random.randint(0, 120)
    y = random.randint(1, 74)
    idx = random.randint(0, len(phrases) - 1)
    bg_color = TFT.color(random.randint(0,255), random.randint(0,255), random.randint(0,255))
    txt_color = TFT.color(random.randint(0,255), random.randint(0,255), random.randint(0,255))
    
    tft.fillrect((x, y), (font_w * len(phrases[idx]), font_h), bg_color)
    tft.text((x, y), phrases[idx], txt_color, size=1)

while True:
    for _ in range(100):
        display_random_text()
        time.sleep_ms(200)
    tft.fill(TFT.WHITE)

Displaying Images

Convert images to raw 16-bit RGB565 format using this helper script (requires Pillow):

from PIL import Image
import struct

def convert_image_to_dat(input_path, output_path):
    img = Image.open(input_path).convert('RGB')
    w, h = img.size
    with open(output_path + '.dat', 'wb') as f:
        for y in range(h):
            for x in range(w):
                r, g, b = img.getpixel((x, y))
                # Invert colors (common for ST7735 REDTAB)
                rgb565 = (( (255-r) & 0xF8 ) << 8) | \
                         (( (255-g) & 0xFC ) << 3) | \
                         ( (255-b) >> 3 )
                f.write(struct.pack('>H', rgb565))

After uploading the resulting .dat file to the device, render it line-by-line:

with open('/image.dat', 'rb') as f:
    for row in range(80):
        line_data = f.read(160 * 2)  # 160 pixels × 2 bytes
        tft.image(0, row, 159, row, line_data)

Common Drawing Functions

# Coordinate setup
x, y = 20, 30

# Screen rotation (0–3)
tft.rotation(1)

# Draw pixel
tft.pixel((x, y), TFT.BLACK)

# Text rendering (supports Chinese with /combined.bin)
tft.text((x, y), "Hello 世界!", TFT.RED, size=1, wrap=True)

# Single character
tft.char((x, y + 20), 'A', TFT.BLUE, size=1)

# Lines
tft.line((x, y), (x+30, y+30), TFT.GREEN)
tft.vline((x+40, y), 20, TFT.YELLOW)
tft.hline((x, y+50), 25, TFT.PURPLE)

# Rectangles
tft.rect((x, y+70), (30, 15), TFT.CYAN)
tft.fillrect((x+40, y+70), (25, 12), TFT.ORANGE)

# Circles
tft.circle((x+15, y+100), 10, TFT.BLACK)
tft.fillcircle((x+50, y+100), 8, TFT.GRAY)

Tags: MicroPython ESP32-C3 ST7735 Luat Air101

Posted on Wed, 30 Sep 2026 16:27:03 +0000 by deepermethod