EmbeddedEra EmbeddedEra

← Todos los casos

Un panel de pared para controlar toda la casa

Panel táctil ESP32-P4 de 7 pulgadas que controla la casa con Home Assistant: luces, clima, medios, cámaras y voz local. Imagen de cámara de 1,27 s a 22 ms.

Role
Firmware, integration, enclosure, test tooling — R&D project
Period
Oct 2026
Stack
ESP32-P4, ESPHome, LVGL, C++, Home Assistant, 3D printing
The 7-inch panel in its black printed case on a stainless fridge door, showing the home screen: clock, outside and inside temperature, a five-day forecast, quick buttons and a printer status tile.

Problem

A house collects controls one app at a time: lights in one, the thermostat in another, TVs and speakers in three more, cameras in two. Each works. None of them is where you are standing when your hands are full in the kitchen.

The brief was one screen on the fridge that runs all of it, answers to voice, shows who is at the door, and keeps the everyday controls working when the internet doesn’t.

Constraints

  • Off-the-shelf hardware. A bought 7-inch, 1024x600 touch panel with an ESP32-P4 for the application and an ESP32-C6 for Wi-Fi. The work is the firmware, the integration and the enclosure, not a new board.
  • Local first. Lights, climate, automations and speech recognition run on a server in the house. No cloud round trip for “turn off the lights”; only services that live in the cloud, like streaming music, need the internet.
  • A phone-like feel on a microcontroller. People compare any touchscreen to their phone. A page that stutters when you scroll reads as broken.
  • Fixed memory. The P4 has fast internal RAM and slower PSRAM. Where each buffer lands decides the frame rate, and the boot image has a hard ceiling.
  • It lifts off the wall. A battery inside, so it can be carried to the table and put back.

What we built

Block diagram: the panel (ESP32-P4 running the UI, ESP32-C6 for Wi-Fi, touch, speakers, microphone, battery) talks over Wi-Fi to Home Assistant on a local server, which controls lights, thermostat, TVs and speakers, cameras, appliances and runs speech recognition.
The panel is the screen, speaker and microphone. Home Assistant on a local server is the brain that talks to every device.

Firmware. ESPHome with LVGL for the screens, plus our own C++ where YAML ran out: page navigation, a layout checker, and a self-test. Pages for the home dashboard (clock, weather, five-day forecast), lights grouped by room, a round thermostat dial, a card per TV and speaker, cameras, timers as rings and a shopping list. What appears on each page is chosen from Settings on the panel, not hard-coded, so adding a lamp doesn’t need a firmware build.

Voice, on the local network. A wake word runs on the panel itself. The spoken command goes to speech-to-text and text-to-speech containers on the server, about 2.5 seconds per command. Timer alarms, doorbell chimes and announcements play through the panel’s own speakers, which are powered only while sound is playing.

Cameras without video decode. The P4 has no H.264 decoder, so live video was never an option. The panel pulls JPEG snapshots through Home Assistant instead, and a motion event at the front door pops that camera up full screen with a chime.

The panel's Cameras page showing a full-screen snapshot from the camera inside a 3D printer, with the sidebar of pages on the left.
The Cameras page with the 3D printer's camera full screen. Any camera Home Assistant knows about can be picked. (Camera name blurred.)

Two panels, one codebase. The firmware is split into hardware, network, theme and UI packages. A second, 5-inch panel on a nightstand builds from the same source with its own pages.

The enclosure. Modelled from the board’s own CAD data, printed in PETG, with the battery inside and both USB-C ports left open. It drops into interchangeable mounts: a magnetic cradle for the fridge, a screwed wooden cradle, portrait versions of both, and a nightstand stand tilted 15°.

The panel on the fridge seen from the side, showing the slim printed case, the cradle underneath and the USB-C ports and switch on the right edge.
On the fridge in its magnetic cradle, with the USB-C ports and switch on the side. (Front-door camera picture blurred.)
CAD render of the panel standing in the tilted nightstand stand.
Render: the same case in the nightstand stand. The panel lifts out of every mount.

What it took

A 1.27-second picture became a 22-millisecond one. ESPHome decodes JPEG in software: 1.27 s per 800x450 snapshot, with the whole interface frozen while it ran. The P4 has a hardware JPEG engine, and no community component used it, so we wrote one. Decode dropped to about 22 ms, a new picture shows every second, and the page stays responsive while it loads.

Scrolling went from 15 to about 30 frames a second, measured, not eyeballed. We built a self-test into the firmware that drives a fake finger across every page, flicks it, waits for the momentum to settle, takes a screenshot and logs frame times. Each change was kept only if the numbers moved:

ChangeRender time per frameMeasured fps
Starting point: draw buffer in PSRAM47.7 ms15
Smaller draw buffer, fits in internal RAM28.7 ms21
Rendering hot paths compiled for speed, in fast memory26.2 ms22
No main-loop sleep while a finger is down24.9 ms24–28
Scrolling a page no longer redraws the sidebar17.4 ms26–36

Compiling everything for speed would have overflowed the boot RAM by 5.4 KB, so only the drawing hot paths got it. A second drawing thread was tried and removed after review found a font cache that isn’t thread-safe.

A Wi-Fi setting that didn’t survive a restart. Changing networks from the screen with the framework’s own action looked fine until the next reboot: the new network was saved under a key that boot never reads. We replaced it with our own connect-and-save script, with a 30-second fallback to the old network if the new password is wrong.

Checks a person doesn’t have to do. Every UI change runs a layout check for overlapping widgets, clipped text and low contrast across all 13 colour themes, plus host-side unit tests of the UI logic with the hardware stubbed out.

CAD render of the back cover with the battery pocket and the four screw bosses.
Render: back cover with the battery pocket. Front and back print together on one plate in about two hours.

Why it matters for your product

The same problems show up in any product with a touchscreen: an interface that has to feel smooth on a microcontroller, memory that decides the frame rate, a framework that almost does what you need, and a case that has to fit the board rather than the other way round. If that’s your product, see HMI and touchscreen display development.