Build an LVGL IoT Dashboard with CrowPanel ESP32 3.5" SPI TFT Display
CrowPanel ESP32 • DHT11 • LVGL • Bluetooth Serial

Build an Environmental Monitoring Dashboard with CrowPanel 3.5" HMI ESP32 Display

This tutorial shows how to build an Environmental Monitoring Dashboard using the CrowPanel 3.5" HMI ESP32 Display, DHT11 Temperature and Humidity Sensor, LVGL, TFT_eSPI, and Bluetooth Serial. The project reads temperature and humidity data, displays the values on an LVGL dashboard, and sends the sensor readings through Bluetooth Serial.

Environmental Monitoring CrowPanel ESP32 DHT11 Sensor Bluetooth Control LVGL Dashboard
CrowPanel ESP32 3.5 SPI TFT Display

CrowPanel ESP32 3.5 SPI TFT Display used for the environmental monitoring dashboard.

Overview

This tutorial demonstrates how to create a compact environmental monitoring system using an ESP32-based CrowPanel display and a DHT11 sensor. The dashboard displays temperature and humidity readings on the screen, sends the values through Bluetooth Serial, and allows the screen backlight to be controlled remotely using simple Bluetooth commands.

Project Use Case: This project is useful for indoor climate dashboards, sensor display panels, classroom IoT demonstrations, basic environmental monitoring prototypes, and compact control panels where users need both local display output and Bluetooth-based monitoring.

Hardware Components

CrowPanel 3.5" HMI ESP32 Display

ESP32-based display module used as the main controller and visual dashboard for the project.

3.5" SPI TFT LCD Display

Built-in 480×320 display used to show the LVGL environmental monitoring dashboard.

DHT11 Temperature and Humidity Sensor

External sensor used to read temperature and humidity values for the dashboard.

Other Hardware

  • Resistive touch panel
  • Jumper wires
  • USB cable for programming
  • Computer or laptop for uploading the Arduino project

Project Files

  • LVGL_SPI_.ino
  • README.md
  • User_Setup.h
  • User_Setup_Select.h
  • lv_demo_widgets.c

Software Used

Development and Board Tools

  • Arduino IDE 2.3.7
  • ESP32 Board Package by Espressif Systems version 2.0.17
  • Serial Monitor
  • Bluetooth terminal app or PC Bluetooth Serial tool

Libraries and Features

  • LVGL Library version 8.3.11
  • TFT_eSPI Library version 2.5.43
  • DHT Sensor Library by Adafruit
  • Adafruit Unified Sensor Library
  • Bluetooth Serial Library

Application Discussion

The CrowPanel 3.5" HMI ESP32 Display combines an ESP32 controller, SPI TFT LCD, and resistive touch input. The DHT11 sensor provides temperature and humidity readings, while LVGL and TFT_eSPI work together to create and render the dashboard interface.

CrowPanel 3.5" HMI ESP32 Display

The CrowPanel is an ESP32-based display module with a 480×320 SPI TFT LCD and resistive touch input. It is useful for graphical dashboards, control panels, and sensor monitoring interfaces.

DHT11 Sensor

The DHT11 sensor measures temperature and humidity. In this project, the readings are displayed on the CrowPanel screen and transmitted through Bluetooth Serial approximately every 2 seconds.

Bluetooth Serial

Bluetooth Serial allows the ESP32 to send sensor readings wirelessly and receive simple control commands, such as turning the screen backlight ON or OFF.

LVGL and TFT_eSPI

LVGL is used to create the graphical user interface with widgets such as charts, gauges, panels, labels, and indicators. TFT_eSPI handles communication between the ESP32 and the SPI TFT display, making it important for proper screen initialization, rendering, color output, and display stability.

Hardware Setup

Schematic and Hardware Connections

A schematic or wiring diagram is applicable for this project because an external DHT11 Temperature and Humidity Sensor is connected to the CrowPanel ESP32 board.

Schematic diagram for CrowPanel ESP32 environmental monitoring dashboard

Schematic diagram for connecting the DHT11 sensor to the CrowPanel ESP32 board.

DHT11 to ESP32 Connections
DHT11 VCC
ESP32 3.3V
DHT11 GND
ESP32 GND
DHT11 DATA
GPIO 32
Built-in Display Connections
TFT Display
Built into CrowPanel
Resistive Touch
Built into CrowPanel
Programming
USB cable to computer
CrowPanel ESP32 3.5 SPI TFT Display setup with DHT11

Actual setup of the CrowPanel ESP32 3.5 SPI TFT Display with DHT11 sensor.

Important: If using a bare DHT11 sensor, add a 10K pull-up resistor between the DATA pin and VCC. The CrowPanel display already includes the TFT display and resistive touch interface, so no separate display wiring is required.

Assembly Instructions

1

Connect Sensor Power

Connect the DHT11 VCC pin to the 3.3V pin of the ESP32.

2

Connect Sensor Ground

Connect the DHT11 GND pin to the GND pin of the ESP32.

3

Connect Sensor Data

Connect the DHT11 DATA pin to GPIO 32 of the ESP32.

4

Connect the CrowPanel

