This project implements a complete HTTP web server on an STM32 Blue Pill (STM32F103C8T6) using the W5500 Ethernet module. The server hosts a modern web dashboard that displays real-time environmental data from a DHT11 sensor and DS3231 RTC, while also providing remote LED control through a REST API.
Key Features:
- HTTP web server on port 80 (accessible via any web browser)
- REST API endpoints for sensor data and LED control
- Real-time temperature and humidity monitoring (DHT11)
- Real-time clock and date display (DS3231)
- Remote LED control with instant feedback
- AJAX-powered auto-refresh (every 3 seconds)
Hardware_Config.mp4
Shows hardware setup and LED control via web interface
webserver_output.mp4
Demonstrates web dashboard with real-time sensor data and LED control
| Peripheral | Pin | Connection | Notes |
|---|---|---|---|
| Wiznet W5500 | PA5 | SCK | SPI1 Clock |
| PA6 | MISO | SPI1 Master In Slave Out | |
| PA7 | MOSI | SPI1 Master Out Slave In | |
| PA4 | CS | Chip Select | |
| PA3 | Reset | Reset Pin | |
| 3.3V | VCC | Power | |
| GND | GND | Common ground | |
| DHT11 | PB0 | Data | Module contain pull-up resistor |
| 5V | VCC | Power | |
| GND | GND | Common ground | |
| DS3231 RTC | PB10 (SCL) | SCL | I2C2 Clock |
| PB11 (SDA) | SDA | I2C2 Data | |
| 3.3V | VCC | Power | |
| GND | GND | Common ground | |
| LED | PC13 | Anode | With current-limiting resistor |
| GND | Cathode | Common ground | |
| Push Button | PA0 | GPIO Input | Button |
| GND | GND | Common ground | |
| USART1(Debug) | PA9 | TX to USB-Serial RX | 115200 baud, 8-N-1 |
| PA10 | RX to USB-Serial TX | Optional for commands |
The server implements a full HTTP/1.1-compliant stack on top of the W5500's hardware TCP/IP offload engine.
| Layer | Protocol | Implementation |
|---|---|---|
| Application | HTTP | Custom request parser + router |
| Transport | TCP | W5500 hardware (RFC 793 compliant) |
| Network | IP | W5500 hardware with ARP support |
| Data Link | Ethernet | W5500 integrated MAC/PHY (10/100BASE-T) |
- Socket Establishment
- W5500 maintains socket 0 in
SOCK_LISTENstate on port 80 listen()initiates passive TCP open- On SYN arrival, state transitions:
LISTEN → SYNRECV → ESTABLISHED
- HTTP Request Parsing
- Raw TCP payload extracted via
recv() - Stateless parser scans for CRLF
(\r\n)delimiters - Extracts: HTTP method (GET only), request URI, protocol version
- Query parameters and headers are parsed but unused (reserved for future)
- Routing Logic
- Path string compared against registered endpoints
- Uses
strcmp()for exact matching (no regex to save flash) - Dispatch to handler functions via conditional branching
| Endpoint | Method | Response | Description |
|---|---|---|---|
/ or /index.html |
GET | HTML page | Web dashboard |
/api/data |
GET | JSON | Temperature, humidity, time, date |
/api/led/on |
GET | JSON | Turn LED ON |
/api/led/off |
GET | JSON | Turn LED OFF |
/api/led/status |
GET | JSON | Get current LED state |
The DHT11 uses a single-wire protocol with precise timing:
| Phase | Duration | Description |
|---|---|---|
| Start Signal | 18ms LOW + 20µs HIGH | MCU wakes sensor |
| Sensor Response | 80µs LOW + 80µs HIGH | Sensor acknowledges |
| Bit "0" | 50µs LOW + 26-28µs HIGH | Logic 0 |
| Bit "1" | 50µs LOW + 70µs HIGH | Logic 1 |
| Data Frame | 40 bits | 5 bytes (humidity ×2 + temp ×2 + checksum) |
Instead of measuring pulse width, I used a simpler approach looking at datasheet:
For each bit:
- Wait for line to go HIGH
- Delay exactly 40µs
- If line still HIGH → logic 1
If line is LOW → logic 0
To ensure the timing is not interrupted, interrupts are disabled while communicating with the sensor. The checksum provided by the sensor is used to verify data integrity.
The DS3231 is a precision Real-Time Clock (RTC) with an integrated temperature-compensated crystal oscillator and I2C interface. The driver provides two ways to access RTC data:
- Time/Date Data: Current time (hours, minutes, seconds) and date (day, month, year)
- Temperature Data: Built-in temperature sensor reading (±3°C accuracy)
Implementation:
- Burst read of all 7 time registers in a single I2C transaction
- BCD conversion handles register format automatically
- Data Flow: I2C Read (0x00-0x06) → 7 bytes → Convert BCD → Update time structure
- Oscillator monitoring detects power failures via status register
| Measurement | Range | Resolution | Format |
|---|---|---|---|
| Time | 00:00:00 - 23:59:59 | 1 second | HH:MM:SS |
| Date | 01/01/00 - 31/12/99 | 1 day | DD/MM/YY |
Note: LCD display shows formatted time/date strings and temperature in physical units. Raw BCD values are automatically converted using internal helper functions. The RTC maintains accurate time even when main power is off using a CR2032 backup battery.
- STM32F103 Datasheet
- STM32F103 Reference Manual
- WIZNET W5500 Datasheet
- DHT11 Sensor Datasheet
- RTC DS3231 Datasheet
- Status: Complete
- Version: v1.0
- Last Updated: April 2026
Rubin Khadka Chhetri
📧 [email protected]
🐙 GitHub: https://github.com/rubin-khadka