qsf
qsf

Reputation: 13

Issue Running Async Web Server with Multi-Core Threading on Raspberry Pi Pico W

I'm working on a project using the Raspberry Pi Pico W 2 that involves displaying data from BLE sensors on a web page, with everything running on the Pico.

My intention is to:

  1. Run an asynchronous web server on Core 0.
  2. Use a thread on Core 1 to handle sensor interactions.

The data sharing between the cores is based on a shared memory model with locking (not part of my issue here).

To test this, I used a sample script from Random Nerd Tutorials, replacing all hardware I/O with console printouts so the test only needs the Pico itself. The web server runs perfectly on its own, but when I add a trivial task to run on Core 1, the following issues occur:

  1. The console outputs appear as expected.
  2. The web server becomes inaccessible.
  3. The Pico locks up completely, requiring a full reset with flash_nuke.uf2 to upload any new code.

Problem

What could be causing the Pico to crash when adding a thread on Core 1, and how can I resolve this issue?

Test Code:

Here is the modified code:

# Modified from Random Nerd Tutorials
# https://randomnerdtutorials.com/raspberry-pi-pico-w-asynchronous-web-server-micropython/

import network
import asyncio
import time
from machine import Pin
import _thread

# Wi-Fi credentials
ssid = "wifi-name"
password = "wifi-password"

# Onboard LED setup
led_control = Pin("LED", Pin.OUT)

# Shared variables
state = "OFF"
random_value = 0

# HTML template
def webpage(random_value, state):
    return f"""
        <!DOCTYPE html>
        <html>
        <head>
            <title>Pico Web Server</title>
            <meta name="viewport" content="width=device-width, initial-scale=1">
        </head>
        <body>
            <h1>Pico Web Server</h1>
            <p>LED state: {state}</p>
            <p>Random value: {random_value}</p>
        </body>
        </html>
    """

# Initialize Wi-Fi
def init_wifi(ssid, password):
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(ssid, password)
    for _ in range(10):
        if wlan.status() >= 3:
            print('Wi-Fi connected')
            print('IP address:', wlan.ifconfig()[0])
            return True
        time.sleep(1)
    print('Wi-Fi connection failed')
    return False

# Asynchronous web server
async def handle_client(reader, writer):
    global state, random_value
    request = await reader.readline()
    if '/lighton' in request:
        led_control.value(1)
        state = "ON"
    elif '/lightoff' in request:
        led_control.value(0)
        state = "OFF"
    elif '/value' in request:
        random_value = random.randint(0, 20)
    response = webpage(random_value, state)
    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()

# Blink task
async def blink_led():
    while True:
        print("Blinking LED")
        await asyncio.sleep(1)

# Core 1 task
def parallel_core_task():
    while True:
        print("Running on Core 1")
        time.sleep(2)

# Main function
async def main():
    if not init_wifi(ssid, password):
        return
    server = await asyncio.start_server(handle_client, "0.0.0.0", 80)
    asyncio.create_task(blink_led())
    async with server:
        await server.serve_forever()

# Start Core 1 thread
_thread.start_new_thread(parallel_core_task, ())

# Start asyncio event loop
loop = asyncio.get_event_loop()
loop.run_until_complete(main())

Console Output:

MPY: soft reboot
Running on Core 1
Wi-Fi connected
IP address: 192.168.0.3
Blinking LED
Running on Core 1
...

Additional Notes:

Upvotes: 0

Views: 61

Answers (0)

Related Questions