Skip to content

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.

feature_of_2.1inch_rotary_knob_screen-ezgif.com-jpg-to-webp-converter

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:


CrowPanel2.1inchRotary-2

ESP32-S3 with display and touch schematic diagram

Schematic Diagram:

CrowPanel2.1inchRotary-3

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.

CrowPanel1.28inchRotary-1

Please click the card below to learn how to install Arduino IDE, and install ESP32 board in the Arduino IDE.

GetStartedWithArduinoIDE.webp

Introduction to the factory default sample program:

display effect

CrowPanel1.28inchRotary-2

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.

GetStartedWithSquareLine

UI engineering files and code resources currently available on GitHub:

CrowPanel-2.1inch-HMI-ESP32-Rotary-Display-480-480-IPS-Round-Touch-Knob-Screen

CrowPanel2.1inchRotary-5

Importing UI projects using SquareLine Studio:

Click “Import Project” in the lower right corner to import the UI project we provided.

CrowPanel2.1inchRotary-6

After importing, the project will appear in the list. Double-click to open the factory.

CrowPanel2.1inchRotary-7

CrowPanel2.1inchRotary-8

You can directly export UI files, use the UI files we provide, or modify the UI project yourself to customize your settings.

CrowPanel2.1inchRotary-9

CrowPanel2.1inchRotary-10

Main program introduction section

Click on the GitHub link download to download the code, and use Arduino to open.

CrowPanel2.1inchRotary-11

Click on the GitHub link download 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.

SLS-UI-36

Core Hardware

  1. ESP32-S3 microcontroller chip

  2. 2.1-inch 480x480 IPS circular touchscreen (ST7701 RGB interface)

  3. Capacitive touchscreen chip (e.g., CST8XX series)

  4. Rotary encoder (with buttons)

  5. PCF8574 I2C expansion I/O chip

  6. WiFi & BLE wireless communication module (integrated into ESP32-S3)

①Main library dependencies

  1. lvgl and lv_demos: Used for graphical user interface display and demonstrations

  2. Arduino_GFX_Library: Drives screen display

  3. WiFi.h and WiFiMulti.h: WiFi connection management

  4. Adafruit_SSD1306 and Adafruit_GFX: OLED display drivers

  5. BLEDevice, BLEServer, BLEUtils: Bluetooth BLE communication

  6. Adafruit_CST8XX: Capacitive touchscreen driver

  7. PCF8574: I2C expansion I/O chip driver

  8. 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"

CrowPanel1.28inchRotary-10

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.

CrowPanel2.1inchRotary-13

4.Select Port

select-port

5.Upload the code: click the "Upload" icon to upload the code.

upload-the-code

Display effect:

CrowPanel2.1inchRotary-12

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.

CrowPanel2.1inchRotary-14

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.

CrowPanel2.1inchRotary-15

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.