1

So, im trying to make a webserver and processing data with a pico in parallel, my goal is to reach the pico from my browser using the local network ip to see in what step the pico is working and what data is on the current loop, however i have two issues and i have no idea how to make it work:

  1. When running the two process in parallel using _thread, the webserver function hangs until the dataprocess function finish, so i cant see in realtime what is going on, the webserver respond only when the other process is finished and it hangs again, i need to press f5 on my browser at the exact time when the dataprocess function finish and start again only to see part of the process because it hangs if i refresh my browser to see the progress

  2. When running the webserver, the urequets.get function of the dataprocess function does not work, it throws [Errno 103] ECONNABORTED

Here is the part of my code that is not working:

import utime, machine, urequests, json, network, socket, _thread

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

def connect():
    global wlan
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect("SSID", "PASSS")
    while wlan.isconnected() == False:
        print("Connecting...")
        led.off()
        utime.sleep_ms(100)
        led.on()
        utime.sleep_ms(100)
        led.off()
        utime.sleep_ms(100)
        led.on()
        utime.sleep_ms(100)
    led.on()
    ip = wlan.ifconfig()[0]
    print(f'Connected on {ip}')
    return ip

def open_socket(ip):
    address = (ip, 80)
    connection = socket.socket()
    connection.bind(address)
    connection.listen(1)
    return connection

def webpage(steps):
    html = f"""
            <!DOCTYPE html>
            <html>
            <head>
            <title>Pico 2</title>
            </head>
            <body>
            <p>{steps}</p>
            </body>
            </html>
            """
    return str(html)

def pushgetdata():
    while wlan.isconnected() == True:
        try:
            global steps
            led.off()
            utime.sleep_ms(300)
            led.on()
            steps = "Step 1: Reading values from sensor one...<br>"
            #function to read data from one sensor here
            #...
            #...
            #...
            led.off()
            utime.sleep_ms(100)
            led.on()
            steps = steps + "Step 2: Reading values from sensor two...<br>"
            #function to read data from other sensor here
            #...
            #...
            #...
            led.off()
            utime.sleep_ms(100)
            led.on()
            steps = steps + "Step 3: Pushing and getting results...<br>"
            jsondata = urequests.get("https://xxx.xxx.xxx/api/?device=pico2&sensor1=valulesfromsensor1&sensor2=valuesfromsensor2")
            proceseddata = jsondata.json()
            steps = steps + proceseddata + "<br>"
            steps = steps + "Step 4: Doing things with results...<br>"
            #function to do conditions and things with results...
            #...
            #...
            #...
            jsondata.close()
            steps = steps + "Step 5: Finished, sleeping for the next round...<br>"
            utime.sleep_ms(100)
            led.off()
            utime.sleep_ms(100)
            led.on()
            utime.sleep(900)
        except OSError as e:
            steps = steps + e
        

def serve(connection):
    while True:
        try:
            client, addr = connection.accept()
            print('client connected from', addr)
            request = client.recv(1024)
            request = str(request)       
            html = webpage(steps)
            client.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
            client.send(html)
            client.close()
        except OSError as e:
            client.close()
            

def webserver():
    ip = connect()
    connection = open_socket(ip)
    _thread.start_new_thread(serve,(connection,))


try:
    webserver()
    pushgetdata()
except KeyboardInterrupt:
    machine.reset()
Bararto
  • 11
  • 2

2 Answers2

0

I'm not sure exactly what's going on with your code, but using the same threading idea, please find here my solution for a similar problem I've encountered today if it helps.

    from machine import Pin
    from time import sleep
    
    import wlan_data, network
    import socket, _thread
    
    
    wlan = network.WLAN(network.STA_IF)
    wlan.active(True)
    wlan.connect(wlan_data.SSID, wlan_data.PASSWORD)
    
    print("WLAN is connected: " + str(wlan.isconnected()))
    
    page = open("index.html", "r")
    html = page.read()
    page.close()
    
    sta_if = network.WLAN(network.STA_IF)
    print(sta_if.ifconfig()[0])
    
    def setUpSocket():
        addr = socket.getaddrinfo('0.0.0.0', 80)[0][-1]
        s = socket.socket()
        s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
        s.bind(addr)
        s.listen(1)
        return s
    
    def serve(s):
        while True:
            try:
                cl, addr = s.accept()
                cl_file = cl.makefile('rwb', 0)
                while True:
                    line = cl_file.readline()
                    if not line or line == b'\r\n':
                        break
                response = html
                cl.send('HTTP/1.0 200 OK\r\nContent-type: text/html\r\n\r\n')
                cl.send(response)
                cl.close()
            except OSError as e:
                cl.close()
        
    def webserver():
        s = setUpSocket()
        _thread.start_new_thread(serve,(s,))
    
    webserver()
    
    led = machine.Pin("LED", machine.Pin.OUT)
    led.toggle()
        
    
    while 1:
        led.toggle()
        sleep(10)

Klaymen
  • 75
  • 2
  • 10
0

_thread library is experimental and buggy. From the micropython documentation https://docs.micropython.org/en/latest/library/_thread.html

This module is highly experimental and its API is not yet fully settled and not yet described in this documentation.

From my own testing, some of the functionality works for a while, then you might add another import and things stop working. Best to steer clear until it is no longer an experimental feature.

Venkat Naidu
  • 105
  • 6