Connect the CrowPanel 3.5" HMI ESP32 Display to the computer using a USB cable.

5

Upload the Arduino Sketch

Upload the Arduino sketch using the correct board settings. After uploading, the LVGL environmental monitoring dashboard should appear on the display.

Software Setup

Download the Project Files

Download or clone the project repository before continuing. It contains the Arduino source code, LVGL UI file, TFT_eSPI configuration files, and project notes used in this tutorial.

Project Repository: github.com/createlabz/crowpanel-3.5-hmi-esp32-spi-environment-dashboard
1

Download the Repository

Open the repository, click the Code button, select Download ZIP, and extract the ZIP file on your computer.

2

Open the Arduino Project

Open the Arduino project file named LVGL_SPI_.ino using Arduino IDE.

3

Install the Required Libraries

Install LVGL, TFT_eSPI, DHT Sensor Library by Adafruit, and Adafruit Unified Sensor Library.

4

Upload and Test

Select the correct board, port, upload speed, and PSRAM setting, then upload the sketch.

Tested Software Versions
Arduino IDE
2.3.7
ESP32 Board Package
2.0.17
LVGL
8.3.11
TFT_eSPI
2.5.43
DHT Sensor Library
Latest Version
Board Settings
Board
ESP32 Dev Module
Flash Frequency
80 MHz
Upload Speed
921600
PSRAM
Enabled
TFT_eSPI configuration: Open Arduino/libraries/TFT_eSPI/User_Setup_Select.h and enable the configuration that matches the CrowPanel 3.5" SPI display. Incorrect configuration may cause a white screen, incorrect colors, display initialization failure, or touch issues.

Code

The following Arduino sketch initializes the TFT display, LVGL, touch input, DHT11 sensor, Bluetooth Serial, PSRAM frame buffer, and Bluetooth ON/OFF backlight control.

LVGL_SPI_.ino
#define LV_CONF_INCLUDE_SIMPLE

#include <lvgl.h>
#include <TFT_eSPI.h>
#include "esp_heap_caps.h"

/* ===== BLUETOOTH SERIAL ===== */
#include "BluetoothSerial.h"
BluetoothSerial SerialBT;

/* ===== DHT SENSOR ===== */
#include <DHT.h>

#define DHTPIN 32
#define DHTTYPE DHT11

DHT dht(DHTPIN, DHTTYPE);

/* Global sensor values for LVGL */
float g_temperature = 0;
float g_humidity = 0;

extern "C" {
  #include <demos/widgets/lv_demo_widgets.h>
}

TFT_eSPI tft = TFT_eSPI();

/* ================= Screen Settings ================= */
static const uint16_t screenWidth = 480;
static const uint16_t screenHeight = 320;

/* ================= LVGL Buffer ================= */
static lv_disp_draw_buf_t draw_buf;
static lv_color_t *buf1 = NULL;

/* ================= LVGL Tick Timer ================= */
hw_timer_t * lv_timer = NULL;

void IRAM_ATTR onTimer() {
  lv_tick_inc(1);
}

/* ================= Display Flush ================= */
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, w * h, true);
  tft.endWrite();

  lv_disp_flush_ready(disp);
}

/* ================= Touch Read ================= */
void my_touchpad_read(lv_indev_drv_t *indev_driver,
                      lv_indev_data_t *data)
{
  uint16_t x, y;

  if (tft.getTouch(&x, &y, 40))
  {
    data->state = LV_INDEV_STATE_PR;
    data->point.x = x;
    data->point.y = y;
  }
  else
  {
    data->state = LV_INDEV_STATE_REL;
  }
}

/* ================= Setup ================= */
void setup()
{
  Serial.begin(115200);

  /* Backlight pin */
  pinMode(27, OUTPUT);
  digitalWrite(27, HIGH);

  /* Start Bluetooth Serial */
  SerialBT.begin("CrowPanel_Control");
  Serial.println("Bluetooth Serial started");

  /* Start DHT sensor */
  dht.begin();

  tft.init();
  tft.setRotation(1);
  tft.setSwapBytes(true);

  uint16_t calData[5] = { 292, 3607, 302, 3486, 7 };
  tft.setTouch(calData);

  tft.fillScreen(TFT_BLACK);

  lv_init();

  /* Allocate FULL frame buffer in PSRAM */
  buf1 = (lv_color_t *)heap_caps_malloc(
    screenWidth * screenHeight * sizeof(lv_color_t),
    MALLOC_CAP_SPIRAM
  );

  if (!buf1) {
    Serial.println("PSRAM allocation failed!");
    while (1);
  }

  lv_disp_draw_buf_init(&draw_buf, buf1, NULL,
                        screenWidth * screenHeight);

  /* 1ms LVGL tick timer */
  lv_timer = timerBegin(0, 80, true);
  timerAttachInterrupt(lv_timer, &onTimer, true);
  timerAlarmWrite(lv_timer, 1000, true);
  timerAlarmEnable(lv_timer);

  /* Register display */
  static lv_disp_drv_t disp_drv;
  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);

  /* Register touch */
  static lv_indev_drv_t indev_drv;
  lv_indev_drv_init(&indev_drv);
  indev_drv.type = LV_INDEV_TYPE_POINTER;
  indev_drv.read_cb = my_touchpad_read;
  lv_indev_drv_register(&indev_drv);

  /* Load LVGL demo */
  lv_demo_widgets();
}

