Building an ESP32-based Smart Switch With LVGL Display: Part 1 - Basic Setup and Display

by thanh01_pmt in Circuits > Arduino

130 Views, 2 Favorites, 0 Comments

Building an ESP32-based Smart Switch With LVGL Display: Part 1 - Basic Setup and Display

esp32-wt32sc01-lvgl8-arduinogfx-display-only.jpg

Welcome to our series on building a sophisticated ESP32-based smart switch! Our final product will feature a touch-enabled LVGL display, WiFi connectivity, MQTT integration for remote control, and audio feedback. This powerful device will allow you to control your home appliances with style and ease.

In this first post, we'll focus on setting up the foundation of our project: configuring the ESP32 and getting a basic display up and running. By the end of this tutorial, you'll have a working ESP32 setup with a simple LVGL interface displayed on the screen.

Let's dive in!


Supplies

This project utilizes the following libraries and hardware:

ArduinoGFX Library: Version 1.4.7 (the latest as of this writing)

LVGL Library: Version 8.3.11

While newer versions (9.x) of LVGL exist, we're using 8.3.11 for two reasons:

  • Compatibility with the Squareline software, which will be used in later parts of this series.
  • Long-term support for the 8.x versions.

You will need to backup and then re-config the lv_conf.h in the folder Arduino > libraries with the attached lv_conf.h below. (download > replace the old file)

Hardware: WT32SC01 board (standard version, not the Plus variant)

WT32-SC01 Board Config

TFT (ST7796)

* TFT_RST=22

* TFT_SCLK=14

* TFT_DC=21

* TFT_CS=15

* TFT_MOSI=13

* TFT_MISO=-1

* TFT_BCKL=23

Touch (FT6336U)

* TOUCH_SDA=18

* TOUCH_SCL=19

* I2C_TOUCH_ADDRESS=0x38

Downloads

Setting Up the Arduino IDE and ESP32 Board

arduino-ide-open-preferences.png

First, ensure you have the Arduino IDE installed and configured for ESP32 development. If you haven't done this yet, follow these steps:

  1. Download and install the Arduino IDE from the official website.
  2. Open Arduino IDE, go to File > Preferences (Arduino > Settings in MacOS).
  3. In "Additional Board Manager URLs", add:
  4. https://raw.githubusercontent.com/espressif/arduino-esp32/gh-pages/package_esp32_index.json
  5. Go to Tools > Board > Boards Manager, search for "esp32" and install the ESP32 board package.
  6. Select your ESP32 board from Tools > Board > ESP32 Arduino.

Installing Required Libraries

library-arduino-gfx-v1.4.7.png
library-lvgl-v8.3.11.png

We'll need two main libraries for this part of the project:

  1. Arduino_GFX: A hardware-agnostic graphics library.
  2. LVGL: A powerful and easy-to-use embedded GUI library.

To install these:

  1. Go to Tools > Manage Libraries in the Arduino IDE.
  2. Search for "arduino gfx" and install the version 1.4.7.
  3. Search for "lvgl" and install the version 8.3.11.

Basic Code Structure

#include <Arduino.h>
#include <Arduino_GFX_Library.h>
#include <lvgl.h>

#define GFX_BL 23 // Backlight control pin

// Display setup
Arduino_DataBus *bus = new Arduino_ESP32SPI(21 /* DC */, 15 /* CS */, 14 /* SCK */, 13 /* MOSI */, GFX_NOT_DEFINED /* MISO */);
Arduino_GFX *gfx = new Arduino_ST7796(bus, 22 /* RST */, 3 /* rotation */, false /* IPS */);

static const uint32_t screenWidth = 480; // Screen width
static const uint32_t screenHeight = 320; // Screen height

static lv_disp_draw_buf_t draw_buf; // LVGL draw buffer
static lv_color_t *disp_draw_buf; // LVGL color buffer
static lv_disp_drv_t disp_drv; // LVGL display driver

// Function declarations
void initDisplay(); // Initialize display
void initLVGL(); // Initialize LVGL
void setupLVGLBuffer(); // Setup LVGL buffer
void setupLVGLDriver(); // Setup LVGL driver
void createSimpleUI(); // Create a simple user interface

// Callback function to flush data from LVGL buffer to the display
void my_disp_flush(lv_disp_drv_t *disp_drv, const lv_area_t *area, lv_color_t *color_p);

void setup() {
Serial.begin(115200);

initDisplay();
initLVGL();
createSimpleUI();
}

void loop() {
lv_timer_handler(); // Handle LVGL tasks
delay(5);
}

// Initialize and configure the display
void initDisplay() {
gfx->begin();
gfx->fillScreen(BLACK);

#ifdef GFX_BL
pinMode(GFX_BL, OUTPUT);
digitalWrite(GFX_BL, HIGH);
#endif
}

// Initialize LVGL and related components
void initLVGL() {
lv_init();
setupLVGLBuffer();
setupLVGLDriver();
}

// Setup buffer for LVGL
void setupLVGLBuffer() {
uint32_t bufSize = screenWidth * 40;
disp_draw_buf = (lv_color_t *)heap_caps_malloc(bufSize * sizeof(lv_color_t), MALLOC_CAP_INTERNAL | MALLOC_CAP_8BIT);
if (!disp_draw_buf) {
Serial.println("LVGL disp_draw_buf allocate failed!");
return;
}
lv_disp_draw_buf_init(&draw_buf, disp_draw_buf, NULL, bufSize);
}

// Setup display driver for LVGL
void setupLVGLDriver() {
lv_disp_drv_init(&disp_drv);
disp_drv.hor_res = screenWidth;
disp_drv.ver_res = screenHeight;
disp_drv.flush_cb = my_disp_flush;
disp_drv.draw_buf = &draw_buf;
lv_disp_drv_register(&disp_drv);
}

// Create a simple user interface with a label
void createSimpleUI() {
lv_obj_t * label = lv_label_create(lv_scr_act());
lv_label_set_text(label, "Hello, ESP32-WT32SC01!");
lv_obj_align(label, LV_ALIGN_CENTER, 0, 0);
}

// Callback function to flush data from LVGL buffer to the display
void my_disp_flush(lv_disp_drv_t *disp_drv, 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);

#if (LV_COLOR_16_SWAP != 0)
gfx->draw16bitBeRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#else
gfx->draw16bitRGBBitmap(area->x1, area->y1, (uint16_t *)&color_p->full, w, h);
#endif

lv_disp_flush_ready(disp_drv);
}

Upload and Test

esp32-wt32sc01-board-setup-to-compile.png
esp32-wt32sc01-lvgl8-arduinogfx-display-only.jpg

Compile and upload this code to your ESP32. If everything is set up correctly, you should see "Hello, ESP32-WT32SC01!" displayed on your screen.

Congratulations! You've successfully set up the basic structure for our ESP32 smart switch project. You now have a working ESP32 with a display showing a simple LVGL interface.