Wiznet makers

lawrence

Published July 12, 2026 © MIT license (MIT)

165 UCC

9 WCC

33 VAR

0 Contests

0 Followers

0 Following

Original Link

STM32-W5500-Embedded-WebServer: Embedded HTTP Web Server on Custom STM32F446RCTx Board

An end-to-end embedded web server built from scratch on a custom PCB — serving a login page and an Industrial IoT dashboard straight out of Flash memory, with z

COMPONENTS Hardware components

WIZnet - W5500

x 1


PROJECT DESCRIPTION

Project Overview

Most embedded web server tutorials hand you a devkit and an off-the-shelf Ethernet shield. This project takes a different route: it starts from a custom-designed STM32F446RCTx development board with the W5500 integrated directly on the PCB, and it delivers a multi-page, browser-accessible web application that lives entirely inside microcontroller Flash.

Hardware

When a browser on the same network hits the board's static IP address, it first lands on a login page. After authentication, it is redirected to a polished Industrial IoT dashboard — all served by 180 MHz of Cortex-M4, over Ethernet, with no Linux, no SD card, and no file system.

What makes this stand out from similar "hello world webserver" builds is the care invested in every layer: a custom PCB, a full STM32CubeMX peripheral configuration, a documented HTML-to-C conversion workflow, and a clean UART debug output trail that confirms every initialization step. Each piece is photographed, screenshotted, and described in the README — making it a genuinely reproducible reference, not just a proof of concept.

Login
Dashboard

Why W5500? — The Reasoning Behind the Hardware Choice

Serving HTTP from a bare-metal microcontroller requires two things to coexist without an OS: a working TCP/IP stack and a firmware loop that handles web requests. The W5500's hardwired TCP/IP engine is precisely what makes that combination viable on an STM32.

With a software TCP/IP stack (lwIP, for example), the MCU must run all protocol logic itself — ARP, IP, TCP — which consumes significant CPU time and RAM, and often requires an RTOS to manage timing reliably. The W5500 eliminates that entire burden.

Why the W5500 is the right chip for this project:

The W5500 integrates a full 10/100 Ethernet MAC and PHY with a hardwired TCP/IP stack into a single SPI-connected package. The STM32 firmware only needs to call the WIZnet ioLibrary's httpServer_run() in a loop; the W5500 handles TCP connection management, packet framing, ARP resolution, and buffering autonomously. The CPU is free to process HTTP requests, parse URIs, and build responses — which is exactly what an application-level web server needs.

The 32 KB on-chip TX/RX buffer memory (configurable per socket) is particularly important here. HTML pages with embedded CSS and placeholder data can easily exceed 2–4 KB. The W5500's generous buffer ensures pages are transmitted without fragmentation issues that smaller-buffer chips struggle with.

Key technical reasons for choosing W5500:

CriterionWhy it matters for this project
Hardwired TCP/IP stackNo lwIP, no RTOS required — bare-metal HTTP server is feasible
8 independent socketshttpServer library uses multiple sockets for concurrent connections
32 KB TX/RX bufferServes full HTML pages without segmentation
SPI interface (up to 80 MHz)Clean integration with STM32 SPI2 peripheral
WIZnet ioLibrary supporthttpServer, socket, wizchip_conf — production-ready, well-documented
Single-chip Ethernet (MAC+PHY)Reduces PCB component count on the custom board

Why W5500-EVB-Pico was not chosen and what that reveals: This project uses a custom STM32F446RCTx board rather than a development kit. That decision itself reflects the project's ambition — designing a board, routing the W5500 next to the MCU, and validating the SPI connection through firmware is a meaningfully harder undertaking than plugging in a module. It demonstrates that the W5500 is viable not just on reference platforms but in custom hardware contexts, which is exactly where industrial and commercial products live.


Hardware Configuration

The project runs on a custom STM32F446RCTx development board with the W5500 Ethernet controller integrated directly on the PCB. No external shields or breakout modules are used.

SPI Configuration

