How to Create a Raspberry Pi Pico W Web Server

If you’re not looking to set up a major website on a hosting service, you can easily run a web server at home. We have previously explained how configure a Raspberry Pi web server using a regular Pi 3, 4 or Zero, but you don’t even need a full Pi to do the job. With the Raspberry Pi PIco W, a Wi-Fi enabled microcontroller that costs only $6, you can perform basic web service.

The Raspberry Pi Pico W isn’t the most obvious choice, but with some MicroPython code and some HTML, we can serve basic static web pages from a Pico W. There are two parts to this project. HTML and MicroPython code. The HTML is what our browser will see, and MicroPython acts as a way to serve the code.

For this project, we’ll be hosting a basic web page from a Raspberry Pi Pico W. We’ll also show how to add some extra pizzazz to your pages with CSS and JavaScript. Finally, we’ll serve content to the world by learning how to pass external requests to our Raspberry Pi Pico W.

For this project you will need

HTML for Raspberry Pi Pico W Web Server

HyperText Markup Language (HTML) is the basic building block for the web. The language is a framework for creating web pages, a framework that has since been updated and improved for more modern sites.

The HTML code for our Pico W web server can be as simple or complicated as you want it to be, but there are a few caveats to be aware of. The HTML for the site is loaded into a Python variable, which means we can’t go overboard with the features as the Pico W only has 264KB of SRAM. Second, we can’t serve images or reference files (CSS/JavaScript) on the Pico W because we’re loading the HTML again into a Python variable that can’t access the file system.

This means that any images or CSS/JavaScript will need to be accessible from a remote site. CSS and JavaScript in HTML will work, but we prefer to reference Bootstrap CSS and JavaScript through its CDN.

To create a basic HTML page

1. Open a text editor of your choice. Notepad is more than enough, but our preference is Notepad++.

2. Set the document type to HTML, then create an html tag. This tells the browser that the page is written in HTML, and the tag indicates the start of the HTML document.



3. Create a new tag, and inside the head, use to set the title of the browser window before closing the The section

is where we store the page metadata. This is data that a web browser will need to understand the page. We use it to set the page title, it’s the bare minimum to make a page work.

Tom's Hardware Pico W <a class="wpil_keyword_link " href="/welcome-to-tweaktowns-new-web-server-a-fast-32c-64t-beast/" title="Web Server" data-wpil-keyword-link="linked">Web Server</a>

4. Create a section . This is the section where user-visible content is displayed.

5. Create a title using the tag

and give your page a title/title. This is the largest title tag.

Tom's Hardware Pico W Web Server

6. Add another title using

and give the section a name. In our example, it is “The latest news”. The tag

is smaller than

but she still points out that this is a new section.

The Latest News

seven. Insert an image, linked from a remote CDN, using the tag . We need the full URL of the image we want to use, making sure we also have permission to use the image. In our example, we use an image of Pexels.com, a free licensed image service. Images can be resized using the tag . We can specify the size as a percentage of its original size, or we can hard code the size in pixels.

8. Use the beacon

to create a paragraph of text. For our demo, we used two Lorem Ipsum paragraphs generated using a Lorem Ipsum generator.

Lorem ipsum dolor sit amet, consectetur adipiscing elit…..

(Image credit: Tom’s Hardware)

9. Finally close the body and then the HTML document.



ten. Save the file as index.html.

For now keep the code in this file, we will use it later.

Python code for the Raspberry Pi Pico W web server

We’ve created a page for our avid readers, and now we need to create a way to serve it to them. For this, we will create a short MicroPython application that will read the contents of our index.html file and serve it as a web page.

1. Follow this guide to set up your Raspberry Pi Pico W. Follow the steps up to “How to Blink an LED”.

2. Create a new blank file.

3. Import two modules. The first is socket, a low-level network interface. The second is the network, which we will use to connect to our Wi-Fi hotspot.

import socket
import network

4. Create an object, a page and use it to reference the HTML file on our Pico W. This will open the file in read-only mode.

page = open("index.html", "r")

5. Read the contents of the file into a new object, html, then close the file. This will read all the HTML in the html object.

html = page.read()
page.close()

6. Create an object, wlan, and use it to create a connection between our code and the Pico W’s Wi-Fi chip.

wlan = network.WLAN(network.STA_IF)

seven. Activate Wi-Fi then connect to your access point with your password.

wlan.active(True)
wlan.connect("ACCESS POINT","PASSWORD")

8. Create an object, sta_if, which will act as an interface between Pico W and the Wi-Fi access point.

sta_if = network.WLAN(network.STA_IF)

9. Print out the Pico W IP address, note the IP address as we will need it later. The data returned is a list object that contains our IP address, netmask, and DHCP server address. The IP address is the first item in the list, so using [0] we can dismiss it from the list without any other information.

