Skip to content

Nextion Touch Panel

Every room already has a control surface on the wall at the right height. This replaces one with a screen: a 5-inch Nextion touchscreen and an ESP32 in a shell 13.4 mm deep, showing eight room buttons, eight scenes and a brightness slider. The Nextion draws its own pages and handles its own touches on its own processor, so the ESP32 never renders anything — it translates between a serial port and Home Assistant, which is why a panel this cheap still feels instant.

The ESPHome config isn’t in the folder. What is here is everything either side of it: the printed shells and wall plates, the Fusion sources, the Nextion HMI project and the 48 px icon set that goes on it. The display’s whole interface is a handful of named components and text variables, and the sections below set every one of them out — so this is a page you build and print from, and write the middle of yourself.

What’s on the screen

Three pages, one navigation strip across all of them.

  • Home (page0) — eight buttons, home_button1 through home_button8.
  • Scenes (page1) — eight more, scene_button1 through scene_button8.
  • Settings (page2) — a single slider labelled Screen Brightness.
  • The nav striptab1, tab2 and tab3 jump to Home, Scenes and Settings, and panic_button sits between them with no local behaviour at all. It does whatever the host decides a panic button does.

The three tabs are dual-state buttons and they mark themselves: each page’s load event sets its own tab’s val to 1 and the other two to 0, so the host never has to know which page is showing.

None of the sixteen room and scene buttons carries a line of its own event code. Nothing happens on the display when you press one; the press leaves as a Nextion touch event and the host acts on it, which in ESPHome arrives as the nextion component’s touch trigger carrying a page id and a component id.

Every label is remote too. Each page keeps a set of invisible text variables — id_h_b1 to id_h_b8 for Home, id_s_b1 to id_s_b8 for Scenes, id_nav_l1 to id_nav_l4 for the strip — and the page’s load event plus a repeating timer copy them onto the visible buttons. Write a label once into the variable and it survives a page change, a redraw and a walk back into the room. Until something does, the panel shows what is baked in: STAIRS, PLAYROOM, BASEMENT, Outside Off, and four tabs that say Label 1 through Label 4.

Brightness works the same way. The slider on Settings writes both the display’s own dim and a variable called page0.remote_dim.val, and every page’s dim_timer re-applies dim from that variable. So the host sets brightness by writing remote_dim, not dim — see Troubleshooting for what happens if you get that backwards.

Parts

Some links below are Amazon affiliate links. As an Amazon Associate I earn from qualifying purchases — at no extra cost to you. It helps keep these guides free. Outside the US, they should send you to your own Amazon store; if one doesn't, searching the part number there will find it.

  • 5-inch Nextion HMI touchscreen, 800×480 — the panel everything here is cut for. Both front parts open a 119.5 × 78.6 mm hole for the module and the bezel’s own window is 111.3 × 67.9 mm over it, and the back shell’s shelf sits the board between two ribs 121.5 mm apart. Those are 5-inch numbers and nothing else’s.
  • Nextion Enhanced 3.5 in NX4832K035 with the IO expansion boardthe smaller panel, and a substitute rather than an alternative. It is 480×320 where bruh_nextion_5_inch_scene_ui_v3_oct.hmi is drawn for 800×480, so every page has to be laid out again, and none of the printed parts in this folder fit it. Buy this one if you want to redraw the UI small; buy the 5-inch if you want to load the HMI that’s already here and be done.
  • ESP32 development board, 38-pin narrow, 2-pack — the host. The bay in the back shell is 29.5 mm wide and about 10 mm deep, which is a 38-pin narrow board with two millimetres either side. A wide 30 mm-plus board does not go in.
  • 32 GB microSD card — how the HMI gets onto the display. Nextion’s card loader wants FAT32 and small; 32 GB is the safe ceiling, which is why this and not the 256 GB card already in the drawer. If nothing on your desk has a card slot, a USB card reader is the other half of that job.
  • 5 V 2.5 A supply and a right-angle 1 ft micro-USB cable — the simple way to power it. The right-angle plug is what lets the shell sit flat; there is an 8.5 mm gap in the rail along the bottom of the bay and that is the only way out for a cable.
  • Isolated 12–72 V to 5 V converter with a USB socket — if there is already a low-voltage rail behind the wall, tap that instead of running another cable.
  • HLK-PM01 mains-to-5 V modules, 10-pack — the in-wall option, small enough to live in a switch box. Read the caution under Power before you order these.
  • Female-to-female jumper leads — four of them is the entire harness between the two boards. Nextion modules come with a 4-wire lead; these go on the other end of it.
  • Lever-nut connectors — one in, four out, which is exactly the shape of the 5 V split the caution under Wiring asks for. No iron, and you can undo it.
  • 24 AWG silicone hookup wire — if you would rather solder than jumper.
  • M3 heat-set inserts and an M3 countersunk screw kit — for anything you expect to open twice.
  • #6-32 wall-plate screws, 100-pack — the printed plates are drilled 3 mm and countersunk for a flat #6 head, and the screws that came with your switch are always 3 mm too short for a printed plate anyway.
  • Matte PLA for the plates and the bezel, PLA+ for the shells. Matte on the visible parts, and it is not a preference — a glossy wall plate at eye level shows every layer line under a ceiling light.
  • A needle file set — cheap, and you will use it twice: once on the display window and once on the plate screw holes. Both jobs go wrong when you reach for a drill instead.
  • XTC-3D print coating — optional, and the difference between a printed plate that looks printed and one that looks moulded. Brush it on the face, sand it back, paint it.
  • VHB tape or a drywall and hollow-wall anchor kit — how the shell gets onto the wall, depending on whether you ever plan to take it down.