MCU specification:

  • STM32F446RCTx, LQFP64 package
  • ARM Cortex-M4 at 176 MHz (PLL from 8 MHz HSE)
  • 256 KB Flash, 128 KB RAM
  • STM32Cube FW_F4 V1.28.3

Peripheral assignment (from .ioc configuration):

PeripheralFunctionPins
SPI2W5500 communicationSCK: PB13, MISO: PB14, MOSI: PB15
GPIO (ETH_CS)W5500 chip selectPB12
GPIO (ETH_RST)W5500 hardware resetPA6
USART3Debug output (async)TX: PB10, RX: PC5
SPI2 IRQSPI2 interrupt enabledNVIC priority group 4

SPI2 configuration:

  • Master mode, Full Duplex
  • Baud rate prescaler: /32 → 1.375 Mbps
  • CPOL: Low, CPHA: First Edge (Mode 0)
  • 8-bit data, MSB first
  • Software NSS

The SPI clock is deliberately conservative at 1.375 Mbps, which is well within the W5500's 80 MHz SPI maximum. This ensures reliable communication during development and initial bring-up, and can be increased for performance optimization.


How It Works

User opens browser  →  enters board's static IP
        ↓
HTTP GET request arrives over Ethernet cable
        ↓
W5500 receives frame, buffers it in internal RX memory
        ↓
STM32 calls httpServer_run() — ioLibrary parses HTTP request
        ↓
URI matched: "/"  →  serve login page (from Flash)
        ↓
User authenticates  →  redirect to "/dashboard"
        ↓
Dashboard HTML served from Flash (webpage.c / webpage.h)
        ↓
Browser renders Industrial IoT dashboard

The HTML-to-C conversion workflow is one of this project's most instructive design decisions. Rather than storing pages on an SD card or SPIFFS, the author converted HTML files into C byte arrays using a Perl-based utility. The generated webpage.c and webpage.h are compiled directly into firmware and placed in Flash. This means:

  • No file system overhead
  • No storage hardware to fail
  • Page content is read-only and protected
  • The binary is completely self-contained
HTML Integration

This approach is standard practice in industrial embedded products, and seeing it implemented cleanly on a student project — including the conversion step and the resulting file structure — makes it a valuable educational artifact.

Network initialization sequence (from UART output):

1. W5500 version check  → confirms chip identity (0x04)
2. Static network config → MAC, IP, Subnet, Gateway, DNS applied
3. httpServer_init()    → sockets allocated, RX/TX buffers assigned
4. Ethernet link status → link confirmed
5. httpServer_run()     → server loop begins, waiting for HTTP requests

Each of these steps is confirmed on the UART debug terminal, making the bring-up sequence fully observable without a logic analyzer.


Software Structure

File / FolderRole
Core/Src/main.cSPI2 init, W5500 reset, network config, httpServer loop
Core/Src/webpage.cHTML pages as C byte arrays (compiled into Flash)
Core/Inc/webpage.hPage registration declarations
Core/Src/w5500/WIZnet ioLibrary: socket, httpServer, wizchip_conf, SPI HAL bridge
stm32webserver.iocSTM32CubeMX configuration (full peripheral, clock, pin assignment)
STM32F446RCTX_FLASH.ldLinker script for Flash execution
STM32F446RCTX_RAM.ldLinker script for RAM execution
images/Hardware photos, SPI config screenshots, UART output, dashboard

Project Workflow — Step by Step

The README documents seven distinct implementation stages, each with a screenshot or photo. This level of documentation completeness is rare for a student project and makes it genuinely reproducible.

Stage 1 — Custom board bring-up A custom STM32F446RCTx board with integrated W5500, RJ45 port, UART debug header, and power supply section. Hardware photos are included.

Stage 2 — SPI2 configuration in CubeMX Full peripheral configuration exported as .ioc, including baud rate, polarity, phase, interrupt routing, and pin assignment. Screenshot of the CubeMX SPI configuration panel is included.

