Adafruit_Learning_System_Guides
Adafruit_Learning_System_Guides copied to clipboard
Pi Pico W adafruit_httpserver hangs if you repeatedly click on-screen buttons on webpage
The example code for adafruit_httpserver has an issue where it will lock up in certain circumstances. I suspect this may actually be an issue with the httpserver library code, but have not been able to pin the issue down.
See discussion: https://forums.adafruit.com/viewtopic.php?t=197898
Code enclosed below, cut down from the latest version of the example here: https://learn.adafruit.com/pico-w-http-server-with-circuitpython/code-the-pico-w-http-server
Using the latest release: adafruit-circuitpython-raspberry_pi_pico_w-en_US-8.0.0-rc.2.uf2 and libraries: adafruit-circuitpython-bundle-8.x-mpy-20230203.zip
Basically if you click repeatedly and rapidly on one of the on-screen buttons on the web page, eventually the code hangs in:
Traceback (most recent call last):
File "code.py", line 157, in
# SPDX-FileCopyrightText: 2022 Liz Clark for Adafruit Industries
#
# SPDX-License-Identifier: MIT
import os
import time
import ipaddress
import wifi
import socketpool
import busio
import board
import microcontroller
import displayio
import terminalio
from digitalio import DigitalInOut, Direction
from adafruit_httpserver.server import HTTPServer
from adafruit_httpserver.request import HTTPRequest
from adafruit_httpserver.response import HTTPResponse
from adafruit_httpserver.methods import HTTPMethod
from adafruit_httpserver.mime_type import MIMEType
# onboard LED setup
led = DigitalInOut(board.LED)
led.direction = Direction.OUTPUT
led.value = False
# connect to network
print()
print("Connecting to WiFi")
# set static IP address
ipv4 = ipaddress.IPv4Address("192.168.1.55")
netmask = ipaddress.IPv4Address("255.255.255.0")
gateway = ipaddress.IPv4Address("192.168.1.1")
wifi.radio.set_ipv4_address(ipv4=ipv4,netmask=netmask,gateway=gateway)
# connect to your SSID
wifi.radio.connect("XXXX", "yyyyy")
print("Connected to WiFi")
pool = socketpool.SocketPool(wifi.radio)
server = HTTPServer(pool)
# variables for HTML
# comment/uncomment desired temp unit
# temp_test = str(ds18.temperature)
# unit = "C"
temp_test = "32"
unit = "F"
# font for HTML
font_family = "monospace"
# the HTML script
# setup as an f string
# this way, can insert string variables from code.py directly
# of note, use {{ and }} if something from html *actually* needs to be in brackets
# i.e. CSS style formatting
def webpage():
html = f"""
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<style>
html{{font-family: {font_family}; background-color: lightgrey;
display:inline-block; margin: 0px auto; text-align: center;}}
h1{{color: deeppink; width: 200; word-wrap: break-word; padding: 2vh; font-size: 35px;}}
p{{font-size: 1.5rem; width: 200; word-wrap: break-word;}}
.button{{font-family: {font_family};display: inline-block;
background-color: black; border: none;
border-radius: 4px; color: white; padding: 16px 40px;
text-decoration: none; font-size: 30px; margin: 2px; cursor: pointer;}}
p.dotted {{margin: auto;
width: 75%; font-size: 25px; text-align: center;}}
</style>
</head>
<body>
<title>Pico W HTTP Server</title>
<h1>Pico W HTTP Server</h1>
<br>
<p class="dotted">This is a Pico W running an HTTP server with CircuitPython.</p>
<br>
<p class="dotted">The current ambient temperature near the Pico W is
<span style="color: deeppink;">{temp_test}°{unit}</span></p><br>
<h1>Control the LED on the Pico W with these buttons:</h1><br>
<form accept-charset="utf-8" method="POST">
<button class="button" name="LED ON" value="ON" type="submit">LED ON</button></a></p></form>
<p><form accept-charset="utf-8" method="POST">
<button class="button" name="LED OFF" value="OFF" type="submit">LED OFF</button></a></p></form>
<h1>Party?</h>
<p><form accept-charset="utf-8" method="POST">
<button class="button" name="party" value="party" type="submit">PARTY!</button></a></p></form>
</body></html>
"""
return html
# route default static IP
@server.route("/")
def base(request: HTTPRequest): # pylint: disable=unused-argument
# serve the HTML f string
# with content type text/html
with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
response.send(f"{webpage()}")
# if a button is pressed on the site
@server.route("/", method=HTTPMethod.POST)
def buttonpress(request: HTTPRequest):
# get the raw text
raw_text = request.raw_request.decode("utf8")
print(raw_text)
# if the led on button was pressed
if "ON" in raw_text:
# turn on the onboard LED
led.value = True
# if the led off button was pressed
if "OFF" in raw_text:
# turn the onboard LED off
led.value = False
# if the party button was pressed
if "party" in raw_text:
# toggle the parrot_pin value
led.value = False
# reload site
with HTTPResponse(request, content_type=MIMEType.TYPE_HTML) as response:
response.send(f"{webpage()}")
print("starting server..")
# startup the server
try:
server.start(str(wifi.radio.ipv4_address))
print("Listening on http://%s:80" % wifi.radio.ipv4_address)
# if the server fails to begin, restart the pico w
except OSError:
time.sleep(5)
print("restarting..")
microcontroller.reset()
clock = time.monotonic() # time.monotonic() holder for server ping
parrot = False # parrot state
party = 0 # time.monotonic() holder for party parrot
p = 0 # index for tilegrid
while True:
try:
# every 30 seconds, ping server & update temp reading
if (clock + 30) < time.monotonic():
clock = time.monotonic()
# comment/uncomment for desired units
# temp_test = str(ds18.temperature)
temp_test = "31"
temp_text_area.text = "Temperature: %s F" % temp_test
# poll the server for incoming/outgoing requests
server.poll()
# pylint: disable=broad-except
except Exception as e:
print(e)
continue