If you would rather buy the trim than print it, the printed plates are copies of Leviton’s oversized 1-gang and oversized 2-gang Decora plates — same footprint, same opening, and they cost less than the filament.

The printed parts

Eight STLs covering two separate jobs: the panel enclosure, and the wall trim that surrounds it. Every number here is measured off the mesh.

FileSizeWhat it is
nextion_5_inch_esp32_bottom_v1169.6 × 88.5 × 12.4 mmBack shell. 2.15 mm walls, a 133.9 × 84.4 mm cavity 7 mm deep for the display, and a 29.5 mm bay walled off at one end for the ESP32
nextion_5_inch_esp32_top_v1169.6 × 88.5 × 4.4 mmFront frame, with a 119.5 × 78.6 mm window. A 3.4 mm lip drops into the back shell — assembled, the panel is 13.4 mm deep
nextion_display_5_cover_v7149.4 × 106.0 × 15.5 mmA separate front bezel with a 10 mm skirt: a 111.3 × 67.9 mm window, stepping back to 119.5 × 78.6 mm and then to a 134.5 × 84.8 mm pocket. Use this or the two-part shell, not both
decora_1-gang_v479.2 × 123.8 × 6.4 mmOversized 1-gang Decora plate, 33.2 × 66.8 mm opening
decora_2-gang_v1125.0 × 123.4 × 6.4 mmOversized 2-gang, two of the same openings on 46 mm centres
bruh_decora_1_v1125.0 × 123.4 × 6.4 mmByte-for-byte the same mesh as decora_2-gang_v1. Print one of them
light_switch_plate_v170.0 × 114.0 × 5.5 mmStandard-size 1-gang plate with a 10.3 × 23.9 mm toggle opening, for the old switch beside the panel
bruh_light_switch_buttons_v142.5 × 103.0 × 34.1 mmA Decora-format keypad — see The light-switch module

Inside the back shell the display does not float: the cavity floor carries two ribs 121.5 mm apart and a shelf 2 mm below the rim, so the module drops in and lands flat. The bay at the other end is closed off from all that, which is what keeps a dev board’s pin headers away from the back of the display glass.

The plate screw holes are not on a device’s centres. Each gang carries two 3 mm holes on its centreline, countersunk to 7 mm at the face, and they are 96.8 mm apart. A US Decora strap’s screws are 83.3 mm apart — 6.7 mm closer each side, which is more than a 3 mm hole can absorb. These plates are drawn to screw into what’s behind them, not onto the switch. Print one and offer it up before you print five, and if you need strap centres, move the holes in cad/decora_1-gang_v4.f3d rather than trying to file your way across 6.7 mm.