Stage 3 — W5500 network initialization Static IP, MAC, gateway, subnet, and DNS configured through the WIZnet ioLibrary wiz_NetInfo struct. W5500 version register verified before network parameters are applied. Screenshot of network config code is included.

Stage 4 — HTML-to-C conversion HTML pages converted to C arrays with a Perl utility. webpage.c and webpage.h added to the STM32CubeIDE project and registered with reg_httpServer_webContent(). Screenshot of the integration step is included.

Stage 5 — Login page Custom login page served at /. Authenticates user before granting access to the dashboard. Screenshot of the browser login page is included.

Stage 6 — Industrial IoT dashboard Post-login dashboard demonstrating how industrial monitoring data can be presented from an embedded server. Screenshot of the rendered dashboard is included.

Stage 7 — UART debug validation UART terminal output confirming: W5500 detection, network config, assigned IP, Ethernet connection status. Screenshot of UART output is included.


What Makes This Project Stand Out

Custom PCB, not a devkit. The W5500 is integrated directly on a custom-designed STM32F446RCTx board. Designing and validating a custom board with integrated Ethernet is a significantly harder engineering task than using a module, and it demonstrates that the W5500 integrates cleanly into real hardware design.

Flash-resident web content. Converting HTML to C arrays and serving directly from microcontroller Flash is the architecture used in production industrial devices. This project demonstrates that pattern end-to-end, including the conversion toolchain.

Multi-page application with authentication. Rather than serving a single static page, the project implements a login flow followed by a dashboard — closer to a real embedded web application than most "hello world" webserver examples.

Step-by-step documentation with screenshots at every stage. Seven documented stages, each with photographic or screenshot evidence. This reproducibility is what separates a well-crafted project from a demo.

Complete .ioc file included. Anyone can open the project in STM32CubeIDE and immediately see the exact clock tree, SPI parameters, GPIO assignments, and interrupt configuration used. No guesswork about peripheral settings.


Comparison with Similar Projects on WIZnet Maker

Comparison 1: How to Synchronize RTC Time with WIZnet W5500 on STM32? (by gavinchang)

WIZnet Maker: maker.wiznet.io — RTC Time Sync with W5500 on STM32

This project uses W5500 + STM32 to implement NTP-based RTC time synchronization via UDP. It is an excellent educational reference for network-layer data exchange — the STM32 builds NTP packets, sends them via W5500's UDP socket, and applies the received timestamp to the on-chip RTC.

Comparison PointSTM32 Embedded WebServer (this project)RTC Time Sync with W5500
Primary goalServe multi-page HTTP web application from FlashSynchronize STM32 RTC via NTP over UDP
Protocol usedHTTP (TCP, port 80)NTP (UDP, port 123)
W5500 socket modeTCP — httpServer socketsUDP — NTP query/response
Output directionBrowser → MCU (inbound HTTP requests)MCU → Internet (outbound NTP query)
User interactionBrowser-based login + dashboardNo UI — background time sync
HardwareCustom STM32F446RCTx PCB with integrated W5500STM32 devkit + W5500 module
Web contentMulti-page HTML served from FlashNone
Complexity levelIntermediate-Advanced (custom board + HTTP server)Intermediate (UDP + NTP protocol)
Educational valueHTTP server architecture, Flash web content, custom PCBNTP protocol, UDP sockets, RTC calibration

Key distinction: The RTC sync project treats W5500 as an outbound data channel — the MCU reaches out to an NTP server and consumes data. This web server project treats W5500 as an inbound service endpoint — external clients connect to the MCU and consume content. Both directions are essential patterns in embedded networking, and together they illustrate the full duplex nature of W5500's socket model.


Comparison 2: How to Build FreeRTOS MQTT Networking with WIZnet W5500 on STM32F103? (by gavinchang)

WIZnet Maker: maker.wiznet.io — FreeRTOS MQTT with W5500 on STM32

