Home > front end >  Micropython Second Thread Hangs Starting WIFI
Micropython Second Thread Hangs Starting WIFI

Time:01-28

I have found an example to publish a very simple HTML page from my Raspberry Pi Pico W. I plan to use it to monitor and control the Pico from a browser within my LAN. If I un-comment the last in the code below and run it directly in Thony (not as a thread) it works no problem and I can turn on and off the LED on the Pico W from my browser.

Sorry this code is long. I created a cut down thread test example and that worked, so it's something about the way this code runs in a thread.

# Test Web server based on an example found here
# https://how2electronics.com/raspberry-pi-pico-w-web-server-tutorial-with-micropython/

import machine
import socket
#import math
import network
import time
import secretsHouse

# Temperature Sensor
sensor_temp = machine.ADC(4)
conversion_factor = 3.3 / (65535)

# Pin Definitions
ledPin = 5                                   # Physical Pin 7  Gnd = 8
led = machine.Pin(ledPin, machine.Pin.OUT)   # Define pin as output 


def webServerMain():
    print("*Thread2*    Main()")
    wlan = network.WLAN(network.STA_IF)
    print("*Thread2*    wlan=" str(wlan))
    try:
        print("*Thread2*    try wlan.active(True)")
        wlan.active(True)
        print("*Thread2*    wlan=active")
    except Exception as errorMsg:
        print("*Thread2*    Error=" str(errorMsg))

    wlan.connect(secretsHouse.ssid,secretsHouse.password)
 
    # Wait for connect or fail
    print("*Thread2*   WIFI Connect Wait=10")
    wait = 10
    while wait > 0:
        if wlan.status() < 0 or wlan.status() >= 3:
            break
        wait -= 1
        print('*Thread2*    waiting for wifi connection...' str(wait))
        time.sleep(2)
 
    # Handle connection error
    if wlan.status() != 3:
        print("*Thread2*    " str(wlan.status()))
        raise RuntimeError('*Thread2    *wifi connection failed')
    else:
        print('*Thread2*    Wifi Connected')
        ip=wlan.ifconfig()[0]
        print('*Thread2*    IP: ', ip)
 
    try:
        if ip is not None:
            connection=open_socket(ip)
            serve(connection)
    except KeyboardInterrupt:
        machine.reset()

def temperature():
    temperature_value = sensor_temp.read_u16() * conversion_factor 
    temperature_Celcius = 27 - (temperature_value - 0.706)/0.00172169/ 8 
    print("*Thread2*  Temp="   str(temperature_Celcius))
    time.sleep(2)
    return temperature_Celcius
 
def webpage(value):
    html = f"""
            <!DOCTYPE html>
            <html>
            <body>
            <form action="./led">
            <input type="submit" value="Led On" />
            </form>
            <form action="./off">
            <input type="submit" value="Led Off" />
            </form>
            <p>Temperature is {value} degrees Celsius</p>
            </body>
            </html>
            """
    return html
 
def serve(connection):
    while True:
        print("*Thread2*    serve() While Loop.... (Wait for web request)")
        client = connection.accept()[0]
        print("*Thread2*    serve() client="   str(client))
        print()
        request = client.recv(1024)
        print("*Thread2*    request=" str(request))
        request = str(request)
        print()
        try:
            request = request.split()[1]
        except IndexError:
            print("IndexError")
            pass
        print()
        print("*Thread2*    Request="   str(request))
        
        if request == '/off?':
            led.low()
        elif request == '/led?':
            led.high()
 
        value='%.2f'%temperature()    
        html=webpage(value)
        client.send(html)
        client.close()
 
def open_socket(ip):
    # Open a socket
    print("*Thread2*    open_socket()")
    address = (ip, 80)
    connection = socket.socket()
    connection.bind(address)
    connection.listen(1)
    print("*Thread2*    connection=" str(connection))
    return(connection)
 
#webServerMain()  # Enable this line to run not in a thread

If I comment out the last line in the above sample and run the code in a separate thread using the example below, the foreground thread runs but the background thread stops with the output as below.

*Thread2*    Main()
*Thread1*    Count=1
*Thread2*    wlan=<CYW43 STA down 0.0.0.0>
*Thread2*    try wlan.active(True)
*Thread1*    Count=2
*Thread1*    Count=3
*Thread1*    Count=4
*Thread1*    Count=5
*Thread1*    Count=6
*Thread1*    Count=7
*Thread1*    Count=8
*Thread1*    Count=9
*Thread1*    Count=10
*Thread1*    Count=11
*Thread1*    Count=12
*Thread1*    Count=13
*Thread1*    Count=14
*Thread1*    Count=15

Here is the code that executes the thread The simple testTone.beep also works correctly just to make sure my thread stuff is reasonable.

# Test Thread
import _thread
import time
import webServerExample
import testTone

_thread.start_new_thread(webServerExample.webServerMain,())
#_thread.start_new_thread(testTone.beep,())

count=0
while True:
    count=count 1
    print("*Thread1*    Count=" str(count))
    time.sleep(2)

I'm stuck now. Any ideas what I'm doing wrong or how I can further narrow the field to find the problem. Thanks in advance David.

UPDATE I think it's only the Wifi starting that stops the second thread so I updated the Title.

CodePudding user response:

This is more of a work around than an answer.

If I put the WIFI stuff in the main thread and then start a second thread that does something trivial it works no problem. I'll rebuild my actual application to function this way and see if something else kills the sub thread.

I'm not sure if this behavior is a bug in Micropython threading?

I'll create a new question with a bare bones example that demonstrates the problem with just the WIFI connection and not much more than a counter or two. David

  • Related