bruh_light_switch_buttons_v1.stl is an assembly export, not a print-ready part — 43 bodies, and only one of them is plastic. Slice it as it stands and your printer will faithfully reproduce a circuit board.

SettingValue
Layer height0.2 mm, or 0.16 mm on the visible faces
Walls3
Infill20%
SupportsNone, once everything is the right way up
MaterialMatte PLA for the plates and bezel, PLA+ for the shells

Orientation is the whole job here, and three of these files export the wrong way up.

  • The two shells are exported lying on their sides — their depth runs along Y, not Z. Rotate each 90° so the flat back face is on the bed, then print.
  • decora_1-gang_v4, decora_2-gang_v1 and nextion_display_5_cover_v7 all export face-up, with the visible face at the top of the model and the hollow recess underneath. Flip them. Face-down on the bed the visible surface is the first layer, which is the flattest thing an FDM printer makes, and every wall above it is vertical, so there is nothing to support.
  • light_switch_plate_v1 is already the right way up. Print it as it comes.

Wiring

Four wires between two boards, and that is the whole electrical build.

SignalNextionESP32
+5 V+5V (red)— power both from the supply, not one through the other
GroundGND (black)GND
Display → hostTX (yellow)any UART-capable GPIO, used as RX
Host → displayRX (blue)the matching UART TX pin

The Nextion’s serial pins are 3.3 V logic and so are the ESP32’s, so the two talk directly. No level shifter, and no reason to fit one.

Pick the two GPIOs yourself and name them in your ESPHome uart: block — there is no config in this folder pinning them down, and inventing a pair here would only give you a number to un-learn.

Don’t feed the display through the ESP32’s 5 V pin. A 5-inch Nextion’s backlight pulls around half an amp on its own. That current has no business crossing a dev board’s micro-USB socket and its 5 V trace on the way to somewhere else. Run one pair from the supply into a lever nut and take two legs out of it, so the board and the display each get their own.

Power

Three ways in, in the order you should want them.

A 5 V brick with a right-angle micro-USB lead is the one to build first. It works, it takes ten seconds to unplug, and nothing about it can hurt you.

An isolated buck converter off an existing 12 V or 24 V rail is the tidy answer if the wall already has one — a doorbell transformer, a landscape-light run, an alarm panel.

The HLK-PM01 puts line voltage on a bare module inside a printed box, and it is the only option here where a mistake matters. If you fit one: it goes in a proper electrical box, not in the printed shell; the mains side gets covered so nothing is exposed when the plate is off; and you kill the breaker before the plate comes off, every time, including the time you are only having a quick look. If any part of that sentence is new to you, use the 5 V brick.

Assembly

  1. Print the shells and dry-fit the display before anything is wired. The module drops through the 119.5 × 78.6 mm window in the front frame and its board lands on the shelf in the back shell. If it does not go, open the window with a file rather than forcing it — the glass is the expensive part.

  2. Melt the heat-set inserts in. Do this before the electronics are in the shell, and do it with the iron at around 200 °C going in slowly and straight. A crooked insert is a crooked screw for the life of the part.

  3. Wire the four leads to the table above and leave them long enough that the two halves can lie open beside each other on the bench. You will be opening this again while you write the ESPHome side.

  4. Load the HMI and confirm the display comes up on its own, before the top goes on. The display works with no host attached — it draws its pages, the tabs navigate, the brightness slider moves. If that is not happening, the problem is the .tft file and not your wiring.

  5. Close the shell, then mount it. VHB on the back if the wall is smooth and painted; anchors if it is not, or if you would like to get it off again without repainting.

  6. Fit the wall plates last, and check the screw holes against the device before you count on them — see the caution above. If a hole needs opening, open it with a round needle file by hand. A drill bit grabs a printed plate and splits it along a layer line, and it splits where you can see it.

Loading the HMI

Nextion displays take their firmware over the microSD slot, not over serial. There is no programmer to buy and nothing to plug into a computer.

  1. Open nextion-hmi/bruh_nextion_5_inch_scene_ui_v3_oct.hmi in the free Nextion Editor and set the device to the panel you actually bought.

  2. Compile, and take the .tft file it produces.

  3. Format the microSD as FAT32 and put that one .tft in the root of it. Nothing else — the loader reads the first one it finds and gets confused by company.

  4. Power the display off, insert the card, power it on. It flashes itself, tells you it is done, and then waits. Power off, remove the card, power back on.

