CrowPanel 2.1inch-HMI ESP32 Rotary Display 480*480 IPS Round Touch Knob Screen¶
What is a rotary screen?¶
The rotary screen is an intelligent interactive device that usually consists of a circular knob and a display. The knob can be rotated to control various functions, while the display is used to display relevant information.
ESP32 Display - 2.1 inch rotary screen, uses high-performance ESP32-S3 chip, equipped with 32-bit dual-core chip. The maximum clock frequency reaches 240MHz, with strong performance and easy to handle complex tasks.
Supports 2.4G WiFi and BLE low-power Bluetooth, to achieve reliable wireless communication, easily connect to the Internet, suitable for smart home, industrial control, portable devices and other scenarios.
Supports capacitive touch operation and knob input, the knob supports clockwise, counterclockwise rotation and full press operation, smooth feel, and various interaction methods.
The 5V charging interface supports both power supply and program burning, and is also equipped with three expansion interfaces: UART, I2C, and FPC, to meet various development needs.
It supports Arduino IDE, Espressif IDF, Lua RTOS, Home Assistant/PlatformIO/Micro Python, and supports the LVGL library; you can design the UI interface yourself. It is an ideal platform for DIY projects like a mechanical keyboard knob.
ESP32 Display - 2.1 inch rotary knob screen is not just an interactive module, but an intelligent interaction solution that combines high performance, multi-function, and ease of use. Whether you are an IoT developer, smart home enthusiast, or professional, you can find an efficient tool that meets your needs.
Self-developed by Elecrow with exclusive design.
Model DHE03921D
Specification¶
Main Chip: ESP32-S3R8 | |
---|---|
Processor | Equipped with high-performance Xtensa 32-bit LX7 dual-core processor, with a main frequency of up to 240MHz |
System memory | 512KB SRAM、8M PSRAM |
Storage | 16M Flash |
Screen | |
Size | 2.1 inch |
Screen Type | IPS |
Touch Type | Capacitive Touch |
Resolution | 480*480 |
Wireless Communication | |
Bluetooth | Bluetooth Low Energy and Bluetooth 5.0 |
WiFi | Support 802.11a/b/g/n,2.4GH |
Hardware | |
UART Interface | 1x UART1, 1x UART0; ZX-MX 1.25-4P |
I2C Interface | ZX-MX 1.25-4P |
FPC connector | 12P, Power supply burning port |
Button | RESET button, BOOT button, confirmation button (knob press switch) |
LED Light | Power indicator, LED ambient light |
Other | |
Power Input | 5V/1A |
Operating temperature | -20~65℃ |
Storage temperature | -40~80℃ |
Operation Power | Module: DC5VMain Chip: 3.3V |
Size | 79*79*30mm |
Shell | Aluminum alloy + plastic + acrylic |
Net Weight | 80g |
Schematic Diagram:¶
ESP32-S3 with display and touch schematic diagram
Schematic Diagram:
Definition in the main program:¶
Arduino_ESP32RGBPanel *bus = new Arduino_ESP32RGBPanel(
16 /* CS */, 2 /* SCK */, 1 /* SDA */,
40 /* DE */, 7 /* VSYNC */, 15 /* HSYNC */, 41 /* PCLK */,
46 /* R0 */, 3 /* R1 */, 8 /* R2 */, 18 /* R3 */, 17 /* R4 */,
14 /* G0/P22 */, 13 /* G1/P23 */, 12 /* G2/P24 */, 11 /* G3/P25 */, 10 /* G4/P26 */, 9 /* G5 */,
5 /* B0 */, 45 /* B1 */, 48 /* B2 */, 47 /* B3 */, 21 /* B4 */
);
Arduino_ST7701_RGBPanel *gfx = new Arduino_ST7701_RGBPanel(
bus, GFX_NOT_DEFINED /* RST */, 0 /* rotation */,
false /* IPS */, 480 /* width */, 480 /* height */,
st7701_type5_init_operations, sizeof(st7701_type5_init_operations),
true /* BGR */,
10 /* hsync_front_porch(10) */, 4 /* hsync_pulse_width(8) */, 20 /* hsync_back_porch(50) */,
10 /* vsync_front_porch(10) */, 4 /* vsync_pulse_width(8) */, 20 /* vsync_back_porch(20) */);
-
I2C_SDA_PIN: 38
-
I2C_SCL_PIN: 39
-
ENCODER_A_PIN: 42
-
ENCODER_B_PIN: 4
-
SCREEN_BACKLIGHT_PIN: 6
PCF8574 Extended IO (via I2C address 0x21):
- P0:Touchscreen reset
- P2: Touchscreen interrupt
- P3: LCD power
- P4: LCD reset
- P5: Encoder button (INPUT_PULLUP)
Use the configuration guide:¶
Get Started with Arduino IDE¶
Please note that the version of esp32 supported by the sample code provided with this product is 2.0.14.
Please click the card below to learn how to install Arduino IDE, and install ESP32 board in the Arduino IDE.
Introduction to the factory default sample program:¶
display effect¶
Design UI file with SquareLine Studio¶
Get Started with SquareLine Studio¶
Please click the card below to learn how to download the SquareLine Studio, and Simple operating instructions.
UI engineering files and code resources currently available on GitHub:¶
CrowPanel-2.1inch-HMI-ESP32-Rotary-Display-480-480-IPS-Round-Touch-Knob-Screen
Importing UI projects using SquareLine Studio:¶
Click “Import Project” in the lower right corner to import the UI project we provided.
After importing, the project will appear in the list. Double-click to open the factory.
You can directly export UI files, use the UI files we provide, or modify the UI project yourself to customize your settings.
Main program introduction section¶
Click on the GitHub link to download the code, and use Arduino to open.
Click on the GitHub link to download the library and UI files we provide, and place these files in the libraries folder..
Then click "File" -> "Preferences" -> "Setting" to check the sketchbook location. Place the libraries downloaded to the sketchbook location.
Core Hardware¶
-
ESP32-S3 microcontroller chip
-
2.1-inch 480x480 IPS circular touchscreen (ST7701 RGB interface)
-
Capacitive touchscreen chip (e.g., CST8XX series)
-
Rotary encoder (with buttons)
-
PCF8574 I2C expansion I/O chip
-
WiFi & BLE wireless communication module (integrated into ESP32-S3)
①Main library dependencies¶
-
lvgl and lv_demos: Used for graphical user interface display and demonstrations
-
Arduino_GFX_Library: Drives screen display
-
WiFi.h and WiFiMulti.h: WiFi connection management
-
Adafruit_SSD1306 and Adafruit_GFX: OLED display drivers
-
BLEDevice, BLEServer, BLEUtils: Bluetooth BLE communication
-
Adafruit_CST8XX: Capacitive touchscreen driver
-
PCF8574: I2C expansion I/O chip driver
-
ui.h: Custom interface-related header file
#include <lvgl.h>
#include <demos/lv_demos.h>
#include <Arduino_GFX_Library.h>
#include "WiFiMulti.h"
#include <WiFi.h>
#include <Adafruit_SSD1306.h>
#include <Adafruit_GFX.h>
#include "BLEDevice.h"
#include "BLEServer.h"
#include "BLEUtils.h"
#include <Adafruit_CST8XX.h>
#include "ui.h"
#include "PCF8574.h"
②Pin definitions¶
The following programs define the relevant pins:
1. I2C pin definitions
#define I2C_SDA_PIN 38
#define I2C_SCL_PIN 39
2. Encoder pin definitions
#define ENCODER_A_PIN 42
#define ENCODER_B_PIN 4
3. Screen backlight pin definition
#define SCREEN_BACKLIGHT_PIN 6
4. OLED reset pin
#define OLED_RESET -1
5. RGB screen-related pins (defined during bus initialization)
16: CS, 2: SCK, 1: SDA, 40: DE, 7: VSYNC, 15: HSYNC, 41: PCLK
46, 3, 8, 18, 17: R0~R4
14, 13, 12, 11, 10, 9: G0~G5
5, 45, 48, 47, 21: B0~B4
6. PCF8574 expansion chip I2C address
PCF8574 pcf8574(0x21);
The above are the main pin definitions and uses involved in this program.
③Multitasking architecture¶
This program runs on the ESP32-S3 development board, combining a 480×480 RGB LCD (ST7701 controller) + capacitive touch screen (CST8XX) + OLED (SSD1306) + rotary encoder to implement a multifunctional human-machine interface control system (HMI).
④User Interaction Flow¶
Main Interface Operations¶
1)Display module
RGB LCD screen (480×480, ST7701 controller)
Driven by Arduino_GFX_Library
and combined with LVGL to display the GUI interface.
OLED screen (SSD1306)
Driven by I2C and used as an auxiliary test display.
#include <Arduino_GFX_Library.h>
#include <Adafruit_SSD1306.h>
#include <Wire.h>
#include <lvgl.h>
// RGB LCD
Arduino_ESP32RGBPanel *bus = new Arduino_ESP32RGBPanel(
41 /* DE */, 40 /* VSYNC */, 39 /* HSYNC */, 42 /* PCLK */,
45 /* R0 */, 48 /* R1 */, 47 /* R2 */, 21 /* R3 */, 14 /* R4 */,
5 /* G0 */, 6 /* G1 */, 7 /* G2 */, 15 /* G3 */, 16 /* G4 */, 4 /* G5 */,
8 /* B0 */, 3 /* B1 */, 46 /* B2 */, 9 /* B3 */, 1 /* B4 */,
0 /* hsync_polarity */, 20 /* hsync_front_porch */, 10 /* hsync_pulse_width */, 10 /* hsync_back_porch */,
0 /* vsync_polarity */, 8 /* vsync_front_porch */, 10 /* vsync_pulse_width */, 10 /* vsync_back_porch */,
1 /* pclk_active_neg */, 16000000 /* prefer_speed */
);
Arduino_ST7701_RGBPanel *gfx = new Arduino_ST7701_RGBPanel(
bus, GFX_NOT_DEFINED, 0, false, 480, 480, st7701_type5_init_operations, sizeof(st7701_type5_init_operations)
);
// OLED
#define SCREEN_WIDTH 128
#define SCREEN_HEIGHT 64
#define SCREEN_ADDRESS 0x3C
#define OLED_RESET -1
Adafruit_SSD1306 display(SCREEN_WIDTH, SCREEN_HEIGHT, &Wire, OLED_RESET);
2)Backlight control
Control the brightness of the LCD backlight via PWM (ledcWrite).
Serial port input commands 0/1/2/3/4
correspond to different brightness levels.
#define SCREEN_BACKLIGHT_PIN 6
const int pwmFreq = 5000;
const int pwmChannel = 0;
const int pwmResolution = 8;
void setupBacklight() {
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
ledcAttachPin(SCREEN_BACKLIGHT_PIN, pwmChannel);
ledcWrite(pwmChannel, 255); //
}
if (str_uart == "0") { ledcWrite(pwmChannel, 0); }
else if (str_uart == "1") { ledcWrite(pwmChannel, 64); }
else if (str_uart == "2") { ledcWrite(pwmChannel, 128);}
else if (str_uart == "3") { ledcWrite(pwmChannel, 192);}
else if (str_uart == "4") { ledcWrite(pwmChannel, 255);}
3)Touch input
Read touch coordinates via the CST8XX controller.
Touch data is connected to the LVGL input driver.
Supports left and right swipe gestures to switch between UI interfaces.
#include <Adafruit_CST8XX.h>
Adafruit_CST8XX tsPanel = Adafruit_CST8XX();
void my_touchpad_read(lv_indev_drv_t *indev_driver, lv_indev_data_t *data) {
if (tsPanel.touched()) {
CST_TS_Point p = tsPanel.getPoint(0);
data->point.x = p.x;
data->point.y = p.y - 20;
data->state = LV_INDEV_STATE_PR;
// Simple swipe recognition
static int last_x = 0;
if (abs(p.x - last_x) > 50) {
if (p.x > last_x) { Serial.println("Swipe right -> Next page"); }
else { Serial.println("Swipe left -> Previous page"); }
}
last_x = p.x;
} else {
data->state = LV_INDEV_STATE_REL;
}
}
4)Encoder and buttons
Encoder A/B phase detection rotation.
Buttons support single click/double click.
#define ENCODER_A_PIN 42
#define ENCODER_B_PIN 4
#define ENCODER_SW_PIN 5
volatile int8_t encoderPos = 0;
void IRAM_ATTR readEncoder() {
int A = digitalRead(ENCODER_A_PIN);
int B = digitalRead(ENCODER_B_PIN);
if (A == B) encoderPos++;
else encoderPos--;
}
void setupEncoder() {
pinMode(ENCODER_A_PIN, INPUT_PULLUP);
pinMode(ENCODER_B_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), readEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_B_PIN), readEncoder, CHANGE);
}
5)Serial port command interaction
Serial port commands control screen color / backlight / WiFi / BLE / OLED / restart.
void processStrFromUart(String str_uart) {
if (str_uart == "r") { gfx->fillScreen(RED); }
else if (str_uart == "g") { gfx->fillScreen(GREEN); }
else if (str_uart == "b") { gfx->fillScreen(BLUE); }
else if (str_uart == "w") { gfx->fillScreen(WHITE); }
else if (str_uart == "R") { ESP.restart(); }
else if (str_uart == "dW") { gfx->print("WiFi"); }
else if (str_uart == "W") { wifiConnect_sta(); }
else if (str_uart == "q") { wifiDisconnect_sta(); }
else if (str_uart == "i") { wifiInfo(); }
else if (str_uart == "dB") { gfx->print("BLE"); bleON(); }
else if (str_uart == "O") { oled_test(); }
else if (str_uart == "o") { oled_stop(); }
}
6)WiFi functionality
Supports STA mode, connects to WiFi hotspots.
Provides connection, disconnection, and query functions.
#include <WiFi.h>
String wifiId = "yourSSID";
String wifiPwd = "yourPASSWORD";
void wifiConnect_sta() {
WiFi.begin(wifiId.c_str(), wifiPwd.c_str());
int i = 0;
while ((i < 20) && (!WiFi.isConnected())) {
delay(500); i++;
}
if (WiFi.isConnected()) Serial.println("WiFi Connected!");
}
void wifiDisconnect_sta() {
WiFi.disconnect(true);
Serial.println("WiFi Disconnected");
}
void wifiInfo() {
Serial.printf("wifiId:%s\nwifiPwd:%s\n", wifiId.c_str(), wifiPwd.c_str());
if (WiFi.isConnected()) {
Serial.printf("IP: %s\n", WiFi.localIP().toString().c_str());
}
}
7)BLE functionality
Provides services and features as a BLE Server.
Broadcast device name: ESP32S3_2.1_BLE_Server
.
#include <BLEDevice.h>
#include <BLEServer.h>
#define BLE_SERVICE_UUID "4fafc201-1fb5-459e-8fcc-c5c9c331914b"
#define BLE_CHARACTERISTIC_UUID "beb5483e-36e1-4688-b7f5-ea07361b26a8"
BLEServer *pBLEserver;
BLEService *pBLEservice;
BLECharacteristic *pBLEcharacteristic;
void bleInit() {
BLEDevice::init("ESP32S3_2.1_BLE_Server");
pBLEserver = BLEDevice::createServer();
pBLEservice = pBLEserver->createService(BLE_SERVICE_UUID);
pBLEcharacteristic = pBLEservice->createCharacteristic(
BLE_CHARACTERISTIC_UUID,
BLECharacteristic::PROPERTY_READ | BLECharacteristic::PROPERTY_NOTIFY
);
pBLEcharacteristic->setValue("Hello from BLE");
pBLEservice->start();
pBLEserver->getAdvertising()->start();
Serial.println("BLE Service Started");
}
void bleON() { bleInit(); }
Upload the Code¶
1.After completing the installation of the ESP32 board according to "Get Started with Arduino IDE" and the installation of the library according to "Install Libraries", open the program and connect the CrowPanel 1.28inch-HMI ESP32 Rotary Display to the computer via a USB-C cable.
2.Select Board: click "Tools" -> "Board" -> "esp32" and select "ESP32S3 Dev Module",Under the "Tools" menu, see "Flash Size" select 16MB(128Mb); "Partition scheme" and select "Huge APP(3MB No OTA/1MB SPIFFS)"; "PSRAM" select "OPI PSRAM"
Note: The factory program here contains a lot of content, and the app0
partition is too small. It needs to be repartitioned. Refer to this document for partitioning instructions.¶
modify sizes of app0 and spiffs.(1).pdf
3.The download cable connects the knob screen to the computer.
4.Select Port
5.Upload the code: click the "Upload" icon to upload the code.
Display effect:¶
Simple example:¶
Encoder_code:¶
The encoder rotates and prints different values via a serial port.
#define ENCODER_A_PIN 42
#define ENCODER_B_PIN 4
volatile int encoderPos = 0;
volatile int lastEncoded = 0;
void IRAM_ATTR updateEncoder() {
int MSB = digitalRead(ENCODER_A_PIN);
int LSB = digitalRead(ENCODER_B_PIN);
int encoded = (MSB << 1) | LSB;
int sum = (lastEncoded << 2) | encoded;
if(sum == 0b1101 || sum == 0b0100 || sum == 0b0010 || sum == 0b1011) encoderPos++;
if(sum == 0b1110 || sum == 0b0111 || sum == 0b0001 || sum == 0b1000) encoderPos--;
lastEncoded = encoded;
}
void setup() {
Serial.begin(115200);
pinMode(ENCODER_A_PIN, INPUT_PULLUP);
pinMode(ENCODER_B_PIN, INPUT_PULLUP);
attachInterrupt(digitalPinToInterrupt(ENCODER_A_PIN), updateEncoder, CHANGE);
attachInterrupt(digitalPinToInterrupt(ENCODER_B_PIN), updateEncoder, CHANGE);
}
void loop() {
static int lastPos = 0;
if (encoderPos != lastPos) {
Serial.print("Encoder Position: ");
Serial.println(encoderPos);
lastPos = encoderPos;
}
delay(10);
}
Operational effect, serial port viewing encoder data.
Note that if you use USB-5V-IN to view serial port data, you need to enable USB cdc on boot in the download settings here.
PWM_backlight_control:¶
Simple PWM backlight control example
// Simple PWM backlight control example
#define SCREEN_BACKLIGHT_PIN 6
const int pwmFreq = 5000;
const int pwmChannel = 0;
const int pwmResolution = 8;
void setup() {
ledcSetup(pwmChannel, pwmFreq, pwmResolution);
ledcAttachPin(SCREEN_BACKLIGHT_PIN, pwmChannel);
// Set the backlight brightness (0-255), for example, 128 is half brightness.
ledcWrite(pwmChannel, 128);
}
void loop() {
// You can dynamically adjust the backlight brightness here.
// For example: breathing light effect.
static int brightness = 0;
static int fadeAmount = 5;
ledcWrite(pwmChannel, brightness);
brightness += fadeAmount;
if (brightness <= 0 || brightness >= 255) {
fadeAmount = -fadeAmount;
}
delay(20);
}
Resource:¶
github:¶
CrowPanel-2.1inch-HMI-ESP32-Rotary-Display-480-480-IPS-Round-Touch-Knob-Screen
How to buy¶
Please visit this page to purchase CrowPanel 2.1inch-HMI ESP32 Rotary Display.
Support¶
If you have any problem about how to use it, you can connect to us at the bottom-right of bazzer or contact to techsupport@elecrow.com to get technology support.