Skip to content

T-Encoder Pro Quick Start

Required Libraries

LibraryVersionSource
TFT_eSPILatestGitHub
LVGL8.xGitHub
XPowersLibLatestGitHub

Arduino

  1. Install VS Code and the PlatformIO IDE extension
  2. Clone the repository:
    bash
    git clone https://github.com/Xinyuan-LilyGO/T-Encoder-Pro.git
  3. Open platformio.ini and select the target example
  4. Click to build, connect via USB-C, click to upload

Arduino IDE

Board Settings

SettingValue
BoardESP32S3 Dev Module
Upload Speed921600
USB CDC On BootEnable
CPU Frequency240 MHz (WiFi)
Flash ModeQIO 80 MHz
Flash Size16 MB (128Mb)
Partition Scheme16M Flash (3MB APP/9.9MB FATFS)
PSRAMOPI PSRAM

LVGL

T-Encoder Pro uses a round GC9A01 TFT (240×240). LVGL 8.x works via TFT_eSPI.

cpp
#include <lvgl.h>
#include <TFT_eSPI.h>

static lv_disp_draw_buf_t draw_buf;
static lv_color_t buf[240 * 10];
TFT_eSPI tft;

void my_disp_flush(lv_disp_drv_t *disp, const lv_area_t *area, lv_color_t *color_p) {
  uint32_t w = area->x2 - area->x1 + 1;
  uint32_t h = area->y2 - area->y1 + 1;
  tft.startWrite();
  tft.setAddrWindow(area->x1, area->y1, w, h);
  tft.pushColors((uint16_t *)&color_p->full, w * h, true);
  tft.endWrite();
  lv_disp_flush_ready(disp);
}

void setup() {
  tft.begin();
  tft.setRotation(0);
  lv_init();
  lv_disp_draw_buf_init(&draw_buf, buf, NULL, 240 * 10);

  static lv_disp_drv_t disp_drv;
  lv_disp_drv_init(&disp_drv);
  disp_drv.hor_res = 240;
  disp_drv.ver_res = 240;
  disp_drv.flush_cb = my_disp_flush;
  disp_drv.draw_buf = &draw_buf;
  lv_disp_drv_register(&disp_drv);

  lv_obj_t *label = lv_label_create(lv_scr_act());
  lv_label_set_text(label, "T-Encoder Pro");
  lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

void loop() {
  lv_timer_handler();
  delay(5);
}

Peripheral Examples

Round Display (GC9A01)

cpp
#include <TFT_eSPI.h>

TFT_eSPI tft;

void setup() {
  tft.begin();
  tft.setRotation(0);
  tft.fillScreen(TFT_BLACK);
  tft.setTextColor(TFT_WHITE, TFT_BLACK);
  tft.setTextSize(2);
  tft.drawString("Encoder Pro", 55, 110);
}

void loop() {}

Rotary Encoder

cpp
// Encoder A/B/Button pins — check utilities.h for your build
#define ENC_A    0
#define ENC_B    2
#define ENC_BTN  1

volatile int encoderPos = 0;

void IRAM_ATTR onEncoderA() {
  if (digitalRead(ENC_A) == digitalRead(ENC_B)) encoderPos++;
  else encoderPos--;
}

void setup() {
  Serial.begin(115200);
  pinMode(ENC_A, INPUT_PULLUP);
  pinMode(ENC_B, INPUT_PULLUP);
  pinMode(ENC_BTN, INPUT_PULLUP);
  attachInterrupt(digitalPinToInterrupt(ENC_A), onEncoderA, CHANGE);
}

void loop() {
  Serial.print("Position: ");
  Serial.println(encoderPos);
  if (digitalRead(ENC_BTN) == LOW) {
    Serial.println("Button pressed");
    delay(200);
  }
  delay(100);
}

PMU (via XPowersLib)

cpp
#include <XPowersLib.h>

XPowersPMU pmu;

void setup() {
  Serial.begin(115200);
  Wire.begin();
  if (!pmu.begin(Wire, AXP2101_SLAVE_ADDRESS)) {
    Serial.println("PMU init failed");
    return;
  }
  Serial.print("Battery voltage: ");
  Serial.print(pmu.getBattVoltage());
  Serial.println(" mV");
}

void loop() {
  delay(1000);
}

FAQ

Q: Upload keeps failing?
A: Hold BOOT, press and release RST, then release BOOT to enter download mode.

Q: What display does T-Encoder Pro use?
A: T-Encoder Pro uses a round GC9A01 TFT display (240 × 240) similar to T-Encoder, but adds extra peripherals like a PMU and additional encoder steps.