print(sta_if.ifconfig()[0])

ten. Set Pico W to listen for connections on port 80 from any IP address. We use socket.SO_REUSEADDR to enable the same IP address to be used after a reset. This fixes an issue where the Pico W would need a full power down in order to reuse the IP address.

addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)

11. Create a loop to continuously execute the next section of code.

while True:

12. Configure Pico W to accept a connection and to create a file that will become our web page.

   cl, addr = s.accept()
   cl_file = cl.makefile('rwb', 0)

13. Create another loop, and inside the loop create an object, line, to read our web page content, line by line.

   while True:
       line = cl_file.readline()

14. Use a conditional statement to stop content playback if there are carriage returns or line breaks.

       if not line or line == b'rn':
           break

15. Create an object, response, in which we store the HTML for the webpage.

   response = html 

16. Configure a client response that sends the HTTP status code and content type to the browser, then respond with HTML to render in their browser. The connection is then disconnected.

   cl.send('HTTP/1.0 200 OKrnContent-type: text/htmlrnrn')
   cl.send(response)
   cl.close()

17. Save the file to the Raspberry Pi Pico W as main.py. By doing this, the code will run automatically when Pico W starts.

(Image credit: Tom’s Hardware)

Full List of MicroPython Codes

import socket
import network

page = open("index.html", "r")
html = page.read()
page.close()

wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("ACCESS POINT","PASSWORD")
sta_if = network.WLAN(network.STA_IF)
print(sta_if.ifconfig()[0])
addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
s = socket.socket()
s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
s.bind(addr)
s.listen(1)
while True:
    cl, addr = s.accept()
    cl_file = cl.makefile('rwb', 0)
    while True:
        line = cl_file.readline()
        if not line or line == b'rn':
            break
    response = html 
    
    cl.send('HTTP/1.0 200 OKrnContent-type: text/htmlrnrn')
    cl.send(response)
    cl.close()

Copy of index.html on the Raspberry Pi Pico W

1. In Thonny, click View >> Files. This will open a file manager. The top window is the source, in this case the main drive of our PC. The bottom window is the target, the Raspberry Pi Pico W.

(Image credit: Tom’s Hardware)

2. In the top window, navigate to the location of your index.html file.

(Image credit: Tom’s Hardware)

3. Right click on index.html and select “Download to /” to copy the file to your Pico W.

(Image credit: Tom’s Hardware)

4. Unplug Pico W from your computer, then reinsert it to restart Pico W and start the web server.

5. On your PC, open a new browser window/tab and navigate to the IP address of your Pico W. After a few moments, you will see the page appear in the window.

(Image credit: Tom’s Hardware)

Improving our HTML

(Image credit: Tom’s Hardware)

By using Bootstrap and its CDN, we created a much more professional page. This basically uses the same basic elements

,

and but with additional features like separators and custom CSS.

Prime is a framework for HTML, CSS, and JavaScript that quickly produces professional-looking sites. If you want to create a quick demo site for clients or your own projects, Bootstrap is a good place to start.

We have adapted the hero model for our demo, replacing the CSS and JavaScript links for BootstrapCDN links.

If you want to use our code, it can be downloaded from here.

Forwarding requests to our Raspberry Pi Pico W web server

Currently, our server is only accessible to devices on the same network. To share our Raspberry Pi Pico W web server with the world, we need to verify our external IP address and configure port forwarding to send external requests to our Pico W.

Each router has a subtly different way of performing these tasks, our steps illustrate how our ISP-provided router handles this.

1. Obtain your external IP address. Use the Google search engine and search “What is my IP address?” and write down the IP address.

(Image credit: Tom’s Hardware)

2. Log in to your router’s advanced settings and select DHCP Reservation. We need to make sure our Pico W has a static IP address on the LAN, and DHCP reservation is one way to do that.

(Image credit: Tom’s Hardware)

3. Select your Pico W from the list of connected devices.

(Image credit: Tom’s Hardware)

4. Add the reservation to the IP lease table, then click Apply. This will ensure that your Pico W receives the same IP address from yours.

(Image credit: Tom’s Hardware)

5. Access the Port Forwarding menu on your router. In our case, it was under Advanced Settings >> Port Forwarding.

(Image credit: Tom’s Hardware)

6. Set the service to HTTP (port 80) and create a rule for HTTP traffic. Set start and end port to 80, protocol to TCP and set IP address to that of your Pico W. to safeguard then apply the rule.

(Image credit: Tom’s Hardware)

seven. On another device, connected via another network (cellular) open the browser and access your external IP address. You will now see the web page being served through your Pico W.

(Image credit: Tom’s Hardware)

Comments are closed.