Skip to content

Instantly share code, notes, and snippets.

@aallan
Created July 4, 2022 15:38
Show Gist options
  • Star 41 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save aallan/3d45a062f26bc425b22a17ec9c81e3b6 to your computer and use it in GitHub Desktop.
Save aallan/3d45a062f26bc425b22a17ec9c81e3b6 to your computer and use it in GitHub Desktop.
An asynchronous webserver written in MicroPython to turn an LED on/off on a Raspberry Pi Pico W
import network
import socket
import time
from machine import Pin
import uasyncio as asyncio
led = Pin(15, Pin.OUT)
onboard = Pin("LED", Pin.OUT, value=0)
ssid = 'A Network'
password = 'A Password'
html = """<!DOCTYPE html>
<html>
<head> <title>Pico W</title> </head>
<body> <h1>Pico W</h1>
<p>%s</p>
</body>
</html>
"""
wlan = network.WLAN(network.STA_IF)
def connect_to_network():
wlan.active(True)
wlan.config(pm = 0xa11140) # Disable power-save mode
wlan.connect(ssid, password)
max_wait = 10
while max_wait > 0:
if wlan.status() < 0 or wlan.status() >= 3:
break
max_wait -= 1
print('waiting for connection...')
time.sleep(1)
if wlan.status() != 3:
raise RuntimeError('network connection failed')
else:
print('connected')
status = wlan.ifconfig()
print('ip = ' + status[0])
async def serve_client(reader, writer):
print("Client connected")
request_line = await reader.readline()
print("Request:", request_line)
# We are not interested in HTTP request headers, skip them
while await reader.readline() != b"\r\n":
pass
request = str(request_line)
led_on = request.find('/light/on')
led_off = request.find('/light/off')
print( 'led on = ' + str(led_on))
print( 'led off = ' + str(led_off))
stateis = ""
if led_on == 6:
print("led on")
led.value(1)
stateis = "LED is ON"
if led_off == 6:
print("led off")
led.value(0)
stateis = "LED is OFF"
response = html % stateis
writer.write('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
writer.write(response)
await writer.drain()
await writer.wait_closed()
print("Client disconnected")
async def main():
print('Connecting to Network...')
connect_to_network()
print('Setting up webserver...')
asyncio.create_task(asyncio.start_server(serve_client, "0.0.0.0", 80))
while True:
onboard.on()
print("heartbeat")
await asyncio.sleep(0.25)
onboard.off()
await asyncio.sleep(5)
try:
asyncio.run(main())
finally:
asyncio.new_event_loop()
@boatrigm
Copy link

boatrigm commented May 6, 2023

This example works great. Wondering if there is an easy way to add url routing to this?

@aallan
Copy link
Author

aallan commented May 6, 2023

This example works great. Wondering if there is an easy way to add url routing to this?

See https://www.raspberrypi.com/news/how-to-run-a-webserver-on-raspberry-pi-pico-w/

@nickodimus
Copy link

nickodimus commented Feb 17, 2024

@aallan @boatrigm - I was just working on this, I've got a working solution with microdot api and reading sensor data concurrently. I'll upload my working project tonight but the jist is the below arrangement. The rest of my code above this in my project is just the microdot restAPI endpoints that I have working perfectly now with templating and inline python etc.

`async def server():
await app.run(port=80, debug=True)

async def main():
task = asyncio.create_task(server())
await weather()

if name == 'main':
asyncio.run(main())`

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment