-1

I've got a program that is pulling UPD data being transmitted by my home weather station. One of those values that is a "rain_accum" which is the total rain accumulation in the past minute. When that "rain_accum" is > 0, I want the light to blink. When the rain_accum == 0, I want it to not blink.

I'm fairly new to Python and very new to uasyncio (note: I'm using Micropython, so I may not have all the capablities of asyncio) and I'm just getting lost. I've been messing with this for 3 days and have actually gotten pretty close to getting it working, but the timing was way off the blink would take several seconds and UDP messages were getting missed. I've cut my code back to the bare basics of what I've been trying to do hoping I could get some direction as to where to go with this.

import uasyncio

async def blink():
    while True:
        print("Here 1")
        await uasyncio.sleep(1)
        print("Here 2")
        await uasyncio.sleep(1)
        
async def getData():
    
    while True:
        print("Getting data")
        
        if True:
            await blink()
        print("Next loop")
        await uasyncio.sleep(5)
        
                              
try:
    
    uasyncio.run(getData())
    
except KeyboardInterrupt:
    print("Quitting")
MABeatty1978
  • 115
  • 1
  • 3
  • 14

1 Answers1

1

In the example in your question, once you call await blink() you never return: your current coroutine has entered an infinite loop.

Take a look at the example from the documentation, which shows how to start two coroutines concurrently. If we were to take that examples and fit it to the example from your question, we might get something like:

import random
import time
import uasyncio

blink_active = False


async def blink():
    while True:
        if blink_active:
            print("Here 1")
            await uasyncio.sleep(1)
            print("Here 2")
            await uasyncio.sleep(1)
        else:
            await uasyncio.sleep(1)


async def getData():
    global blink_active

    # Start a concurrent async task
    uasyncio.create_task(blink())

    last_check = 0
    while True:
        now = time.time()
        if now - last_check > 5:
            data = random.randint(0, 10)
            print("Got data", data)
            if data > 7:
                print("Start blinking")
                blink_active = True
            else:
                print("Stop blinking")
                blink_active = False
            last_check = now

        print("Next loop")
        await uasyncio.sleep(1)


try:
    uasyncio.run(getData())
except KeyboardInterrupt:
    print("Quitting")

Here, getData() starts a blink task that will run forever. Whether it "blinks" (or prints out text) is controlled by a global variable, blink_active.

In getData, our loop runs once/second, but we only gather new data every five seconds. Depending on the value we retrieve from our "sensor", we start or stop the blinker by setting blink_active appropriately.

larsks
  • 277,717
  • 41
  • 399
  • 399
  • Thank you, that has me working. Question though, what is the significance of the last_check > 5. Why is that necessary? – MABeatty1978 Feb 09 '23 at 20:58
  • You're missing half the expression; we're checking if `now - last_check > 5`. Remember when I said, "we only gather new data every five seconds"? That is checking to see if it's been five seconds since our last check. – larsks Feb 09 '23 at 20:59