Features

The kode dot has the best screen in a maker device on the market. It is a 2.13-inch AMOLED touch screen with the following features:
FeatureDescription
Size2.13 inches
Resolution410x502 pixels
Color depth16 bits (RGB565)
DriverCO5300 - QSPI
Touch driverCST820 - I2C
The screen is completely programmable with existing Arduino and ESP-IDF libraries and compatible with LVGL.

Connection diagram

Screen driver

The screen driver is the CO5300 and works using the QuadSPI bus. This driver is connected to the ESP32-S3 in the following way:
CO5300ESP32-S3
Chip SelectGPIO9
ClockGPIO17
Data 0GPIO15
Data 1GPIO14
Data 2GPIO16
Data 3GPIO10
ResetGPIO8
The QuadSPI bus is of the same family as the SPI bus, but has double the bandwidth.

Touch driver

The touch driver is the CST820 and works using the I2C bus. This driver is connected to the ESP32-S3 in the following way:
CST820ESP32-S3
SDAGPIO48
SCLGPIO47
InterruptEXP15
ResetGPIO8
The touch driver has the address 0x15 on the I2C bus.
The interrupt pin is connected to EXP15 of the IO expander. See IO expander for more information.
The reset pin of the touch driver and the screen driver are connected to the same pin of the ESP32-S3.

Arduino

ESP-IDF

Example code

Basic example

This is the most basic code to test the screen, only printing a ¡Hola mundo! on the screen.
display_test.ino
/**
 * Simple display demo with Arduino_GFX: initializes the panel and draws “Hello World!”.
 * Uses ESP32-S3 QSPI bus, 410x502 resolution, and max brightness.
 * Renders large text roughly centered on a blue background.
*/
/* ───────── KODE | docs.kode.diy ───────── */

#include <Arduino_GFX_Library.h>

#define DSP_HOR_RES 410
#define DSP_VER_RES 502
#define DSP_SCLK 17
#define DSP_SDIO0 15
#define DSP_SDIO1 14
#define DSP_SDIO2 16
#define DSP_SDIO3 10
#define DSP_RST 8
#define DSP_CS 9

/* Objects to handle the graphics bus and display */
static Arduino_DataBus *gfxBus;
static Arduino_CO5300 *gfx;

void setup() {
  Serial.begin(115200);
  delay(100);
  Serial.println("Simple Display Demo");

  /* ─── Display configuration ───
     QSPI bus: CS, SCLK, D0, D1, D2, D3 */
  gfxBus = new Arduino_ESP32QSPI(DSP_CS, DSP_SCLK, DSP_SDIO0, DSP_SDIO1, DSP_SDIO2, DSP_SDIO3);
  /* Panel constructor: bus, RST, rotation offset (0), x/y offset (0,0),
     width/height, backlight pin (22), options (0,0,0) */
  gfx = new Arduino_CO5300(gfxBus, DSP_RST, 0, 0, DSP_HOR_RES, DSP_VER_RES, 22, 0, 0, 0);

  if (!gfx->begin()) {
    Serial.println("Error: display init failed");
    while (true) /* halt on failure */ ;
  }

  gfx->setRotation(0);
  gfx->setBrightness(255);
  gfx->displayOn();
  Serial.println("Display initialized");

  /* Print Hello World! */
  gfx->fillScreen(BLUE);
  gfx->setTextSize(4);
  gfx->setTextColor(ORANGE);
  gfx->setCursor(65, 250);
  gfx->print("Hello World!");
}

void loop() {
  delay(1000);
}

LVGL example

This code implements LVGL 9.3 and allows you to test the screen printing a text, using an example or using a demo. By default, the music demo of LVGL is used.
lvgl_test.ino
/**
 * Example of using LVGL with Arduino on Kode Dot.
 * Sets up the display, touch panel, and draws a simple label.
 * More info: https://docs.lvgl.io/master/integration/framework/arduino.html
 */
/* ───────── KODE | docs.kode.diy ───────── */

#include <lvgl.h>
#include <Arduino_GFX_Library.h>
#include <Wire.h>
#include <bb_captouch.h>

/*To use the built-in examples and demos of LVGL uncomment the includes below respectively.
 *You also need to copy lvgl/examples to lvgl/src/examples. Similarly for the demos lvgl/demos to lvgl/src/demos.
 *Note that the lv_examples library is for LVGL v7 and you shouldn't install it for this version (since LVGL v8)
 *as the examples and demos are now part of the main LVGL library. */

// #include <examples/lv_examples.h>
// #include <demos/lv_demos.h>

