Skip to content

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

ComponentRecommendedAlternative
MicrocontrollerESP32 DevKit V1ESP32-S3, ESP32-C3
Display3.5" ILI9488 TFT (480x320)2.8" ILI9341 (320x240)
Temperature/HumidityDHT22 (AM2302)BME280, SHT30
Light SensorBH1750LDR + ADC
Relay Module4-channel 5V relayMOSFET module for LED strips
Power5V 2A USB supply3.7V LiPo + boost converter
Enclosure3D printed caseProject 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

  1. Open lopaka.app in your browser
  2. Click "New Project"
  3. Select ESP32 as the target platform
  4. Enter display resolution: 480 x 320 (or your display dimensions)
  5. Name your project: "Smart Home Dashboard"
  6. 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.

  1. Background rectangle:

    • Drag a Rectangle widget to the top
    • Position: (0, 0), Size: (480, 40)
    • Background color: #1e293b (dark slate)
  2. 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
  3. Title:

    • Drag a Label widget
    • Position: (44, 10), Size: (250, 20)
    • Text: "Smart Home Dashboard"
    • Font: LV_FONT_DEFAULT_16, color: #e2e8f0
  4. 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

  1. Card background:

    • Drag a Rectangle widget
    • Position: (20, 55), Size: (210, 80)
    • Background color: #0f172a
    • Border radius: 12
    • Border color: #334155, width: 1
  2. Temperature icon:

    • Drag a Label widget
    • Position: (30, 65), Size: (30, 30)
    • Text: "T", font size 24
  3. 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)
  4. 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:

  1. Copy the temperature card (select all widgets, copy, paste)
  2. Move to position (250, 55)
  3. Change icon to "H"
  4. Change value to "45% RH", color: #06b6d4 (cyan)
  5. Change location to "Living Room"

Step 5: Create the Lighting Control Panel

This section combines toggles and sliders for light control.

  1. Panel background:

    • Drag a Rectangle widget
    • Position: (20, 150), Size: (440, 100)
    • Background color: #0f172a
    • Border radius: 12
    • Border color: #334155, width: 1
  2. Panel title:

    • Drag a Label widget
    • Position: (35, 158), Size: (200, 20)
    • Text: "Lighting"
    • Font: LV_FONT_DEFAULT_16, color: #e2e8f0
  3. 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%
    • Toggle switch: Position (340, 182), Size: (40, 22)
      • Background when on: #22c55e
      • Set to ON state
    • Label: "60%" at (390, 185), color: #94a3b8
  4. 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%"
  5. 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

Step 6: Create Status Cards

Two smaller cards at the bottom for security and energy monitoring.

Security Card

  1. Card background:

    • Rectangle at (20, 265), Size: (210, 50)
    • Background: #0f172a, border radius: 12, border: #334155
  2. Security icon:

    • Label: "LOCK", position (30, 273), size 30x30, font 20
  3. Status text:

    • Label: "All Clear", position (65, 275), size 150x20
    • Font: LV_FONT_DEFAULT_14, color: #22c55e (green)
  4. Detail text:

    • Label: "3 doors, 2 windows", position (65, 293), size 150x16
    • Font: LV_FONT_DEFAULT_10, color: #64748b

Energy Card

  1. Card background:

    • Rectangle at (250, 265), Size: (210, 50)
    • Background: #0f172a, border radius: 12, border: #334155
  2. Energy icon:

    • Label: "PWR", position (260, 273), size 30x30, font 20
  3. Usage value:

    • Label: "1.2 kWh", position (295, 275), size 150x20
    • Font: LV_FONT_DEFAULT_14, color: #e2e8f0
  4. Detail text:

    • Label: "Today - $0.18", position (295, 293), size 150x16
    • Font: LV_FONT_DEFAULT_10, color: #64748b

Step 7: Add a Second Screen — Settings

A smart home dashboard needs a settings screen for configuration.

  1. In Lopaka, click "Add Screen" in the screen panel
  2. Name it "Settings"
  3. 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.

  1. Select the menu button on the main screen
  2. In the Events panel, add a Click event
  3. Action: Navigate to screen -> "Settings"
  4. On the settings screen, add a back button that navigates to the main screen

Step 9: Export the Code

  1. Click Export in the top toolbar
  2. Select LVGL C code for ESP32
  3. Download the generated files

The export includes:

  • dashboard_ui.c — main screen creation code
  • settings_ui.c — settings screen code
  • ui.h — shared declarations and screen references
  • ui_helpers.c — helper functions for navigation and styling

Step 10: Wire Up Sensor Data

The exported UI is static — now connect real sensor data.

cpp
#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.

cpp
// 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);
}
PartApprox. PriceWhere to Buy
ESP32 DevKit V1$6-8Amazon, AliExpress, Adafruit
3.5" ILI9488 TFT$10-15Amazon, AliExpress
DHT22 Sensor$4-6Amazon, Adafruit
BH1750 Light Sensor$2-3Amazon, AliExpress
4-Channel Relay$4-6Amazon, AliExpress
Jumper wires$3-5Any electronics supplier
Breadboard$3-5Any electronics supplier

Troubleshooting

Display Not Working

  • Verify TFT_eSPI User_Setup.h matches 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_SIZE in lv_conf.h (try 48KB or 64KB)
  • Reduce the number of simultaneous widgets
  • Use LV_MEM_CUSTOM=1 to 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

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.