/* ================= Loop ================= */
void loop()
{
  lv_timer_handler();

  /* ===== Read DHT11 every ~2 seconds ===== */
  static unsigned long lastRead = 0;

  if (millis() - lastRead > 2000) {
    float t = dht.readTemperature();
    float h = dht.readHumidity();

    if (!isnan(t) && !isnan(h)) {
      g_temperature = t;
      g_humidity = h;

      Serial.print("Temp: ");
      Serial.print(t);
      Serial.print(" Hum: ");
      Serial.println(h);

      SerialBT.print("Temp:");
      SerialBT.print(t);
      SerialBT.print("C Hum:");
      SerialBT.print(h);
      SerialBT.println("%");
    }

    lastRead = millis();
  }

  /* ===== Bluetooth command handler ===== */
  if (SerialBT.available()) {
    String cmd = SerialBT.readStringUntil('\n');
    cmd.trim();

    Serial.print("Received: ");
    Serial.println(cmd);

    if (cmd == "ON") {
      digitalWrite(27, HIGH);
      SerialBT.println("Screen ON");
    }

    if (cmd == "OFF") {
      digitalWrite(27, LOW);
      SerialBT.println("Screen OFF");
    }
  }
}

Code Breakdown / Configuration Breakdown

Libraries and Tools Used

The project uses LVGL for the graphical dashboard, TFT_eSPI for the display driver, DHT library for temperature and humidity readings, and BluetoothSerial for wireless monitoring and command control.

Important Pins and Settings

The DHT11 data pin is connected to GPIO 32. The screen backlight control uses GPIO 27. The dashboard resolution is set to 480×320.

Initialization

The setup initializes Serial communication, Bluetooth Serial, DHT11, TFT display, touch calibration, LVGL, PSRAM buffer, LVGL timer, display driver, input driver, and the LVGL widgets demo.

Main Operation

The loop keeps LVGL running, reads temperature and humidity approximately every 2 seconds, sends the readings to Serial and Bluetooth, and checks Bluetooth commands.

Bluetooth Commands

Sending ON through Bluetooth turns the screen backlight on. Sending OFF turns the screen backlight off.

Expected Output

The dashboard should appear on the CrowPanel display, and Bluetooth Serial should show readings such as Temp:29C Hum:65%.

Documentation / Output Guide

After uploading the sketch, the LVGL environmental monitoring dashboard should appear on the CrowPanel display. The DHT11 readings should update approximately every 2 seconds and can also be viewed through Bluetooth Serial.

Expected Output / Behavior
Dashboard Display
Temperature and humidity values appear on the LVGL dashboard.
Bluetooth Output
Sensor readings are sent through Bluetooth Serial, such as Temp:29C Hum:65%.
ON Command
Turns the screen backlight ON.
OFF Command
Turns the screen backlight OFF.

Troubleshooting

PSRAM allocation failed

Enable PSRAM in Arduino IDE under the board settings.

White screen

Check the TFT_eSPI configuration and make sure it matches the CrowPanel 3.5" SPI display.

Touch not accurate

Recalibrate the touch panel and update the tft.setTouch(calData); values.

Bluetooth not appearing

Make sure the ESP32 board supports Bluetooth Classic SPP.

Video Demonstration

The testing video shows the CrowPanel dashboard running and displaying the environmental monitoring interface.

Watch on YouTube

Conclusion

This project demonstrates how to build an Environmental Monitoring Dashboard using the CrowPanel 3.5" HMI ESP32 Display, LVGL, TFT_eSPI, DHT11 sensor, and Bluetooth Serial. The project successfully reads temperature and humidity values, displays them on an LVGL dashboard, and sends the readings through Bluetooth Serial. It also allows the screen backlight to be controlled remotely using Bluetooth commands.

This project can be improved by adding air quality sensors such as MQ135, BME680, or SGP30, WiFi cloud monitoring, MQTT support, SD card data logging, a mobile monitoring application, historical temperature and humidity charts, warning indicators, and custom LVGL widgets.

Temperature Monitoring Humidity Monitoring Bluetooth Serial Backlight Control MQTT SD Card Logging Custom LVGL Widgets

References

These are the websites and documentation sources used as references. They are listed as names or plain website addresses only.

Arduino
Espressif Systems
LVGL Documentation
TFT_eSPI by Bodmer
Adafruit DHT Sensor Library
Adafruit Unified Sensor Library
Elecrow CrowPanel Documentation
CreateLabz GitHub Repository
CreateLabz CrowPanel 3.5 HMI ESP32 Environment Dashboard Repository
github.com/createlabz/crowpanel-3.5-hmi-esp32-spi-environment-dashboard
github.com/createlabz/lvgl
youtube.com/shorts/-G3fhEvk6ik?feature=share
3.5-inchCrowpanelDashboardElecrowEsp32Iot dashboardLovyangfxLvglSpi tft

Leave a comment

All comments are moderated before being published