This project uses W5500 + STM32F103 + FreeRTOS to implement MQTT communication over wired Ethernet — publishing sensor data or control messages to a broker. It is a natural complement to the web server approach, targeting M2M (machine-to-machine) messaging rather than browser interaction.

Comparison PointSTM32 Embedded WebServer (this project)FreeRTOS MQTT with W5500
Primary goalBrowser-accessible embedded web applicationMQTT publish/subscribe for IoT messaging
Protocol usedHTTP (TCP)MQTT (TCP, broker-based)
Interaction modelHuman via browserMachine-to-machine via broker
RTOS dependency❌ Bare-metal (no RTOS)✅ FreeRTOS required
MCUSTM32F446RCTx (176 MHz, Cortex-M4)STM32F103 (72 MHz, Cortex-M3)
HardwareCustom PCB with integrated W5500Devkit + W5500 module
Web interface✅ Multi-page login + dashboard❌ None
ScalabilitySingle-device local accessCloud/broker scale, many devices
Use caseLocal device monitoring and control via browserFleet telemetry, remote control, IoT cloud

Key distinction: The MQTT project needs FreeRTOS to manage the MQTT keepalive task alongside other application tasks — the protocol demands more scheduling complexity. The web server project achieves its goal in a bare-metal while(1) loop, demonstrating that W5500's httpServer library is robust enough to run without an RTOS. For teams starting with embedded Ethernet, the bare-metal web server is the lower-barrier entry point.


Significance for WIZnet & Application Potential

W5500 ioLibrary httpServer — A Validated Reference Implementation

The WIZnet ioLibrary includes an httpServer module, but documentation on integrating it with a custom STM32F4 board — particularly with HTML content served from Flash — is sparse. This project validates the complete integration path: SPI2 peripheral initialization on STM32F446, ioLibrary driver porting, HTML-to-C conversion, reg_httpServer_webContent() usage, and the httpServer_run() loop. That makes it a concrete reference that developers porting the ioLibrary to new hardware can follow directly.

Demonstrating W5500 Fitness for Custom Hardware Design

Because the W5500 is placed on a custom PCB rather than a breakout module, this project implicitly demonstrates the chip's suitability for production board design — correct SPI routing, reset circuitry, RJ45 magnetics integration, and power supply requirements. This is a data point WIZnet benefits from: the chip works cleanly in custom silicon contexts, not just on evaluation boards.

Expanding the Industrial IoT Web Interface Reference Set

The "Industrial IoT Dashboard" framing is deliberate and accurate. Embedded web servers running on MCUs with W5500 are a common architecture for industrial HMI (Human-Machine Interface) panels, PLC status pages, building automation controllers, and test equipment web interfaces. This project provides a clean, reproducible template for exactly that pattern.

Concrete Application Scenarios

Industrial HMI and device dashboards:

  • PLC or controller status pages accessible from any browser on the plant floor LAN
  • Machine parameter viewing and adjustment without dedicated display hardware
  • Alarm status and event log pages served from the controller itself

Building automation and facility management:

  • HVAC, lighting, or access control units serving a local web interface
  • Energy meter or sub-panel monitoring with browser-accessible dashboard
  • Multi-zone configuration via embedded forms (extending this project's login pattern)

Test and measurement equipment:

  • Bench instruments serving calibration data, measurement history, or configuration pages
  • Production line testers with web-accessible pass/fail logs and statistics

Education and training:

  • End-to-end embedded networking curriculum: custom board design → SPI bring-up → ioLibrary porting → HTTP server → browser interaction
  • Demonstrates the HTML-to-C workflow that underpins many real-world embedded web products
  • Shows students what happens at each layer when a browser request meets a microcontroller

Upgrade paths from this base:

  • Replace static HTML with CGI handlers → send real sensor data to the browser dynamically
  • Add form-based control → write to GPIO or UART from browser input
  • Add basic auth token or session cookie → harden the login mechanism
  • Port to W5500-EVB-Pico + MicroPython → lower-barrier replication of the same architectureTroubleshooting Notes
Documents
Comments Write