Create an access point with the Raspberry Pi Pico W, serve a web-page and flash the on-board LED

Following various examples, I’ve created a MicroPython script that does the following:

  • Create an access point on the Raspberry Pi Pico W.
  • Create a web server.
  • Serve a simple page on that web server.
  • Toggle/flash the on-board LED when that page is loaded/refreshed.

TL;DR – see the code here

Download MicroPython and install it

First of all, you’ll need to download the latest MicroPython UF2. The one I’m using is v1.19.1-108-g474c47d59 (2022-07-08) .uf2 from this page. I found out via the Raspberry Pi forums that there was something broken on versions earlier than the 07-05 one – check out the thread here.

Next, you will need to put the Pico into bootloader mode and then drag the UF2 file to the external device that comes up.

Initial access point

Use Thonny to program the initial code:

import socket
import network

ssid = "PicoW"
password = "123456789"

ap = network.WLAN(network.AP_IF)
ap.config(essid=ssid, password=password) 
ap.active(True)

while ap.active == False:
  pass

print("Access point active")
print(ap.ifconfig())

Despite setting the SSID, to start with I got a generic wi-fi name starting with “PICO”. In order to get PicoW working, I had to power cycle the Pico (rather than just CTRL-D and run again). This is behaviour described here on the RP forums.

I tried connecting to it using my mobile and success – I could connect to the access point, but had no Internet (as expected, obviously).

Serving a web page

Now, I want to serve a web page of some kind from the Pico W, otherwise it’s pretty useless. What’s the point in having an access point that does nothing?

I found this MicroPython library called tinyweb which is like Flask, but for MicroPython instead of full-blown Python. This I can use to establish “routes” which will deliver specific content via the web browser.

tinyweb requires, as it says in the README, the logging library. I had to scratch around to find that, so here it is.

I uploaded the tinyweb folder and the logging.py file to the PicoW and added

import tinyweb

at the top of the code. This ran correctly, so I then looked at the tinyweb documentation for how to create a web server.

I added some more code (which you can see on my own GitHub repo – WordPress is doing VERY weird things if I paste it in here!)

I connected to the AP again using my phone, turned off mobile data to make sure it didn’t try and serve content from the Internet, and then accessed http://192.168.4.1/ (which had been printed to the REPL which I could see because I was using Thonny).

To my surprise, I got Hello world! on the browser. Yay! It works!

Flash the onboard LED

I added the definition of the onboard LED:

led = Pin("LED", Pin.OUT)

and set the / path of the tinyweb web server to toggle it on and off.

Now, when I refresh the Hello World page, the LED goes on and off. Wonderful!

See the code on GitHub.

10 comments for “Create an access point with the Raspberry Pi Pico W, serve a web-page and flash the on-board LED

  1. Hi Michael,
    Thonny shows that the access point is active. How can I connect to the access point on Windows 10. It doesn’t work with chrome.

    Greetings Konrad

    • Hi Konrad,
      First of all, you’ll need to use the Windows wi-fi connection tool to connect TO your new access point. Let me know if you still get probs.

  2. How do you upload the tinyweb folder and the logging.py file to the picoW? I opened the picoW with bootsel and copied the files over and it said couldn’t find tinyweb when i tried to import. I booted again with bootsel and the files are gone?

  3. Wonderful example and it worked for me. I also edited the HTML a bit, added few buttons and linked them to different URLs like ”192.168.4.1/led_on or /led_off”. But I cannot wrap my head around how to make Pico do things when these URLs are visited.

    • Hi Cagan,
      Okay, if you look at the code here: https://github.com/recantha/PicoWAccessPoint/blob/main/main.py
      …you will see a bit that starts:
      @app.route(‘/’)
      …then a function
      This defines the behaviour when you hit / – you will see it prints something to the screen and then does led.toggle() to turn the LED on or off.

      What you’d need to do is to define your own route:
      @app.route(‘/led_on’)
      and then create a new function below it (similar to the one for /) which would turn the LED on – led.on().
      Then, create your led_off route and function to do led.off()

      Hope that makes sense!

      Mike

  4. Have you had any luck running this with external power supply? When I run connected to my computer everything works smoothly, but when I run it as main.py on startup not connected to my laptop it gets stuck setting up the AP. Thanks for the great tutorial.

    • I seem to remember having a similar problem, but I can’t remember what I did to resolve it. Sorry. However, it’s possible there’s a better example out there for doing the same thing, maybe with a different library?

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.