ESP32 Smart Home Dashboard: Complete UI Design Tutorial
Published on Lopaka.app — The free web-based LVGL GUI builder for embedded developers
Introduction
Smart home dashboards are one of the most popular ESP32 projects — and for good reason. They combine sensor data, user controls, and real-time feedback into a single, satisfying interface.
In this comprehensive tutorial, you will design a complete smart home dashboard UI using Lopaka — the free, web-based LVGL GUI builder — then deploy it to an ESP32 with a 3.5" TFT display. The dashboard will include:
- Temperature and humidity display with live sensor readings
- Lighting controls with on/off toggles and brightness sliders
- Security status panel with door/window indicators
- Weather widget showing current conditions
- Navigation between multiple screens
Estimated completion time: 45-60 minutes for the UI design, plus hardware setup time.
Difficulty level: Intermediate
Hardware Requirements
| Component | Recommended | Alternative |
|---|---|---|
| Microcontroller | ESP32 DevKit V1 | ESP32-S3, ESP32-C3 |
| Display | 3.5" ILI9488 TFT (480x320) | 2.8" ILI9341 (320x240) |
| Temperature/Humidity | DHT22 (AM2302) | BME280, SHT30 |
| Light Sensor | BH1750 | LDR + ADC |
| Relay Module | 4-channel 5V relay | MOSFET module for LED strips |
| Power | 5V 2A USB supply | 3.7V LiPo + boost converter |
| Enclosure | 3D printed case | Project box |
Total estimated cost: $25-45 depending on what you already have.
Software Requirements
- Lopaka — free web-based GUI builder (lopaka.app)
- Arduino IDE or PlatformIO — for ESP32 programming
- LVGL library — v8.x or v9.x
- TFT display driver library — TFT_eSPI recommended
- Sensor libraries — DHT, BH1750, etc.
Step 1: Plan Your Dashboard Layout
Before opening Lopaka, sketch your dashboard layout on paper. A good smart home dashboard follows these principles:
- Most important information first — temperature and time should be prominent
- Logical grouping — related controls together (all lighting in one area)
- Touch-friendly — buttons and sliders should be at least 40x40 pixels
- Consistent spacing — use a grid system for alignment
- Color coding — use colors to indicate status (green = on, red = alert, gray = off)
For a 480x320 display, we will design this layout:
+-----------------------------------------------------+
| [=] Smart Home Dashboard [72 deg F] | <- Header (40px)
+-----------------------------------------------------+
| |
| +--------------+ +--------------+ |
| | TEMP 72.5F | | HUM 45% RH | <- Sensor cards
| | Living Room| | Living Room| |
| +--------------+ +--------------+ |
| |
| +-------------------------------------------+ |
| | LIGHTING | |
| | Kitchen: [====|=====] 60% [ON] | | <- Controls
| | Bedroom: [==|=======] 20% [OFF] | |
| | Porch: [ON] | |
| +-------------------------------------------+ |
| |
| +--------------+ +--------------+ |
| | SECURITY | | ENERGY | <- Status cards
| | All Clear | | 1.2 kWh | |
| +--------------+ +--------------+ |
| |
+-----------------------------------------------------+Step 2: Create the Project in Lopaka
- Open lopaka.app in your browser
- Click "New Project"
- Select ESP32 as the target platform
- Enter display resolution: 480 x 320 (or your display dimensions)
- Name your project: "Smart Home Dashboard"
- Click "Create"
You now have a blank canvas at the correct resolution.
Step 3: Design the Header Bar
The header provides context and quick-access information.
Background rectangle:
- Drag a Rectangle widget to the top
- Position: (0, 0), Size: (480, 40)
- Background color:
#1e293b(dark slate)
Menu icon:
- Drag a Button widget
- Position: (10, 8), Size: (24, 24)
- Background color: transparent
- Add a child Label with text
"=", font size 18, color#94a3b8
Title:
- Drag a Label widget
- Position: (44, 10), Size: (250, 20)
- Text:
"Smart Home Dashboard" - Font:
LV_FONT_DEFAULT_16, color:#e2e8f0
Weather widget:
- Drag a Label widget
- Position: (340, 10), Size: (130, 20)
- Text:
"72 deg F" - Font:
LV_FONT_DEFAULT_14, color:#94a3b8 - Right-aligned
Step 4: Create Sensor Cards
Sensor cards display real-time environmental data.
Temperature Card
Card background:
- Drag a Rectangle widget
- Position: (20, 55), Size: (210, 80)
- Background color:
#0f172a - Border radius: 12
- Border color:
#334155, width: 1
Temperature icon:
- Drag a Label widget
- Position: (30, 65), Size: (30, 30)
- Text:
"T", font size 24
Temperature value:
- Drag a Label widget
- Position: (70, 65), Size: (140, 36)
- Text:
"72.5 deg F" - Font: large (28px or
LV_FONT_DEFAULT_28), color:#f97316(orange)
Location label:
- Drag a Label widget
- Position: (70, 100), Size: (140, 20)
- Text:
"Living Room" - Font:
LV_FONT_DEFAULT_12, color:#64748b
Humidity Card
Duplicate the temperature card and modify:
- Copy the temperature card (select all widgets, copy, paste)
- Move to position (250, 55)
- Change icon to
"H" - Change value to
"45% RH", color:#06b6d4(cyan) - Change location to
"Living Room"
Step 5: Create the Lighting Control Panel
This section combines toggles and sliders for light control.
Panel background:
- Drag a Rectangle widget
- Position: (20, 150), Size: (440, 100)
- Background color:
#0f172a - Border radius: 12
- Border color:
#334155, width: 1
Panel title:
- Drag a Label widget
- Position: (35, 158), Size: (200, 20)
- Text:
"Lighting" - Font:
LV_FONT_DEFAULT_16, color:#e2e8f0
Kitchen light row:
- Label:
"Kitchen:"at (35, 185), color:#94a3b8 - Slider: Position (120, 185), Size: (200, 16)
- Background:
#334155, indicator:#fbbf24(yellow) - Set initial value to 60%
- Background:
- Toggle switch: Position (340, 182), Size: (40, 22)
- Background when on:
#22c55e - Set to ON state
- Background when on:
- Label:
"60%"at (390, 185), color:#94a3b8
- Label:
Bedroom light row:
- Duplicate the kitchen row, move to y-position 215
- Change label to
"Bedroom:" - Set slider to 20%
- Set toggle to OFF state
- Change label to
"20%"
Porch light row:
- Label:
"Porch:"at (35, 242), color:#94a3b8 - Toggle switch only: Position (120, 239), Size: (40, 22)
- Set to ON state
- Label:
"ON"at (175, 242), color:#22c55e
- Label:
Step 6: Create Status Cards
Two smaller cards at the bottom for security and energy monitoring.
Security Card
Card background:
- Rectangle at (20, 265), Size: (210, 50)
- Background:
#0f172a, border radius: 12, border:#334155
Security icon:
- Label:
"LOCK", position (30, 273), size 30x30, font 20
- Label:
Status text:
- Label:
"All Clear", position (65, 275), size 150x20 - Font:
LV_FONT_DEFAULT_14, color:#22c55e(green)
- Label:
Detail text:
- Label:
"3 doors, 2 windows", position (65, 293), size 150x16 - Font:
LV_FONT_DEFAULT_10, color:#64748b
- Label:
Energy Card
Card background:
- Rectangle at (250, 265), Size: (210, 50)
- Background:
#0f172a, border radius: 12, border:#334155
Energy icon:
- Label:
"PWR", position (260, 273), size 30x30, font 20
- Label:
Usage value:
- Label:
"1.2 kWh", position (295, 275), size 150x20 - Font:
LV_FONT_DEFAULT_14, color:#e2e8f0
- Label:
Detail text:
- Label:
"Today - $0.18", position (295, 293), size 150x16 - Font:
LV_FONT_DEFAULT_10, color:#64748b
- Label:
Step 7: Add a Second Screen — Settings
A smart home dashboard needs a settings screen for configuration.
- In Lopaka, click "Add Screen" in the screen panel
- Name it
"Settings" - Design the settings screen with:
- Header (same style as main screen)
- WiFi settings section with SSID and signal strength
- MQTT configuration fields
- Sensor calibration options
- Display brightness slider
- Theme selector (dark/light mode toggle)
Step 8: Add Screen Navigation
Connect the menu button to navigate between screens.
- Select the menu button on the main screen
- In the Events panel, add a Click event
- Action: Navigate to screen ->
"Settings" - On the settings screen, add a back button that navigates to the main screen
Step 9: Export the Code
- Click Export in the top toolbar
- Select LVGL C code for ESP32
- Download the generated files
The export includes:
dashboard_ui.c— main screen creation codesettings_ui.c— settings screen codeui.h— shared declarations and screen referencesui_helpers.c— helper functions for navigation and styling
Step 10: Wire Up Sensor Data
The exported UI is static — now connect real sensor data.
#include <lvgl.h>
#include <DHT.h>
#include "ui.h"
#define DHTPIN 4
#define DHTTYPE DHT22
DHT dht(DHTPIN, DHTTYPE);
// Reference to UI labels (declared in ui.h)
extern lv_obj_t *ui_TempValue;
extern lv_obj_t *ui_HumidValue;
void update_sensor_data(lv_timer_t *timer) {
float temp = dht.readTemperature();
float humid = dht.readHumidity();
if (!isnan(temp)) {
char buf[16];
snprintf(buf, sizeof(buf), "%.1f deg F", temp * 9.0/5.0 + 32);
lv_label_set_text(ui_TempValue, buf);
}
if (!isnan(humid)) {
char buf[16];
snprintf(buf, sizeof(buf), "%.0f%% RH", humid);
lv_label_set_text(ui_HumidValue, buf);
}
}
void setup() {
Serial.begin(115200);
dht.begin();
// Initialize LVGL and display
lv_init();
// ... display driver setup ...
// Create the UI from Lopaka export
ui_init();
// Create a timer to update sensor data every 2 seconds
lv_timer_create(update_sensor_data, 2000, NULL);
}
void loop() {
lv_timer_handler();
delay(5);
}Step 11: Add Touch Input
Connect the slider and toggle events to control relays.
// Event callback for kitchen light slider
void kitchen_slider_event(lv_event_t *e) {
lv_obj_t *slider = lv_event_get_target(e);
int value = lv_slider_get_value(slider);
// Update PWM output for dimming
ledcWrite(KITCHEN_PWM_CHANNEL, value * 255 / 100);
// Update percentage label
char buf[8];
snprintf(buf, sizeof(buf), "%d%%", value);
lv_label_set_text(ui_KitchenPercentLabel, buf);
}
// Event callback for toggle switch
void porch_toggle_event(lv_event_t *e) {
lv_obj_t *toggle = lv_event_get_target(e);
bool state = lv_obj_has_state(toggle, LV_STATE_CHECKED);
digitalWrite(PORCH_RELAY_PIN, state ? HIGH : LOW);
lv_label_set_text(ui_PorchStatusLabel, state ? "ON" : "OFF");
}
void setup() {
// ... previous setup code ...
// Register event callbacks
lv_obj_add_event_cb(ui_KitchenSlider, kitchen_slider_event, LV_EVENT_VALUE_CHANGED, NULL);
lv_obj_add_event_cb(ui_PorchToggle, porch_toggle_event, LV_EVENT_VALUE_CHANGED, NULL);
}Complete Parts List with Links
| Part | Approx. Price | Where to Buy |
|---|---|---|
| ESP32 DevKit V1 | $6-8 | Amazon, AliExpress, Adafruit |
| 3.5" ILI9488 TFT | $10-15 | Amazon, AliExpress |
| DHT22 Sensor | $4-6 | Amazon, Adafruit |
| BH1750 Light Sensor | $2-3 | Amazon, AliExpress |
| 4-Channel Relay | $4-6 | Amazon, AliExpress |
| Jumper wires | $3-5 | Any electronics supplier |
| Breadboard | $3-5 | Any electronics supplier |
Troubleshooting
Display Not Working
- Verify TFT_eSPI
User_Setup.hmatches your display pins - Check SPI connections (MOSI, MISO, SCK, CS, DC, RST)
- Ensure power supply can deliver enough current (TFT displays can draw 200-300mA)
Touch Not Responding
- Verify touch controller type (XPT2046 is common on ILI9488 modules)
- Calibrate touch using the TFT_eSPI touch calibration sketch
- Check touch CS pin is correctly defined
LVGL Memory Issues
- Increase
LV_MEM_SIZEinlv_conf.h(try 48KB or 64KB) - Reduce the number of simultaneous widgets
- Use
LV_MEM_CUSTOM=1to use heap allocation
Sensor Readings Unreliable
- Add a 10K pull-up resistor to DHT22 data pin
- Use shielded cable for sensor connections over 1 meter
- Add software filtering (moving average) for smoother readings
Next Steps
Now that your smart home dashboard is working, consider these enhancements:
- MQTT integration — connect to Home Assistant or OpenHAB
- OTA updates — enable wireless firmware updates
- Multiple rooms — add tab navigation for different rooms
- Graphs and charts — display temperature history over time
- Voice control — integrate with Alexa or Google Home
- Enclosure — 3D print a custom case for a polished look
Why Lopaka?
Lopaka makes embedded UI design accessible to everyone. Instead of spending hours positioning widgets by trial and error, you can:
- Design visually with drag-and-drop in your browser
- See changes instantly without compiling or flashing
- Export clean LVGL code ready for ESP32 deployment
- Iterate quickly — try different layouts in minutes, not hours
- Free forever — no limitations, no watermarks, no signup
Start designing your smart home dashboard at lopaka.app — no download required.
Join the Community
- Discord: Join the Lopaka community for help and project sharing
- GitHub: Star the project and contribute
- Twitter: Follow @lopaka_app for tips and updates
Share your smart home dashboard projects with us — we love seeing what the community builds!
This tutorial was written for Lopaka.app — the free web-based LVGL GUI builder. Built by embedded developers, for embedded developers.