How to build an STM32 Web Dashboard

In this tutorial, we'll show you how to build a complete STM32 device dashboard using the Mongoose Library, transforming your Nucleo-F756ZG board into a browser-accessible web dashboard for control, monitoring, and updates.

We’ll guide you step-by-step through creating a functional web dashboard with system stats, LED control, device settings, and firmware updates.

The web dashboard you'll build will run directly on the STM32, accessible from any browser on the same network.

Step 1: Set Up Your Development Environment

Before building your STM32 device dashboard, prepare your development environment:

So please make sure to have CubeIDE installed before proceeding to the next steps.

Step 2. Create the Dashboard Layout

Visit https://mongoose.ws/wizard/ and create a project with three web dashboard pages:

This tool allows to create your STM32 device dashboard in a visual way. Click on the "New" button to start a new design. Select STM32 as the target architecture, and choose an empty dashboard template.

An empty "dashboard" page is created automatically. Add two more pages: device settings page, and a firmware update page.

Web UI pages

Step 3. Dashboard Page

The Dashboard page shows:

We will create 4 cards for those. However the information will be taken from different places. A device name would be settable by the user on the "Device Settings" page. Therefore, it will be backed by the "settings" API endpoint.

Go to the API endpoint editor and create settings endpoint, with a single string attribute device_name in it.

Settings API

The current tick number and RAM usage are read-only metrics, so create a separate API endpoint for that, called state. Mark it read-only, and create three attributes in it: ram_free, ram_free, and ticks.

Add leds endpoint with three boolean fields led1, led2, led3.

Now we're ready to add UI elements to the Dashboard page. Add "stats row" element, add cards to have 4 in total, and edit their titles and values that reference recently added API endpoints.

Add a panel for the LED toggle. Set toggle buttons to "autosave".

Dashboard page

Step 4. Device Settings Page

Click on the device settings page, and add a panel there. Remove all unnesessary settings, leave only one with the text input. Label it "Device name". Set API reference for the text input to settings.device_name

Settings page

Step 5. Firmware Update Page

This page would enable OTA firmware updates using the web dashboard:

The firmware_update endpoint gets added automatically when you add the firmware update button to the UI.

Mongoose has built-in firmware update support for a variety of microcontrollers. SMT32 is one of the supported microcontrollers, so when we add this API endpoint, we automatically get working firmware update functionality.

OTA page

Step 6. Build and test the firmware

Now the Web dashboard is ready. Click on the Generate button. Wizard creates a new STM32 project in the output directory. Build it and flash it.

Note that the target could any other microcontroller from the STM32 family.

Attach a serial console, reboot the device. Get device's IP address from the serial logs. Open your browser, type it device's IP address into the address bar. Now you should see the web dashboard served by the device.

Step 7. Attach UI controls to the hardware

Clicking on LED toggle does not do anything, cause the leds endpoint is not yet linked to the hardware. OTA updates work without any further efforts! The settings page gets saved only to RAM, rebooting the device looses all changes.

RAM and temperature stats show mock data instead of a real one.

Let's link all these API endpoints - leds, settings, stats, to our STM32 device. For that, we need to override the default API callback functions that are generated in mongoose/mongoose_glue.h with our own custom callbacks.

Settings page

Here is the updated main/main.c:

void my_get_leds(struct leds *leds) {
  leds->led1 = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_0);
  leds->led2 = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_7);
  leds->led3 = HAL_GPIO_ReadPin(GPIOB, GPIO_PIN_14);
}
void my_set_leds(struct leds *leds) {
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_0, leds->led1);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_7, leds->led2);
  HAL_GPIO_WritePin(GPIOB, GPIO_PIN_14, leds->led3);
}

void my_get_state(struct state *state) {
  state->ram_total = configTOTAL_HEAP_SIZE;
  state->ram_used =  xPortGetFreeHeapSize();
  state->tick = HAL_GetTick();
}

static struct settings x;
void my_get_settings(struct settings *settings) {
  *settings = x;
}
void my_set_settings(struct settings *settings) {
    x = *settings;
}

Add calls to mongoose_set_http_handlers() right after the mongoose_init() call:

  mongoose_set_http_handlers("state", my_get_state, NULL);
  mongoose_set_http_handlers("leds", my_get_leds, my_set_leds);
  mongoose_set_http_handlers("settings", my_get_settings, my_set_settings);

Rebuild the firmware. Use the firmware update page, select the freshly built firmware.bin to update to the new firmware. Congratulations! Now our dashboard shows actual device values. LED control works, and the device settings page save device data permanently on flash.

Conclusion

You’ve just built a full-featured STM32 device dashboard on your STM32 using the Mongoose Embedded Web Server. Your web dashboard can now:

This web dashboard architecture is ideal for smart devices, industrial sensors, or any IoT product that benefits from a browser-based interface.

The STM32 device dashboard approach helps eliminate the need for separate mobile apps, making your solution more accessible and cross-platform. Whether you're prototyping or building production devices, integrating a web dashboard into your firmware gives your users intuitive and powerful control.