Engineering Reference · PHYSICALLY PROVEN ON ESP32-P4
Board-specific wiring, generated contracts, developer ownership, startup behavior, troubleshooting and accepted physical proof for two buttons and two LEDs.
Hardware Example 01 — GPIO Digital I/O
Device Console: After flashing, open Device Console → MONITOR for live raw runtime output. The current example identifies its GPIO assignments but does not emit explicit recurring
GPIO n: HIGH/LOWstate lines, so do not expect the read-only I/O GPIO section to represent every button or LED transition.
Status: PHYSICALLY PROVEN / CLOSED ON ESP32-P4
Hardware Example selection is mutually exclusive. Selecting Example 01 generates, links, displays, initializes and polls only Example 01; other completed example implementations remain preserved but inactive. Board: Waveshare ESP32-P4-WIFI6-Touch-LCD-7B Display: 1024 × 600
Purpose
This first ForgeUI Hardware Example shows the ordinary application boundary: ForgeUI supplies an editable standard-widget UI, generated LVGL, the public Runtime SDK and genuine UserEvent callbacks. Developer-owned application code configures GPIO, debounces physical inputs and drives physical outputs. It does not use a Native Component or introduce a GPIO framework.
The board allocation and safety audit are authoritative in 11_ESP32_P4_WIFI6_TOUCH_7B_BOARD_PINOUT_MASTER.md.
Required parts
- Waveshare ESP32-P4-WIFI6-Touch-LCD-7B running the Example 01 project
- Two normally-open momentary pushbuttons
- Two LEDs
- Two 330-ohm current-limiting resistors (one per LED)
- Breadboard/jumper wires and a common GND
- If using the local LED test module: its enable/slider/interlock must be enabled
Power the board down before changing wiring. ESP32-P4 GPIO is 3.3 V logic; never apply 5 V to a GPIO.
Wiring
| Board pin | Connect through | Destination | Firmware meaning |
|---|---|---|---|
| GPIO2 | Button 1 | GND | Active-low input with internal pull-up |
| GPIO4 | Button 2 | GND | Active-low input with internal pull-up |
| GPIO3 | 330-ohm resistor, then LED 1 anode | LED 1 cathode to GND | HIGH = on, LOW = off |
| GPIO5 | 330-ohm resistor, then LED 2 anode | LED 2 cathode to GND | HIGH = on, LOW = off |
For each button, released reads HIGH and pressed reads LOW. No external pull-up is required. For each LED, place the resistor in series; the longer LED leg is normally the anode and the flat-side/short leg is normally the cathode. Confirm polarity against the actual component datasheet if uncertain.
Local LED hardware warning: Scott's physical LED test hardware has its own
local enable/slider/interlock. Enable that circuit before judging GPIO3 or
GPIO5 operation. A disabled local module can make correct firmware look broken.
UI and physical behavior
Load Hardware Examples → Example 01 → GPIO Digital I/O → Load Example in the left Studio tray. The resulting project is an ordinary editable project made from standard Heading, Text, LED and Switch widgets.
- Physical Button 1 changes on-screen Indicator 1 after stable debounce.
- Physical Button 2 changes on-screen Indicator 2 after stable debounce.
- The LED 1 touchscreen Switch drives physical GPIO3/LED 1.
- The LED 2 touchscreen Switch drives physical GPIO5/LED 2.
- Inputs and outputs are independent. Indicators represent physical buttons and
deliberately do not mirror the output switches.
- Startup state is aligned end-to-end: LED 1 switch OFF, LED 2 switch OFF,
Indicator 1 OFF, Indicator 2 OFF, GPIO3 LOW, GPIO5 LOW, and both physical LEDs OFF. A button held during initialization may immediately set its matching indicator ON because indicators represent the physical inputs.
Generated ForgeUI contracts
Stable persisted component names produce these public generated Runtime SDK APIs:
void FG_Set_Indicator1(bool on);
void FG_Set_Indicator2(bool on);The standard touchscreen Switches produce these genuine generated UserEvents:
void FG_On_LED1_Toggle_Changed(bool checked);
void FG_On_LED2_Toggle_Changed(bool checked);The identities are indicator1 / Indicator1, indicator2 / Indicator2, led1-toggle / LED1 Toggle, and led2-toggle / LED2 Toggle.
Code ownership
studio/src/forgeui/hardwareExamples/HardwareExample01.tsowns the editable
example registry metadata and project payload.
firmware/ForgeUI-One/main/90_Studio_Export.c/.his generated ForgeUI code and
must not be edited manually.
firmware/ForgeUI-One/main/96_Hardware_Example_01.c/.his the small,
developer-owned GPIO and 25 ms debounce example.
firmware/ForgeUI-One/main/95_UserEvents.ccontains the developer-owned bodies
of the two generated Switch hooks; each delegates to its matching GPIO output.
Regeneration may replace generated 90_Studio_Export.*. The exporter preserves active customized 95_UserEvents.c callback bodies. Application behavior remains outside private LVGL objects and uses only the public generated API.
The authoritative regeneration path also retains "96_Hardware_Example_01.c" in idf_component_register(SRCS ...) only when the required Example 01 Runtime SDK APIs and UserEvents are present. This prevents normal regeneration from dropping the developer hardware module.
Physical proof results — 2026-08-08
Scott manually flashed the software-complete build to the actual Waveshare ESP32-P4-WIFI6-Touch-LCD-7B. Direct multimeter measurements established:
| Output path | Touchscreen state | GPIO measurement | Result |
|---|---|---|---|
| LED 1 / GPIO3 | OFF | approximately 0 V | Physically proven |
| LED 1 / GPIO3 | ON | approximately 3.3 V | Physically proven |
| LED 2 / GPIO5 | OFF | approximately 0 V | Physically proven |
| LED 2 / GPIO5 | ON | approximately 3.3 V | Physically proven |
Both external LED circuits illuminated correctly after their own local normally-off enable/slider/interlock was switched ON. Both output channels are physically proven.
Scott then completed the physical input proof on the same working build and actual board:
| Input path | Physical action | Display result | Result |
|---|---|---|---|
| Button 1 / GPIO2 | Press and release | ForgeUI Indicator 1 changes | Physically proven |
| Button 2 / GPIO4 | Press and release | ForgeUI Indicator 2 changes | Physically proven |
Both input channels operate correctly. Together with the output proof, this physically demonstrates both architectural directions:
- physical digital input → developer-owned GPIO code → generated Runtime SDK → live ForgeUI UI;
- ForgeUI touch control → genuine generated UserEvent → developer-owned GPIO code → physical output.
Troubleshooting: physical LED module enable / interlock
Some LED test modules or circuits include a local normally-off enable, slider, button, or interlock. Before diagnosing ForgeUI, GPIO, callbacks, or generated code:
- Confirm the local LED enable/interlock is ON.
- Measure the GPIO directly.
- Verify approximately 0 V when OFF and approximately 3.3 V when ON.
- Investigate software only if the GPIO itself does not change as expected.
A local LED interlock being OFF can make a correctly operating GPIO output look dead — a tiny switch with an impressive talent for sending an investigation in the wrong direction. This exact condition occurred during the first physical proof and is retained as a practical troubleshooting lesson.
Physical proof checklist
Final physical proof checklist:
- [x] Button 1 drives Indicator 1.
- [x] Button 2 drives Indicator 2.
- [x] LED 1 touchscreen switch drives GPIO3 at approximately 0 V / 3.3 V and physical LED 1.
- [x] LED 2 touchscreen switch drives GPIO5 at approximately 0 V / 3.3 V and physical LED 2.
- [x] Both input channels operate independently.
- [x] Both output channels operate independently.
- [x] Bidirectional input/output architecture is physically demonstrated.
Final authoritative status:
HARDWARE EXAMPLE 01 — 2 BUTTONS + 2 LEDS<br> PHYSICALLY PROVEN ON ESP32-P4<br> GPIO2 BUTTON 1 — PROVEN<br> GPIO3 LED 1 — PROVEN<br> GPIO4 BUTTON 2 — PROVEN<br> GPIO5 LED 2 — PROVEN.
