- 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.
- 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.
- 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.
- 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.
- 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)