Simple Web Server

Simple LED Web Server - Code Walkthrough
Introduction
This tutorial explains how to create a web server on a Raspberry Pi Pico W that can control an LED through a web page. Think of it like creating your own mini-website that can control real hardware!
What You'll Learn
- How to connect your Pico W to WiFi
- How to create a simple web server
- How to control hardware (LED) from a webpage
- Basic Python programming concepts
Prerequisites
- You need a
secrets.pyfile with your WiFi credentials:
1 2 | |
Section 1: Importing Libraries
1 2 3 4 5 | |
What's happening here?
import statements tell Python to load special tools (called libraries) that we need:
network- Tools for connecting to WiFisocket- Tools for creating web servers (like a mailbox for internet messages)secrets- Your WiFi password file (keeps it separate and safe)time- Tools for waiting and timingPin- From themachinelibrary, this controls the physical pins on your Pico W
Think of imports like getting tools from a toolbox - you only take out what you need for the job.
Section 2: Setting Up the LED
1 2 3 | |
What's happening here?
led = Pin("LED", Pin.OUT) - This creates a connection to the built-in LED on your Pico W
- "LED" tells it which pin to use (the built-in one)
- Pin.OUT means we want to control it (send signals OUT to it)
led_state = False - This creates a variable to remember if the LED is on or off
- False means "off"
- True would mean "on"
- This is like a sticky note that says "remember: LED is currently off"
Section 3: Connecting to WiFi
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
What's happening here?
def connect_wifi(): - This creates a function (a reusable block of code) called connect_wifi
- Functions are like recipes - you write them once, then use them whenever needed
print(f'Connecting to WiFi: {secrets.SSID}') - Shows which network we're connecting to
- f'...' is called an f-string - it lets you put variables inside text
- secrets.SSID gets your network name from the secrets file
wlan = network.WLAN(network.STA_IF) - Creates a WiFi object
- Think of this like turning on your phone's WiFi
wlan.active(True) - Turns on the WiFi radio
wlan.connect(secrets.SSID, secrets.PASSWORD) - Attempts to connect using your credentials
The while loop:
1 2 3 | |
while means "keep doing this as long as..."
- not wlan.isconnected() means "as long as we're NOT connected"
- print('.', end='') prints a dot without going to a new line
- time.sleep(1) waits 1 second
- This creates the "Connecting..." dots you see
return wlan - Gives back the WiFi object so other parts of the code can use it
Section 4: Controlling the LED
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
What's happening here?
global led_state - This tells Python we want to change the led_state variable we created earlier
- Without global, Python would create a new, separate variable
led_state = not led_state - This flips the state
- If led_state was False, not False becomes True
- If led_state was True, not True becomes False
- It's like a light switch - if it's off, turn it on; if it's on, turn it off
The if/else statement:
1 2 3 4 5 6 | |
if led_state: means "if led_state is True"
- led.on() physically turns the LED on
- else: means "otherwise" (if led_state is False)
- led.off() physically turns the LED off
return "ON" if led_state else "OFF" - This is a shortcut way to return text
- If led_state is True, return "ON"
- If led_state is False, return "OFF"
Section 5: Creating the Web Page
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | |
What's happening here?
html = f"""...""" - Creates a multi-line string containing HTML code
- f"""...""" lets us put Python variables inside the HTML
- HTML is the language used to create web pages
Key HTML parts:
- <title>LED Control</title> - Sets the browser tab title
- <h1>Simple LED Control</h1> - Creates a big heading
- <p>LED Status: <strong>...</strong></p> - Shows the current LED status
- <button onclick="toggleLED()">Toggle LED</button> - Creates a clickable button
The JavaScript part:
1 2 3 4 | |
fetch('/toggle', {method: 'POST'}) sends a message to our server
- .then(() => location.reload()) refreshes the page after the LED toggles
Section 6: The Web Server
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
What's happening here?
Setting up the server:
1 2 3 | |
socket.socket() creates a "mailbox" for internet messages
- s.bind(('0.0.0.0', 80)) says "listen on all network connections, port 80"
- Port 80 is the standard port for websites
- s.listen(1) says "allow 1 person to connect at a time"
The main server loop:
1 2 | |
Handling visitors:
1 2 3 | |
s.accept() waits for someone to visit our website
- client.recv(1024) reads their request (what page they want)
- .decode('utf-8') converts the message to readable text
Understanding the request:
1 2 3 4 5 6 7 8 9 10 11 | |
GET /means "show me the main page"POST /togglemeans "toggle the LED"HTTP/1.1 200 OKis like saying "Everything's fine, here's what you asked for"
client.close() - Ends the conversation with that visitor
Section 7: The Main Program
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | |
What's happening here?
def main(): - Creates the main function that runs our program
led.off() - Makes sure the LED starts in the "off" position
wlan = connect_wifi() - Calls our WiFi function and saves the result
start_server(wlan) - Starts the web server (this runs forever)
if __name__ == '__main__': - This is Python's way of saying "if this file is being run directly (not imported), then run the main() function"
How Everything Works Together
- Startup: Program turns off LED and connects to WiFi
- Server starts: Creates a "mailbox" at your Pico's IP address
- Waiting: Server waits for someone to visit the website
- Visitor arrives: Someone types the IP address in their browser
- Send webpage: Server sends the HTML page with the button
- Button clicked: Visitor clicks "Toggle LED"
- Message sent: Browser sends a "toggle" message to the server
- LED changes: Server runs the toggle function, changing the LED
- Response sent: Server tells the browser "LED is now ON/OFF"
- Page refreshes: Browser reloads to show the new status
- Repeat: Back to step 5, ready for the next click
Key Programming Concepts You Learned
Variables: Storing information (like led_state)
Functions: Reusable blocks of code (like toggle_led())
Loops: Repeating actions (while loops)
Conditionals: Making decisions (if/else statements)
Libraries: Using pre-written code (import statements)
Global variables: Sharing data between functions
Return values: Functions giving back results
String formatting: Putting variables in text (f"...")
Real-World Applications
This same pattern is used in:
- Smart home devices (controlling lights, thermostats)
- IoT (Internet of Things) sensors
- Industrial control systems
- Home automation projects
- Remote monitoring systems
You've just built the foundation for controlling any device over the internet!
Full Source Code
Here is the full source code. It is about 70 lines.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 | |