benji bon
benji bon

Reputation: 31

Other code won’t run because webserver section is waiting for web requests

So I am trying to make an rc plane with the pi pico, so to make it remote controlled, i decided to have it host a little web server, just simply with the controls. And I got that to work. But then I noticed the planes lights stopped blinking. In short, the microcontroller can’t do anything else because it is busy waiting for a web request.

The lights will only blink if I refresh the page, or click a button.

Here is the loop, plane_duties() is all of the other code

while True:
    plane_duties(.05)
    try:
        cl, addr = s.accept()
        request = cl.recv(1024)
        request = str(request)
        tlan_toggle = request.find('tlan=toggle')
        blan_toggle = request.find('blan=toggle')

        if tlan_toggle == 8:
            tlan = not tlan
        if blan_toggle == 8:
            blan = not blan
        print(tlan, blan)
        tlanState = 'Landing is OFF' if tlan else 'Landing is ON'
        tlanStateClass = 'off' if tlan else 'on'
        blanState = 'Cargo is OFF' if blan else 'Cargo is ON'
        blanStateClass = 'off' if blan else 'on'

        response = html.replace('{{tlanStateClass}}', tlanStateClass).replace('{{blanStateClass}}', blanStateClass) % (
            tlanState, blanState)
        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()
        print('connection closed')

Is there any way I can run code while waiting for a request?

Upvotes: 0

Views: 190

Answers (1)

Peter I.
Peter I.

Reputation: 126

This is a typical web server scenario. The problem arises because you do a synchronous approach: first you do your plane duties, then you try to get new values from a connected client - then repeat. What happens if you have a connection with a decent lag?

You need to separate the web handling from the plane handling. Both parts share only a common data structure that contains the states, here "Landing" and "Cargo". Both parts have to run independently, so the plane duties can run every 20 ms and the web interface can update values when they arrive.

Good luck the pi pico is a dual core processor. Just add

import _thread

def plane_duties_loop():
    while True:
        plane_duties(0.05)
        update_blink()

thread = _thread.start_new_thread(plane_duties_loop, ())

To share values between the two parts you need to make sure they aren't modified while your code wants to read them.

import _thread

def plane_duties_loop():
    while True:
        lock.acquire() # request lock 
        values = read_global_values() # now the values are locally available
        lock_release() # global values may be used by other thread again
        plane_duties(0.05)
        update_blink()

lock = _thread.allocate_lock() # create a global lock, a "semaphore".
thread = _thread.start_new_thread(plane_duties_loop, ()) # start thread for plane handling
web_server() # this thread does the web handling

For the web server part you need a similar lock.acquire() / lock.release() bracket when you access the common variables. I spared that for brevity.

Upvotes: 0

Related Questions