The icons in nextion-assets/ are the source artwork for the buttons — 21 icons at 48 × 48 px (rooms, lights, fan, blinds, media, scene moods) plus a 454 × 454 px background. They are already inside the compiled HMI; they are in the folder so you can swap one out for a room the original never had.

What the display expects from the host

Everything below is read out of the HMI project, so it is what the panel will actually do rather than what a config file claims.

The host has toWhich means
Talk at 921600 baudpage0’s pre-initialise event runs bauds=921600, so the display changes speed a few milliseconds after power-on, on every power-on
Write button labels into variablesid_h_b1id_h_b8 (Home), id_s_b1id_s_b8 (Scenes), id_nav_l1id_nav_l4 (the three tabs and the panic button). The pages copy them onto the buttons themselves
Read touch eventsThe sixteen buttons and the panic button run no local code; a press is a touch event with a page id and a component id, and nothing more
Set brightness via page0.remote_dim.valThe Settings slider writes it, and every page’s dim_timer re-applies dim from it

Handle those four and you are done. Navigation is not your problem — the tabs change pages on their own and light themselves as they go.

The light-switch module

bruh_light_switch_buttons_v1 is the odd file in the folder: a Decora-format module 42.5 × 103 mm, the size of a switch’s mounting strap, with a knob standing 15 mm proud of the face. It is a design, not a build — there is no firmware and no PCB for it here — but the assembly is dimensioned around real parts, and they are recognisable enough to order.

In the CADWhat it is
42 × 78 mm board, 1.6 mmThe PCB everything mounts to
11.8 × 13.8 × 11 mm body, 6 mm shaft, five pinsAn EC11 rotary encoder
25 mm × 15.5 mm cylinder on the shaftThe knob
36.7 mm ring carrying twelve 5 × 5 mm LEDsA 12-pixel WS2812 ring, around the knob
25 × 27 mm module with a 25 × 13.9 mm glassA 0.96-inch I²C OLED
Two 5-pin 2.54 mm headers, one straight, one right-angleHow it leaves the board

To print the part, open cad/bruh_light_switch_buttons_v1.f3d, hide the electronics and export the one plastic body. Everything else in that file is there so the holes land in the right places.

Troubleshooting

The screen comes up and then goes silent, or the host reads garbage. The baud rate. The display starts at whatever speed it was saved with and jumps to 921600 the instant page 0 loads, and a host sitting at 9600 sees a page of nonsense and then nothing. bauds is the volatile form of the command, so this happens again at every power cycle — it is not something you set once.

The buttons say STAIRS, PLAYROOM and Label 1. Nothing has written the text variables yet. That is the shipped placeholder set, and seeing it means the display is healthy and the host is not talking.

Brightness snaps back a second after you set it. You wrote dim. Every page runs a timer that re-applies dim from page0.remote_dim.val, so a direct write survives until the next tick and no longer. Write remote_dim instead.

The card does nothing when the display powers up. FAT32, 32 GB or under, one .tft in the root, and the card goes in with the power off. Three of those four are the usual culprit.

The bezel sits proud of the display, or rocks. Its pocket is 134.5 × 84.8 mm and steps to 119.5 × 78.6 mm around the module, and 5-inch Nextion boards vary at the corners by a fraction of a millimetre. Take the corners back with a needle file, not the whole pocket.

Files & downloads

Printable parts

Loading 3D model…
Drag to rotate · Scroll to zoom · Right-click to pan

Parts marked from CAD are tessellated from the STEP files below, for previewing only — approximate where the STEP is exact. Download the STEP for the real model.

CAD source

The design itself, if you want to change it rather than print it. A STEP file is exact geometry and opens in almost anything; a Fusion 360 archive keeps the modelling history, so you can go back and edit the sketch that made the part.

Every file for this project on GitHub → Also in the folder: nextion-hmi/ — Nextion display projects, 1 file; nextion-assets/ — Nextion UI artwork, 22 files.