Loop wont stop after indicated times

General discussions and questions abound development of code with MicroPython that is not hardware specific.
Target audience: MicroPython Users.
Post Reply
soggycashew
Posts: 55
Joined: Sat Sep 18, 2021 10:21 pm

Loop wont stop after indicated times

Post by soggycashew » Sun Jan 16, 2022 5:08 pm

Hello, I have a momentary button on my Pico and when pressed it runs the function below. When pressed it runs the function BUT it runs on an infinity loop and not the 2 times I indicated. What am I doing incorrectly? Thanks....

Code: Select all

def show_display(pin):
    for i in range(2):
    # Scroll in, stop, scroll out (vertical)
        scroll_in_screen_v(OLED_screen1)
        time.sleep(5) # Sleep for 5 seconds
        scroll_out_screen_v(2)

        scroll_in_screen_v(OLED_screen2)
        time.sleep(5) # Sleep for 5 seconds
        scroll_out_screen_v(2)
        
#Attach interrupt to btn_show_display            
btn_show_display.irq(trigger=machine.Pin.IRQ_RISING, handler=show_display)

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Loop wont stop after indicated times

Post by pythoncoder » Sun Jan 16, 2022 5:26 pm

I suggest you read this doc. Interrupt service routines should be written to complete in times measured in μs, not 20s. The doc explains how to work round this.

The longer answer is that interrupts aren't the best way to interface switches for a variety of reasons including contact bounce. Asynchronous programming using uasyncio is your friend and drivers for switches and pushbuttons are available.
Peter Hinch
Index to my micropython libraries.

soggycashew
Posts: 55
Joined: Sat Sep 18, 2021 10:21 pm

Re: Loop wont stop after indicated times

Post by soggycashew » Sun Jan 16, 2022 6:01 pm

@pythoncoder I read/looked at the document link you posted and I am lost on how to get this working. All I wanted to do was when the button was pressed just run the function twice. Can you give me an example with my code please?

I did find a video by Digi-Key based off your Asyncio HERE. I got it working with his video BUT im not running multiple things at one time, I just wanted to loop the display 2x.

Thanks,

Code: Select all

# Coroutine: blink on a timer
async def blink(delay):
    while True:
        led.toggle()
        await uasyncio.sleep(delay)

# Coroutine: only return on button press
async def wait_button():
    btn_prev = btn_show_display.value()
    while (btn_show_display.value() == 1) or (btn_show_display.value() == btn_prev):
        btn_prev = btn_show_display.value()
        await uasyncio.sleep(0.04)
        
# Coroutine: entry point for asyncio program
async def main():
    # Start coroutine as a task and immediately return
    uasyncio.create_task(blink(0.2))
    
    while True:
        # Calculate time between button presses
        await wait_button()
        
        for i in range(2):
        # Scroll in, stop, scroll out (vertical)
            scroll_in_screen_v(OLED_screen1)
            time.sleep(5) # Sleep for 5 seconds
            scroll_out_screen_v(2)

            scroll_in_screen_v(OLED_screen2)
            time.sleep(5) # Sleep for 5 seconds
            scroll_out_screen_v(2)

# Start event loop and run entry point coroutine
uasyncio.run(main())

User avatar
pythoncoder
Posts: 5956
Joined: Fri Jul 18, 2014 8:01 am
Location: UK
Contact:

Re: Loop wont stop after indicated times

Post by pythoncoder » Mon Jan 17, 2022 10:50 am

Here is how I would do it. You'll need to copy the primitives directory and contents from here to your target device. You could just copy pushbutton.py, delay_ms.py, and __init__.py but you must keep the primitives directory.

Code: Select all

import uasyncio
from machine import Pin
from primitives.pushbutton import Pushbutton

pin = Pin(1, Pin.IN,Pin.PULL_UP)  # Adapt for your hardware

# Coroutine: blink on a timer
async def blink(delay):
    while True:
        led.toggle()
        await uasyncio.sleep(delay)

async def on_press():  # Runs when button pressed
    for i in range(2):
    # Scroll in, stop, scroll out (vertical)
        scroll_in_screen_v(OLED_screen1)
        await uasyncio.sleep(5) # Sleep for 5 seconds (must use async sleep)
        scroll_out_screen_v(2)

        scroll_in_screen_v(OLED_screen2)
        await uasyncio.sleep(5) # Sleep for 5 seconds
        scroll_out_screen_v(2)

# Coroutine: entry point for asyncio program
async def main():
    pb = Pushbutton(pin)  # Create pushbutton instance
    pb.press_func(on_press)
    # Start coroutine as a task and immediately return
    uasyncio.create_task(blink(0.2))
    
    while True:
        await asyncio.sleep(1)  # You can run other code here

# Start event loop and run entry point coroutine
uasyncio.run(main())
Peter Hinch
Index to my micropython libraries.

soggycashew
Posts: 55
Joined: Sat Sep 18, 2021 10:21 pm

Re: Loop wont stop after indicated times

Post by soggycashew » Mon Jan 17, 2022 11:22 pm

@pythoncoder thank you it works great... If I was to use another button do I just add it in and "Create pushbutton instance" like in your example?

I noticed a difference from your example and my example. The onboard light blinks and I press the button, the oled runs and on its await uasyncio.sleep(5) the led flashes until it starts again. On my example the led quit until the whole thing was done running.

Does that mean the oled isn't in use so it continues the led until tis in use again? I also see you added "# You can run other code here" if I had other code what could I add there as an example?

Post Reply