/* Display resolution and rotation */
#define DSP_HOR_RES 410
#define DSP_VER_RES 502
#define DSP_ROTATION LV_DISPLAY_ROTATION_0

/* LVGL draw buffer size */
#define DRAW_BUF_SIZE (DSP_HOR_RES * DSP_VER_RES / 10 * (LV_COLOR_DEPTH / 8))
static uint8_t *lv_buf1;
static uint8_t *lv_buf2;

/* Objects to handle display bus and panel */
static Arduino_DataBus *gfxBus;
static Arduino_CO5300 *gfx;
static BBCapTouch touch;

/* Callback for LVGL to push rendered image to the display */
void my_disp_flush(lv_display_t *disp, const lv_area_t *area, uint8_t *px_map) {
  uint32_t w = lv_area_get_width(area);
  uint32_t h = lv_area_get_height(area);

  gfx->startWrite();
  gfx->writeAddrWindow(area->x1, area->y1, w, h);
  gfx->writePixels((uint16_t *)px_map, w * h);
  gfx->endWrite();

  /* Tell LVGL flushing is done */
  lv_display_flush_ready(disp);
}

/* Read data from the touch panel */
void my_touchpad_read(lv_indev_t *indev, lv_indev_data_t *data) {
  TOUCHINFO ti;
  if (touch.getSamples(&ti) && ti.count > 0) {
    data->state = LV_INDEV_STATE_PRESSED;
    data->point.x = ti.x[0];
    data->point.y = ti.y[0];
  } else {
    data->state = LV_INDEV_STATE_RELEASED;
  }
}

/* Use Arduino's millis() as LVGL tick source */
static uint32_t my_tick(void) {
  return millis();
}

void setup() {
  Serial.begin(115200);
  Serial.println("LVGL with Arduino on Kode Dot");

  /* ─── Display configuration ─── */
  gfxBus = new Arduino_ESP32QSPI(9, 17, 15, 14, 16, 10);
  gfx = new Arduino_CO5300(gfxBus, 8, 0, 0, DSP_HOR_RES, DSP_VER_RES, 22, 0, 0, 0);
  if (!gfx->begin()) {
    Serial.println("Display initialization failed");
    while (true) delay(1000);
  }
  gfx->setRotation(0);
  gfx->setBrightness(255);
  gfx->fillScreen(BLACK);
  Serial.println("Display initialized");

  /* ─── Touch panel configuration ─── */
  if (touch.init(48, 47, -1, -1, 400000) == CT_SUCCESS) {
    touch.setOrientation(0, DSP_HOR_RES, DSP_VER_RES);
    Serial.printf("Touch OK. Type=%d\n", touch.sensorType());
  } else {
    Serial.println("Touch initialization failed");
  }

  /* ─── Initialize LVGL ─── */
  lv_init();
  lv_tick_set_cb(my_tick); /* Set tick source */

  lv_display_t *disp = lv_display_create(DSP_HOR_RES, DSP_VER_RES);
  lv_display_set_flush_cb(disp, my_disp_flush);

  /* Allocate buffers in PSRAM */
  lv_buf1 = (uint8_t *)heap_caps_malloc(DRAW_BUF_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
  lv_buf2 = (uint8_t *)heap_caps_malloc(DRAW_BUF_SIZE, MALLOC_CAP_SPIRAM | MALLOC_CAP_8BIT);
  lv_display_set_buffers(disp, lv_buf1, lv_buf2, DRAW_BUF_SIZE, LV_DISPLAY_RENDER_MODE_PARTIAL);

  /* Configure input device as a pointer (touch) */
  lv_indev_t *indev = lv_indev_create();
  lv_indev_set_type(indev, LV_INDEV_TYPE_POINTER);
  lv_indev_set_read_cb(indev, my_touchpad_read);

  /* *******************
   * Create a simple label 
  ******************** */
  lv_obj_t *label = lv_label_create(lv_screen_active());
  lv_label_set_text(label, "Hello Arduino, I'm LVGL!");
  lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);

  /* *******************
   * Try an example. See all the examples
   *  - Online: https://docs.lvgl.io/master/examples.html
   *  - Source codes: https://github.com/lvgl/lvgl/tree/master/examples
  ******************** */
  //  lv_example_btn_1();

  /* *******************
   * Or try out a demo. Don't forget to enable the demos in lv_conf.h. E.g. LV_USE_DEMO_WIDGETS
  ******************** */
  //    lv_demo_music();
}

void loop() {
  lv_timer_handler(); /* Let LVGL handle the GUI */
  delay(5);
}

Download of examples

You can test the example codes using the Arduino IDE or the ESP-IDF IDE or download the codes in our drive: Examples of screen code